MethodHandle initialization process - problem with JVM TI early VM start event

David Holmes david.holmes at oracle.com
Wed Jan 4 07:03:44 UTC 2017


Looking further into this the crash occurs because java.lang.Class has 
not been initialized yet. Logging shows we go straight from initializing 
Object to initializing java.net.Authenticator then to 
java.lang.invoke.MethodHandleNatives.

[3.484s][debug][vtables ] Initializing: java/lang/invoke/MethodHandleNatives
[3.484s][trace][vtables ] copy vtable from java.lang.Object to 
java.lang.invoke.MethodHandleNatives size 5
[3.484s][info ][class,init ] 2 Initializing 
'java/lang/invoke/MethodHandleNatives' (0x000000080000c608)
[3.485s][debug][class,resolve ] java.lang.invoke.MethodHandleNatives 
java.lang.Class MethodHandleNatives.java:44
[3.485s][trace][vtables ] invokevirtual resolved method: 
caller-class:java.lang.invoke.MethodHandleNatives, 
compile-time-class:java.lang.Class, 
method:java.lang.Class.desiredAssertionStatus()Z, 
method_holder:java.lang.Class, access_flags: public
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/linkResolver.cpp:1295

But why we are not implicitly initializing java.lang.Class before the 
invokevirtual processing?

The clinit for MethodHandleNatives starts with:

  static {};
     descriptor: ()V
     flags: (0x0008) ACC_STATIC
     Code:
       stack=3, locals=2, args_size=0
          0: ldc #160 // class java/lang/invoke/MethodHandleNatives
          2: invokevirtual #161 // Method 
java/lang/Class.desiredAssertionStatus:()Z

A class must be initialized before we may invoke a method on it, or 
obtain an instance - so why is nothing ensuring java.lang.Class is 
initialized?

David
-----

On 4/01/2017 1:11 PM, David Holmes wrote:
> We have encountered a crash in a JVM TI test, starting with b148, that
> is caused by the attempted use of MethodRefs and invoke_dynamic within
> class loading that occurs from the "early VM start" JVM TI event
> callback - which happens before the VM and core classes are fully
> initialized. The class being loaded/initialized is in java.base and so
> this is allowed. The class, java.net.Authenticator, was changed in b148
> to have static initialization involving method refs and hence the
> problem was introduced.
>
> I've included a stack dump below.
>
> It is far from clear to me where responsibility for this lies, or even
> how to narrow that down. Is it in the code of MethodHandleNatives? Or is
> it in the VM linking/resolution code?
>
> Thoughts appreciated. :)
>
> Thanks,
> David
> -----
>
>
> --------------- T H R E A D ---------------
>
> Current thread (0x00007ff99c01c000): JavaThread "Unknown thread"
> [_thread_in_vm, id=31105, stack(0x00007ff9a5584000,0x00007ff9a5684000)]
>
> Stack: [0x00007ff9a5584000,0x00007ff9a5684000], sp=0x00007ff9a56809e0,
> free space=1010k
> Native frames: (J=compiled Java code, A=aot compiled Java code,
> j=interpreted, Vv=VM code, C=native code)
> V [libjvm.so+0x16b1932] VMError::report_and_die(int, char const*, char
> const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char cons
> t*, int, unsigned long)+0x162
> V [libjvm.so+0x16b26af] VMError::report_and_die(Thread*, char const*,
> int, char const*, char const*, __va_list_tag*)+0x2f
> V [libjvm.so+0xaa0fed] report_vm_error(char const*, int, char const*,
> char const*, ...)+0xdd
> V [libjvm.so+0x110fbd6]
> LinkResolver::runtime_resolve_virtual_method(CallInfo&, methodHandle
> const&, KlassHandle, Handle, KlassHandle, bool, Th
> read*)+0x1f6
> V [libjvm.so+0x11128b5] LinkResolver::resolve_invokevirtual(CallInfo&,
> Handle, constantPoolHandle const&, int, Thread*)+0x185
> V [libjvm.so+0x1113c5b] LinkResolver::resolve_invoke(CallInfo&, Handle,
> constantPoolHandle const&, int, Bytecodes::Code, Thread*)+0xab
> V [libjvm.so+0xdea7da] InterpreterRuntime::resolve_invoke(JavaThread*,
> Bytecodes::Code)+0x23a
> V [libjvm.so+0xdf69bb]
> InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0xeb
> j java.lang.invoke.MethodHandleNatives.<clinit>()V+2 java.base
> v ~StubRoutines::call_stub
> V [libjvm.so+0xe15970] JavaCalls::call_helper(JavaValue*, methodHandle
> const&, JavaCallArguments*, Thread*)+0x950
> V [libjvm.so+0xdcd15c]
> InstanceKlass::call_class_initializer_impl(instanceKlassHandle,
> Thread*)+0x15c
> V [libjvm.so+0xdcd2a3] InstanceKlass::call_class_initializer(Thread*)+0x83
> V [libjvm.so+0xdcd762]
> InstanceKlass::initialize_impl(instanceKlassHandle, Thread*) [clone
> .part.160]+0x4a2
> V [libjvm.so+0xdcdd2b]
> InstanceKlass::initialize_impl(instanceKlassHandle, Thread*)+0x13b
> V [libjvm.so+0xdcde72] InstanceKlass::initialize(Thread*)+0x102
> V [libjvm.so+0x110dd0c] LinkResolver::resolve_static_call(CallInfo&,
> LinkInfo const&, bool, Thread*)+0x14c
> V [libjvm.so+0xe13e3a] JavaCalls::call_static(JavaValue*, KlassHandle,
> Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x13a
> V [libjvm.so+0x15bd833]
> SystemDictionary::find_method_handle_type(Symbol*, KlassHandle,
> Thread*)+0x10f3
> V [libjvm.so+0x15be1c6]
> SystemDictionary::link_method_handle_constant(KlassHandle, int,
> KlassHandle, Symbol*, Symbol*, Thread*)+0x596
> V [libjvm.so+0xa8ad46]
> ConstantPool::resolve_constant_at_impl(constantPoolHandle const&, int,
> int, Thread*)+0x7d6
> V [libjvm.so+0xa8b7ad]
> ConstantPool::resolve_bootstrap_specifier_at_impl(constantPoolHandle
> const&, int, Thread*)+0x16d
> V [libjvm.so+0x11135db] LinkResolver::resolve_invokedynamic(CallInfo&,
> constantPoolHandle const&, int, Thread*)+0x71b
> V [libjvm.so+0x1113d2e] LinkResolver::resolve_invoke(CallInfo&, Handle,
> constantPoolHandle const&, int, Bytecodes::Code, Thread*)+0x17e
> V [libjvm.so+0xdebb64]
> InterpreterRuntime::resolve_invokedynamic(JavaThread*)+0x274
> V [libjvm.so+0xdf69a8]
> InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0xd8
> j java.net.Authenticator.<clinit>()V+0 java.base
> v ~StubRoutines::call_stub
> V [libjvm.so+0xe15970] JavaCalls::call_helper(JavaValue*, methodHandle
> const&, JavaCallArguments*, Thread*)+0x950
> V [libjvm.so+0xdcd15c]
> InstanceKlass::call_class_initializer_impl(instanceKlassHandle,
> Thread*)+0x15c
> V [libjvm.so+0xdcd2a3] InstanceKlass::call_class_initializer(Thread*)+0x83
> V [libjvm.so+0xdcd762]
> InstanceKlass::initialize_impl(instanceKlassHandle, Thread*) [clone
> .part.160]+0x4a2
> V [libjvm.so+0xdcdd2b]
> InstanceKlass::initialize_impl(instanceKlassHandle, Thread*)+0x13b
> V [libjvm.so+0xdcde72] InstanceKlass::initialize(Thread*)+0x102
> V [libjvm.so+0xf331f2] find_class_from_class_loader(JNIEnv_*, Symbol*,
> unsigned char, Handle, Handle, unsigned char, Thread*)+0x122
> V [libjvm.so+0xec0369] jni_FindClass+0x5e9
> C [libjckjvmti.so+0x60d69] vmse00101_VMStart+0x2b
> V [libjvm.so+0x107ce3b] JvmtiExport::post_early_vm_start()+0xcb
> V [libjvm.so+0x16150ee] Threads::create_vm(JavaVMInitArgs*, bool*)+0x4de


More information about the core-libs-dev mailing list