changeset 8620:56123fdca84a jdk8u171-b08

8194739: Zero port of 8174962: Better interface invocations Reviewed-by: adinn, coleenp
author aph
date Mon, 22 Jan 2018 15:19:02 +0000
parents 1252eaaa2c8b
children 4fefe015a728
files src/cpu/zero/vm/methodHandles_zero.cpp src/share/vm/interpreter/bytecodeInterpreter.cpp
diffstat 2 files changed, 32 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/zero/vm/methodHandles_zero.cpp	Thu Feb 22 21:28:07 2018 -0800
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp	Mon Jan 22 15:19:02 2018 +0000
@@ -180,3 +180,9 @@
     return NULL;
   }
 }
+
+#ifndef PRODUCT
+void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
+  // This is just a stub.
+}
+#endif //PRODUCT
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Feb 22 21:28:07 2018 -0800
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Mon Jan 22 15:19:02 2018 +0000
@@ -2569,13 +2569,35 @@
 
         // this could definitely be cleaned up QQQ
         Method* callee;
-        Klass* iclass = cache->f1_as_klass();
-        // InstanceKlass* interface = (InstanceKlass*) iclass;
+        Method *interface_method = cache->f2_as_interface_method();
+        InstanceKlass* iclass = interface_method->method_holder();
+
         // get receiver
         int parms = cache->parameter_size();
         oop rcvr = STACK_OBJECT(-parms);
         CHECK_NULL(rcvr);
         InstanceKlass* int2 = (InstanceKlass*) rcvr->klass();
+
+        // Receiver subtype check against resolved interface klass (REFC).
+        {
+          Klass* refc = cache->f1_as_klass();
+          itableOffsetEntry* scan;
+          for (scan = (itableOffsetEntry*) int2->start_of_itable();
+               scan->interface_klass() != NULL;
+               scan++) {
+            if (scan->interface_klass() == refc) {
+              break;
+            }
+          }
+          // Check that the entry is non-null.  A null entry means
+          // that the receiver class doesn't implement the
+          // interface, and wasn't the same as when the caller was
+          // compiled.
+          if (scan->interface_klass() == NULL) {
+            VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap);
+          }
+        }
+
         itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable();
         int i;
         for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) {
@@ -2587,7 +2609,8 @@
         if (i == int2->itable_length()) {
           VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap);
         }
-        int mindex = cache->f2_as_index();
+        int mindex = interface_method->itable_index();
+
         itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
         callee = im[mindex].method();
         if (callee == NULL) {