8150436: Incorrect invocation mode when linkToInteface linker is eliminated
authorvlivanov
Fri, 26 Feb 2016 01:58:29 +0300
changeset 36331 eeeb86fd9922
parent 36330 37a0f096251b
child 36332 6fa29ad824ad
8150436: Incorrect invocation mode when linkToInteface linker is eliminated Reviewed-by: kvn, shade
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Feb 26 01:58:26 2016 +0300
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Feb 26 01:58:29 2016 +0300
@@ -1134,12 +1134,19 @@
         MethodHandles::is_signature_polymorphic_intrinsic(id)) {
       bc = MethodHandles::signature_polymorphic_intrinsic_bytecode(id);
 
-      // Need to adjust invokehandle since inlining through signature-polymorphic
-      // method happened.
-      if (bc == Bytecodes::_invokehandle &&
-          !MethodHandles::is_signature_polymorphic_method(attached_method())) {
-        bc = attached_method->is_static() ? Bytecodes::_invokestatic
-                                          : Bytecodes::_invokevirtual;
+      // Adjust invocation mode according to the attached method.
+      switch (bc) {
+        case Bytecodes::_invokeinterface:
+          if (!attached_method->method_holder()->is_interface()) {
+            bc = Bytecodes::_invokevirtual;
+          }
+          break;
+        case Bytecodes::_invokehandle:
+          if (!MethodHandles::is_signature_polymorphic_method(attached_method())) {
+            bc = attached_method->is_static() ? Bytecodes::_invokestatic
+                                              : Bytecodes::_invokevirtual;
+          }
+          break;
       }
     }
   } else {
--- a/hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java	Fri Feb 26 01:58:26 2016 +0300
+++ b/hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java	Fri Feb 26 01:58:29 2016 +0300
@@ -180,7 +180,10 @@
     static void testInterface() {
         System.out.println("linkToInterface");
 
-        // Monomorphic case (optimized virtual call)
+        // Monomorphic case (optimized virtual call), concrete target method
+        run(() -> linkToInterface(new P1(), P1.class));
+
+        // Monomorphic case (optimized virtual call), default target method
         run(() -> linkToInterface(new T(), I.class));
 
         // Megamorphic case (virtual call)