C1 code installation and JNIHandle::deleted_handle() oop

Roman Kennke rkennke at redhat.com
Tue Nov 14 15:02:25 UTC 2017

When the compiler thread is _in_native state, it doesn't stop for 
safepoints, e.g. GC. This means it must not touch naked oops, otherwise 
the GC may move away the oop under our feet. Seems like this is what 
happens here.
I am not sure what granularity VM_ENTRY_MARK are usually done. My 
feeling is that it should be somewhere around 
LIR_Assembler::emit_code(BlockList*) ?


> Hi,
> In some of our aggressive test configurations for Shenandoah, we sometimes see the following failure:
>    http://cr.openjdk.java.net/~shade/shenandoah/c1-race-fail-hs_err.log
> It seems to happen when C1 code installation is happening during Full GC.
> The actual failure is caused by touching the JNIHandles::deleted_handle() oop in
> JNIHandles::guard_value() during JNIHandles::resolve() against the constant oop handle when we are
> recording the debugging information for C1-generated Java call:
>    http://hg.openjdk.java.net/jdk/hs/file/5caa1d5f74c1/src/hotspot/share/runtime/jniHandles.hpp#l220
> The C1 thread is in _thread_in_native state, and so the runtime thinks the thread is at safepoint,
> but the thread touches the deleted_handle oop(). When Shenandoah dives into Full GC and moves that
> object at the same time, everything crashes and burns.
> Is C1 (and any other compiler thread) supposed to transit to _vm_state when touching the naked oops,
> and thus coordinate with safepoints? I see VM_ENTRY_MARK all over ci* that seems to transit there
> before accessing the heap. Does that mean we need the same everywhere around JNIHandles::resolve too?
> Or is there some other mechanism that is supposed to get compiler threads to coordinate with GC?
> Thanks,
> -Aleksey

More information about the hotspot-compiler-dev mailing list