Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8237741

ensure that store-store barriers precede publication of buffered values

XMLWordPrintable

      This is a tracking bug to follow up on the questions in these Emails:

      http://mail.openjdk.java.net/pipermail/valhalla-dev/2020-January/006706.html
      http://mail.openjdk.java.net/pipermail/valhalla-dev/2020-January/006710.html

      Every path that first publishes a buffered inline instance, from the thread
      that created it, *must* issue a store-store barrier before publication and
      after the inline value fields have been buffered. It seems to be the case
      that some such paths in the Valhalla VM are *not* protected, and this
      may cause race conditions which are not allowed by the JVMS.

      (Instead of a store-store barrier an equivalent safe publication technique
      could be used, such as a safepoint, as used by the GC to publish the
      bulk results of a copy phase.)

      Detail:

      Value types are allowed to tear in user-visible heap variables
      (unless marked “always atomic” via an upcoming feature).

      But buffers introduced on the fly by the JVM are not user-visible
      variables. They are not even variables; they are immutable;
      this strengthens my point, though doesn’t make it completely.

      JVM-introduced buffers must be protected from tearing, by
      ensuring that before each such buffer is published all stores
      to its value's fields are fully settled. This requires a store-store
      barrier before the publishing store.

      The JVM has freedom to unbuffer and rebuffer values
      between any two instructions (remember deopt & reopt),
      so the tearing of a heap buffer would appear as tearing of a
      value on stack or in a local. But the JVMS does not allow
      race conditions to affect stacked or local values.

      The JVMS does allow race conditions on multi-field values
      stored in heap variables. But no race conditions should
      be allowed if a heap variable is implemented as an invisible
      reference to a buffered value. In that case, the buffered
      value must always be fully settled for safe publication
      before the invisible reference is stored to the heap variable.

      This extra condition is perhaps not strictly necessary, but it is
      probably *practically* necessary, because any race conditions
      that might appear on such a buffered value must be attributable
      to a particular variable (of value type) in the heap, and the only
      variable visible to the user is the invisible reference, which is
      inherently non-tearing. Any races on the indirect buffer would
      have to be attributable to the reference field and controllable
      by locking its containing object. But if the invisible reference
      escapes (via copying) to another place, such as the stack
      or a local or another invisible reference variable in the heap,
      then any pending races on the buffer will suddenly appear
      in the wrong place. The race gets misplaced because a
      new alias (reference) appears to the buffer. The best way
      to rule this out is to safely publish the buffer in the first place,
      rather than try to prevent misplaced races after an unsafe
      publication.

            Unassigned Unassigned
            jrose John Rose
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: