JDK-8026502 : java/lang/invoke/MethodHandleConstants.java fails on all platforms
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: hs25,8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-10-15
  • Updated: 2014-04-18
  • Resolved: 2013-10-24
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.
JDK 7 JDK 8 Other
7u51Fixed 8 b115Fixed hs25Fixed
Related Reports
Duplicate :  
Relates :  
Description
Even with the fix for JDK-8022066 MethodHandleConstants.java still fails.

Note: there were significant changes to the 292 implementation recently and an updated version of JDK-8022066 was merged into the jdk8 mainline. The experts in this area have been notified, and are aware of this issue. The test has been added to the ProblemList.txt, and should be removed when this bug is fixed.

Sample failure.

TEST: java/lang/invoke/MethodHandleConstants.java
JDK under test: (/opt/jprt/T/P1/131320.chhegar/testproduct/linux_i586_2.6-product)
java version "1.8.0-internal"
Java(TM) SE Runtime Environment (build 1.8.0-internal-201310141313.chhegar.tl_13_04_staging-b00)
Java HotSpot(TM) Client VM (build 25.0-b53, mixed mode, sharing)


ACTION: build -- Passed. All files up to date
REASON: User specified action: run build indify.Indify 
TIME:   0.0 seconds
messages:
command: build indify.Indify
reason: User specified action: run build indify.Indify 
elapsed time (seconds): 0.0

ACTION: compile -- Passed. Compilation successful
REASON: User specified action: run compile MethodHandleConstants.java 
TIME:   0.028 seconds
messages:
command: compile /opt/jprt/T/P1/131320.chhegar/s/jdk/test/java/lang/invoke/MethodHandleConstants.java
reason: User specified action: run compile MethodHandleConstants.java 
elapsed time (seconds): 0.028

ACTION: build -- Passed. All files up to date
REASON: Named class compiled on demand
TIME:   0.0 seconds
messages:
command: build indify.Indify
reason: Named class compiled on demand
elapsed time (seconds): 0.0

ACTION: main -- Failed. Unexpected exit from test [exit code: 134]
REASON: User specified action: run main/othervm indify.Indify --verify-specifier-count=0 --expand-properties --classpath ${test.classes} --java test.java.lang.invoke.MethodHandleConstants --check-output 
TIME:   0.202 seconds
messages:
command: main indify.Indify --verify-specifier-count=0 --expand-properties --classpath ${test.classes} --java test.java.lang.invoke.MethodHandleConstants --check-output
reason: User specified action: run main/othervm indify.Indify --verify-specifier-count=0 --expand-properties --classpath ${test.classes} --java test.java.lang.invoke.MethodHandleConstants --check-output 
elapsed time (seconds): 0.202
STDOUT:
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x405289fa, pid=1589, tid=1670151056
#
# JRE version: Java(TM) SE Runtime Environment (8.0) (build 1.8.0-internal-201310141313.chhegar.tl_13_04_staging-b00)
# Java VM: Java HotSpot(TM) Client VM (25.0-b53 mixed mode, sharing linux-x86 )
# Problematic frame:
# V  [libjvm.so+0x4fc9fa]  SystemDictionary::find_method_handle_invoker(Symbol*, Symbol*, KlassHandle, Handle*, Handle*, Thread*)+0x4aa
#
# Core dump written. Default location: /opt/jprt/T/P1/131320.chhegar/s/jdk/build/linux-i586/testoutput/jdk_lang/JTwork/scratch/core or core.1589
#
# An error report file with more information is saved as:
# /opt/jprt/T/P1/131320.chhegar/s/jdk/build/linux-i586/testoutput/jdk_lang/JTwork/scratch/hs_err_pid1589.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#
STDERR:
patching test/java/lang/invoke/MethodHandleConstants.main(L)V
46:invokestatic 10 MH_String_replace_C2()L => ldc 299:MethodHandle[5, 298]
79:invokestatic 16 MH_MethodHandle_invokeExact_SC2()L => ldc 302:MethodHandle[5, 301]
117:invokestatic 19 MH_MethodHandle_invoke_SC2()L => ldc 305:MethodHandle[5, 304]
155:invokestatic 21 MH_Class_forName_S()L => ldc 308:MethodHandle[6, 307]
176:invokestatic 23 MH_Class_forName_SbCL()L => ldc 311:MethodHandle[6, 310]

TEST RESULT: Failed. Unexpected exit from test [exit code: 134]
Comments
Verified by regression test java/lang/invoke/MethodHandleConstants.java
18-11-2013

RULE java/lang/invoke/MethodHandleConstants.java Exception any
30-10-2013

This is the JDK part to fix the root cause: diff -r 0913c3bab168 src/share/classes/java/lang/invoke/MethodHandles.java --- a/src/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 22 15:12:22 2013 -0700 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 22 19:49:01 2013 -0700 @@ -1716,6 +1716,13 @@ return mh1; checkSymbolicClass(defc); return mh; } + // Treat MethodHandle.invoke and invokeExact specially. + if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { + mh = findVirtualForMH(member.getName(), member.getMethodType()); + if (mh != null) { + return mh; + } + } MemberName resolved = resolveOrFail(refKind, member); mh = getDirectMethodForConstant(refKind, defc, resolved); if (mh instanceof DirectMethodHandle @@ -1768,12 +1775,6 @@ return mh1; if (MethodHandleNatives.refKindIsField(refKind)) { return getDirectFieldNoSecurityManager(refKind, defc, member); } else if (MethodHandleNatives.refKindIsMethod(refKind)) { - if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { - MethodHandle mh = findVirtualForMH(member.getName(), member.getMethodType()); - if (mh != null) { - return mh; - } - } return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass); } else if (refKind == REF_newInvokeSpecial) { return getDirectConstructorNoSecurityManager(defc, member);
23-10-2013

