C1 code installation and JNIHandle::deleted_handle() oop

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Tue Nov 14 15:36:10 UTC 2017


I agree with your & Roman analysis: compilers shouldn't touch naked oops 
unless the thread is in _thread_in_vm mode.

Looking at the crash log, the problematic code is under assert:

void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
   assert(JNIHandles::resolve(value()) == NULL ||
          "Should be in heap");

So, the proper fix would be to make the verification code more robust.

Best regards,
Vladimir Ivanov

On 11/14/17 5:16 PM, Aleksey Shipilev wrote:
> 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