RFR: 8318462: [GenShen] Prevent unsafe access to displaced mark-word [v2]

Roman Kennke rkennke at openjdk.org
Thu Oct 19 12:32:10 UTC 2023


> We must be very careful when we access (load or update) the object age concurrently because the age is stored in the object's header and that header can be 'displaced'. This means that the header is overloaded with a pointer (stack or ObjectMonitor*) and the original header is stored at that location. The header can also be in INFLATING state, which means that a stack-lock is currently in the process to be inflated to an ObjectMonitor. Let's consider the cases separately:
> 
> Loading object age:
> - INFLATING: we can not access the header, and thus not the age.
> - Stack-locked: the thread which locks the object can unlock at any time, concurrently. It is not safe to access the header, and thus the age.
> - Monitor-locked: monitors don't go away without coordinating with Java threads and possibly GC threads. This coordination is done by handshaking the thread - a Java thread would be brought to its next safepoint, and GC threads, which are typically participating in handshakes by joining the SuspendibleThreadSet, can opt to handshake at a safe point by calling SuspendibleThreadSet::yield(). If 'our' thread participates in handshakes in one way or the other, it is safe to access an ObjectMonitor once we got a valid ObjectMonitor* from an object's header, but only until that thread handshakes. Long story short: it is typically safe to access ObjectMonitor :-)
> 
> Updating object age:
> Updating object age only happens during evacuation, and only on a new copy of an object, before that copy has been published. Access to the object header is therefore fully thread-local and not problematic. What *is* problematic is when we have to deal with displaced headers, because displaced headers are *not* thread local, and must be considered a shared resource. A competing thread may succeed to evacuate the object and publish its copy before 'our' thread can do so. If 'our' thread would update the displaced header, it may over-write whatever the other thread has done.
> - INFLATING: We cannot access the header at all. However, that should not happen: a thread can only inflate once it has successfully evacuated an object, and 
> - Stack-locked: the other thread may succeed evacuation and continue to unlock the object, at which point the stack-pointer would be 'dangling' and we may over-write random information on the foreign thread stack.
> - Monitor-locked: even though monitor deflation is coordinated (see above), updating the displaced header in a monitor might over-write whatever a competi...

Roman Kennke has updated the pull request incrementally with one additional commit since the last revision:

  Handle forwarded headers

-------------

Changes:
  - all: https://git.openjdk.org/shenandoah/pull/343/files
  - new: https://git.openjdk.org/shenandoah/pull/343/files/3869c012..dd6329a3

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=shenandoah&pr=343&range=01
 - incr: https://webrevs.openjdk.org/?repo=shenandoah&pr=343&range=00-01

  Stats: 10 lines in 1 file changed: 9 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/shenandoah/pull/343.diff
  Fetch: git fetch https://git.openjdk.org/shenandoah.git pull/343/head:pull/343

PR: https://git.openjdk.org/shenandoah/pull/343


More information about the shenandoah-dev mailing list