RFR: 8347463: jdk/jfr/threading/TestManyVirtualThreads.java crashes with assert(oopDesc::is_oop_or_null(val)) [v9]
Dean Long
dlong at openjdk.org
Mon Oct 27 20:54:08 UTC 2025
On Mon, 27 Oct 2025 13:03:54 GMT, Anton Seoane Ampudia <aseoane at openjdk.org> wrote:
>> This PR introduces a fix for a intermittent assert crash due to a non-oop found in the stack when deoptimizing.
>>
>> The `inline_native_GetEventWriter` JFR intrinsic performs a call into the runtime, which can safepoint, to write a checkpoint for the vthread. This call returns a global handle (`jobject`) that then gets resolved to a raw oop.
>>
>> However, the corresponding `jfr_write_checkpoint_Type` does not set any return, modelling the call as `void`. If a safepoint hits in the small window after the stub returns but before the writer oop is used, and the GC moves the object in that window, the deoptimization path cannot resolve a handle that it never recorded, leading to the subsequent crash.
>>
>> An IR Framework test is introduced to exercise the error explicitly. Additionally, related documentation in form of comments in the appropriate file (`runtime.hpp`) is added to hopefully prevent similar cases in the future.
>>
>> **Testing:** passes tiers 1-5
>
> Anton Seoane Ampudia has updated the pull request incrementally with one additional commit since the last revision:
>
> Adjust comment
src/hotspot/share/opto/runtime.hpp line 55:
> 53: // even if the return value is unused. This is crucial for correct handling
> 54: // of runtime calls that return an oop and may trigger deoptimization
> 55: // on return. See rematerialize_objects() in deoptimization.cpp.
I was wondering why this is only a problem for deoptimization, and not regular safepoints that trigger a GC. But the comment in rematerialize_objects() explains that the return value is not part of the GC oopmap.
test/hotspot/jtreg/compiler/intrinsics/TestReturnsOopSetForJFRWriteCheckpoint.java line 49:
> 47: }
> 48:
> 49: // Crash was due to the returns_oop field not being set
I was confused when I could not find "returns_oop". It turns out the names are CallNode::returns_pointer() and ScopeDesc::return_oop().
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27913#discussion_r2467041649
PR Review Comment: https://git.openjdk.org/jdk/pull/27913#discussion_r2467037934
More information about the hotspot-compiler-dev
mailing list