Integrated: Tsan oop map table hash fix
Jiangli Zhou
jiangli at openjdk.org
Mon Aug 19 22:18:57 UTC 2024
On Thu, 15 Aug 2024 00:07:22 GMT, Jiangli Zhou <jiangli at openjdk.org> wrote:
> Additional testing on JDK 21 with tsan found some crashes due to using `oop` `identity_hash` for computing the TsanOopMap entry hash. The crashes manifest as following two types:
>
> 1) `guarantee(moves_this_cycle) failed: "Impossible to reconcile GC"`
>
> 2) `ThreadSanitizer: CHECK failed: tsan_sync.cpp:261 "((*dst_meta)) == ((0))"`
>
> With `-Xlog:tsan=trace` output, I found the same `oop` is added to the map twice in some cases. The second time when an `oop` is added occurs during `InterpreterMacroAssembler::lock_object` path. Apparently a new identity hash is computed for the `oop` with a previous computed identity hash. That causes the `oop` being added again. Later when notifying tsan if the `oop` is moved, it triggers the above crashes depending on the memory layout.
>
> This fix computes `primitive_hash` using the oop address instead of `identity_hash` for entry hash. During GC, `TsanOopMapTable::collect_moved_objects_and_notify_freed` unlinks an entry from the map if the enclosing `oop` is moved. The moved entries are collected into an array and are inserted back to the map after iterating the map (within a worker thread). That's needed since the entry hash would be different after an `oop` is moved. The operations are protected by the `TsanOopMap_lock`.
>
> Since `primitive_hash` is now used, I also changed `TsanOopMapTableKey::get_hash` and `TsanOopMapTableKey::equals` to use `entry.object_no_keepalive()` instead of `entry._obj`. If `entry._obj` is outdated, it could result incorrect hash value for the current entry. So the updated oop address should be used instead. Running tsan jtreg tests on slowdebug binary run into new failures without the change.
>
> The change is updated to only call `TsanOopMap::notify_tsan_for_freed_and_moved_objects` from the last worker thread that completes the parallel WeakProcessor::Task work.
>
> Testing
>
> Tsan jtreg tests on linux-x64:
>
> $ bash configure --with-boot-jdk=/usr/local/google/home/jianglizhou/openjdk/jdk-21.0.1 --with-debug-level=release --disable-warnings-as-errors --with-jtreg=/usr/local/google/home/jianglizhou/github/jtreg/build/images/jtreg --with-stdc++lib=static --disable-precompiled-headers --enable-unlimited-crypto --with-native-debug-symbols=internal --with-default-make-target=jdk-image --disable-warnings-as-errors --with-toolchain-type=clang
>
>
> ==============================
> Test summary
> ==============================
> TEST TOTAL PASS FAIL ERROR
> jtreg:test/hot...
This pull request has now been integrated.
Changeset: aa3821a2
Author: Jiangli Zhou <jiangli at openjdk.org>
URL: https://git.openjdk.org/tsan/commit/aa3821a24450081e41d495da2841dd15496727d3
Stats: 97 lines in 6 files changed: 72 ins; 13 del; 12 mod
Tsan oop map table hash fix
Reviewed-by: manc
-------------
PR: https://git.openjdk.org/tsan/pull/23
More information about the tsan-dev
mailing list