JDK-8067247 : Crash: assert(method_holder->data() == 0 ...) failed: a) MT-unsafe modification of inline cache
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-12-11
  • Updated: 2016-04-28
  • Resolved: 2016-04-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
9 b115Fixed
Related Reports
Relates :  
Relates :  
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=\compiledIC_x86.cpp:106
# A fatal error has been detected by the Java Runtime Environment:
#  Internal Error (C:\...\hotspot\src\cpu\x86\vm\compiledIC_x86.cpp:106), pid=7372, tid=9720
#  assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee()) failed: a) MT-unsafe modification of inline cache
# JRE version: Java(TM) SE Runtime Environment (9.0) (build 1.9.0-internal-fastdebug-...)
# Java VM: Java HotSpot(TM) Client VM (1.9.0-internal-...)
# Core dump written. Default location: C:\...

see https://bugs.openjdk.java.net/browse/JDK-8144856

[~dlong] I don't think that JDK-8140659 is related. It requires multiple threads to trigger concurrent indy call site linkage. But there's only 1 application thread in vm/mlvm/indy/stress/gc/lotsOfCallSites: Java Threads: ( => current thread ) 0xf63c8400 JavaThread "Service Thread" daemon [_thread_blocked, id=23183, stack(0xe33af000,0xe3400000)] 0xf63c2400 JavaThread "Sweeper thread" daemon [_thread_blocked, id=23182, stack(0xe352e000,0xe357f000)] 0xf63c0800 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=23181, stack(0xe357f000,0xe3600000)] 0xf63bcc00 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=23180, stack(0xe390d000,0xe395e000)] 0xf63a3800 JavaThread "Finalizer" daemon [_thread_blocked, id=23179, stack(0xe395e000,0xe39af000)] 0xf639a000 JavaThread "Reference Handler" daemon [_thread_blocked, id=23178, stack(0xe39af000,0xe3a00000)] =>0xf630dc00 JavaThread "main" [_thread_in_vm, id=23174, stack(0xf77a4000,0xf77f5000)] V [libjvm.so+0x3cb76b] CompiledStaticCall::set_to_interpreted(methodHandle, unsigned char*)+0xfb V [libjvm.so+0x3c9a1f] CompiledIC::set_to_monomorphic(CompiledICInfo&)+0x41f V [libjvm.so+0xa20a1e] SharedRuntime::resolve_sub_helper(JavaThread*, bool, bool, Thread*)+0xa8e V [libjvm.so+0xa20ad3] SharedRuntime::resolve_helper(JavaThread*, bool, bool, Thread*)+0x53 V [libjvm.so+0xa2a7f3] SharedRuntime::resolve_opt_virtual_call_C(JavaThread*)+0x113 v ~RuntimeStub::resolve_opt_virtual_call J 446% C1 vm.mlvm.indy.stress.gc.lotsOfCallSites.Test.run()Z (300 bytes) @ 0xf4411628 [0xf4410f10+0x00000718] http://aurora-ds3.us.oracle.com:9502/runs/01153/1153476.VMSQE.PIT/1153476.VMSQE.PIT-516/results/ResultDir/lotsOfCallSites/hs_err_pid23170.log

It does look similar to JDK-8005873. invoke_MT LambdaForm corresponds to generic invoke (MH::invoke()). Though the MethodHandle can always be the same at some particular call site, the framework sometimes switches the LambdaForm by calling MethodHandle.updateForm. E.g., a MethodHandle customization request (MethodHandle.customize) can trigger LambdaForm substitution. But I don't see how generic invoker can be customized. So, probably, the root cause is different.

My memory is fuzzy about this but an invokehandle was an invokevirtual before rewriting and it's used for signature-polymorphic methods. I don't think the Method* can change but I might be wrong. Maybe [~jrose] or [~vlivanov] knows.

It's been failing since Dec 2014. I just saw 8140659, which on the surface sounds like it could be related.

There seems to be inconsistencies in SharedRuntime::resolve_helper about whether invokehandle should appear to be virtual or not. There's an assert saying it shouldn't be but there are also is_virtual paths that check for invokehandle. I think the code assumes they are non-virtual. If the Method* can change then I think it needs to use a patching strategy like is being done with CompiledIC virtual invokes. Why would this just be failing now though?

OK, I was only looking at the internal name from the Symbol. The hash values in the java_mirror's are indeed different. The bytecode of the invoke is Bytecodes::_invokehandle. Is the Method * allowed to change in that case?

Anonymous classes should have a hash appended to their name. See: Klass::external_name()

I looked at a crash from 12/4. The two different Method *'s do not match, even though they have the same method name and klass name: java/lang/invoke/LambdaForm$MH.invoke_MT. There are two different "anonymous" InstanceKlass's with the same name. Could this be related to 8072008? But that change came in after the crash on 11/9,

Maybe. I don't think you can use CompiledStaticCall if the Method* is ever going to change. The assert is completely correct that this will be an unsafe transition.

There's only one thread running so it can't actually be an MT safety issue. Shouldn't the contents of a compiled static call stub always be the same once it's been resolved? The callee is a methodHandle and the method shouldn't change. I think someone needs to look at the code at a failure in order to understand it. Actually what happens with class redefinition? The Method* will change so there's no way to MT safely rewrite the stub unless it was cleared first. Maybe that's already handled but someone should check.

[~never], any ideas?

Notice that we are still crashing, even after this fix: http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/diff/a41fe5ffa839/src/cpu/x86/vm/compiledIC_x86.cpp#l1.34

ILW=Assert, two times, none = MMH = P3