Resolving CONSTANT_MethodHandle[MethodHandle.class, "invokeExact", <somesignature>] is causing the JVM to fall over. The path is validly used to resolve "invokeBasic" but is toxic for "invokeExact" and "invoke". Two fixes are needed. First, the JVM must not crash. Second, the JDK code must not ask the JVM to do the impossible, which is to make an absolute (context-independent) lookup of a signature polymorphic method. (MH.invokeBasic is a special case, since its semantics depend only on the erasure of its signature.) SystemDictionary::find_method_handle_type already defends correctly against a null caller_klass. The following related routines should also defend against nulls: link_method_handle_constant, find_dynamic_call_site_invoker, find_method_handle_invoker, something like this: diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp +++ b/src/share/vm/classfile/systemDictionary.cpp @@ -2334,6 +2334,10 @@ objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty)); assert(appendix_box->obj_at(0) == NULL, ""); + if (accessing_klass.is_null() || method_type.is_null()) { + THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokehandle", empty); + } + // call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName JavaCallArguments args; args.push_oop(accessing_klass()->java_mirror()); @@ -2459,6 +2463,8 @@ Handle type; if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') { type = find_method_handle_type(signature, caller, CHECK_(empty)); + } else if (caller.is_null()) { + THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MH constant", empty); } else { ResourceMark rm(THREAD); SignatureStream ss(signature, false); @@ -2522,6 +2528,10 @@ Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty)); Handle method_type = find_method_handle_type(type, caller, CHECK_(empty)); + if (caller.is_null() || method_type.is_null()) { + THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty); + } + objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty)); assert(appendix_box->obj_at(0) == NULL, "");
23-10-2013

Yes, I can reproduce the crash. The problem is that we call java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant which has this code: MemberName resolved = resolveOrFail(refKind, member); mh = getDirectMethodForConstant(refKind, defc, resolved); The check for MethodHandle.invoke and invokeExact is in getDirectMethodForConstant but we crash before we get there in resolveOrFail: Stack: [0x000000010c2e8000,0x000000010c3e8000], sp=0x000000010c3e4a20, free space=1010k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.dylib+0x1c81fc] Klass::java_mirror() const+0xc V [libjvm.dylib+0xb84583] SystemDictionary::find_method_handle_invoker(Symbol*, Symbol*, KlassHandle, Handle*, Handle*, Thread*)+0x283 V [libjvm.dylib+0x8c53bd] LinkResolver::lookup_polymorphic_method(methodHandle&, KlassHandle, Symbol*, Symbol*, KlassHandle, Handle*, Handle*, Thread*)+0x60d V [libjvm.dylib+0x8cd0b1] LinkResolver::resolve_handle_call(CallInfo&, KlassHandle, Symbol*, Symbol*, KlassHandle, Thread*)+0x161 V [libjvm.dylib+0x9b9ccd] MethodHandles::resolve_MemberName(Handle, Thread*)+0x8cd V [libjvm.dylib+0x9bc6be] MHN_resolve_Mem+0x34e j java.lang.invoke.MethodHandleNatives.resolve(Ljava/lang/invoke/MemberName;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;+0 j java.lang.invoke.MemberName$Factory.resolve(BLjava/lang/invoke/MemberName;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;+32 j java.lang.invoke.MemberName$Factory.resolveOrFail(BLjava/lang/invoke/MemberName;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MemberName;+4 j java.lang.invoke.MethodHandles$Lookup.resolveOrFail(BLjava/lang/invoke/MemberName;)Ljava/lang/invoke/MemberName;+35 j java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(BLjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+70 j java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+38
23-10-2013

Thanks, David. My question rooted in the fact that I was unsure if that change was already merged into jdk8/tl. It definitely was.
22-10-2013

Chris - I saw this fail in a jtreg run made on October 18, but I don't see it fail now. I don't see indify.Indify in the test logs anymore. I think something changed, but I don't know what. If it reappears, I'll make a note. This was with a relatively recent vintage jdk8/tl and hsx/hotspot-comp
22-10-2013

So jdk8/tl crashes on that test?
16-10-2013

Note: the changes for 8022066, including this test MethodHandleConstants.java, have been integrated into the jdk8/tl forest, for inclusion in jdk8-b113. Original Changeset: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/3e3cbd93f4f1 ... and subsequent merge: http://hg.openjdk.java.net/jdk8/tl/jdk/diff/99832c718cb8/src/share/classes/java/lang/invoke/MethodHandles.java jdk8/tl contains the latest source in the area, until it is integrated into master ( b113 ).
16-10-2013

John, are you looking into this issue?
16-10-2013