RFR: Reimplement TsanOopMap support using WeakHandle and ResizeableResourceHashtable [v7]

Jiangli Zhou jiangli at openjdk.org
Wed Jul 24 17:24:30 UTC 2024


> The new implementation for TsanOopMap support in JDK 21 is partially modeled after [JvmtiTagMap](https://github.com/openjdk/jdk21u-dev/blob/cdbd94f8fa97847c02e1f0f4c6cd75f457a62e25/src/hotspot/share/prims/jvmtiTagMap.hpp#L37) and [JvmtiTagMapTable](https://github.com/openjdk/jdk21u-dev/blob/cdbd94f8fa97847c02e1f0f4c6cd75f457a62e25/src/hotspot/share/prims/jvmtiTagMapTable.hpp#L43):
> 
> - Use [WeakHandle](https://github.com/openjdk/jdk21u-dev/blob/cdbd94f8fa97847c02e1f0f4c6cd75f457a62e25/src/hotspot/share/oops/weakHandle.hpp#L42) for handling oops in the table entries;
> - Use ResizeableResourceHashtable to for the underlying hash table. Table growing/resizing and removal of freed object entries are mostly handled within ResizeableResourceHashtable, except some small parts are done within TsanOopMapTable. That makes the new implementation simpler.
> 
> The TsanOopMapTable contains entries consisting of TsanOopMapTableKey:oop_size (key:value) pairs. The TsanOopMapTableKey contains:
> 
>  - A Weakhandle that holds a pointer to the oop;
>  - The original (or updated) address of the object in Java heap;
> 
> For TsanOopMapTable support, I added a new weak OopStorage, which is created during tsan_init(). All WeakHandles used for tracking Tsan interested Java objects are created from that OopStorage. GC processes these WeakHandles in concurrent WeakProcessor worker threads.
> 
> To notify Tsan about object free/move in time, I added a call in WeakProcessor::Task::work to process the TsanOopMap:
> 
> - If an object is freed by GC, call __tsan_java_free to notify Tsan. Remove the entry from the table.
> - If an object is moved by GC, update the raw address in the entry using the new oop address obtained from the WeakHandle and add the “move” to a GrowableArray.
> - After all entries in TsanOopMap are processed, sort the “moves” in the GrowableArray and notify Tsan by calling __tsan_java_move for each object in the sorted array. This part is the existing implementation from JDK 11 for Tsan support.
> 
> Note all above operations occur during GC, before any of the mutators sees a moved or freed Java object.
> 
> As an alternative, I initially experimented with doing the above operations concurrently (to mutators) in ServiceThread after GC finished processing the WeakHandles. That could occur after mutators sees moved objects and resulted incorrect data being recorded in Tsan.
> 
> Suppressed following Tsan errors in JDK:
> 1)  In `java.util.concurrent.locks`, for
> 
> WARNING: ThreadSanitizer: data race (pid=787116)...

Jiangli Zhou has updated the pull request incrementally with two additional commits since the last revision:

 - - Add comment about saved oop sizes in TsanOopMapTable.
 - - Rename SHARE_VM_PRIMS_TSAN_OOPMAPTABLE_HPP to SHARE_TSAN_TSANOOPMAPTABLE_HPP.

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

Changes:
  - all: https://git.openjdk.org/tsan/pull/19/files
  - new: https://git.openjdk.org/tsan/pull/19/files/a4496362..00bcec7f

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=tsan&pr=19&range=06
 - incr: https://webrevs.openjdk.org/?repo=tsan&pr=19&range=05-06

  Stats: 5 lines in 1 file changed: 1 ins; 0 del; 4 mod
  Patch: https://git.openjdk.org/tsan/pull/19.diff
  Fetch: git fetch https://git.openjdk.org/tsan.git pull/19/head:pull/19

PR: https://git.openjdk.org/tsan/pull/19


More information about the tsan-dev mailing list