< prev index next >

src/hotspot/share/interpreter/bytecodeInterpreter.cpp

Print this page
@  rev 50381 : 8203188: Add JEP-181 support to the Zero interpreter
|  Reviewed-by: dholmes, chrisphi
o  rev 50380 : Aphs' tracer code for JDK 11.
|
~

@@ -2570,15 +2570,13 @@
         }
 
         istate->set_msg(call_method);
 
         // Special case of invokeinterface called for virtual method of
-        // java.lang.Object.  See cpCacheOop.cpp for details.
-        // This code isn't produced by javac, but could be produced by
-        // another compliant java compiler.
+        // java.lang.Object.  See cpCache.cpp for details.
+        Method* callee = NULL;
         if (cache->is_forced_virtual()) {
-          Method* callee;
           CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
           if (cache->is_vfinal()) {
             callee = cache->f2_as_vfinal_method();
             // Profile 'special case of invokeinterface' final call.
             BI_PROFILE_UPDATE_FINALCALL();

@@ -2591,10 +2589,33 @@
             Klass* rcvrKlass = rcvr->klass();
             callee = (Method*) rcvrKlass->method_at_vtable(cache->f2_as_index());
             // Profile 'special case of invokeinterface' virtual call.
             BI_PROFILE_UPDATE_VIRTUALCALL(rcvrKlass);
           }
+        } else if (cache->is_vfinal()) {
+          // private interface method invocations
+          //
+          // Ensure receiver class actually implements
+          // the resolved interface class. The link resolver
+          // does this, but only for the first time this
+          // interface is being called.
+          int parms = cache->parameter_size();
+          oop rcvr = STACK_OBJECT(-parms);
+          CHECK_NULL(rcvr);
+          Klass* recv_klass = rcvr->klass();
+          Klass* resolved_klass = cache->f1_as_klass();
+          if (!recv_klass->is_subtype_of(resolved_klass)) {
+            ResourceMark rm(THREAD);
+            char buf[200];
+            jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
+              recv_klass->external_name(),
+              resolved_klass->external_name());
+            VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), buf, note_no_trap);
+          }
+          callee = cache->f2_as_vfinal_method();
+        }
+        if (callee != NULL) {
           istate->set_callee(callee);
           istate->set_callee_entry_point(callee->from_interpreted_entry());
 #ifdef VM_JVMTI
           if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) {
             istate->set_callee_entry_point(callee->interpreter_entry());

@@ -2603,11 +2624,10 @@
           istate->set_bcp_advance(5);
           UPDATE_PC_AND_RETURN(0); // I'll be back...
         }
 
         // this could definitely be cleaned up QQQ
-        Method* callee;
         Method *interface_method = cache->f2_as_interface_method();
         InstanceKlass* iclass = interface_method->method_holder();
 
         // get receiver
         int parms = cache->parameter_size();
< prev index next >