< prev index next >

src/hotspot/cpu/zero/methodHandles_zero.cpp

Print this page
@  rev 50381 : 8203188: Add JEP-181 support to the Zero interpreter
|  Reviewed-by: dholmes, chrisphi
~

@@ -24,10 +24,11 @@
  */
 
 #include "precompiled.hpp"
 #include "interpreter/cppInterpreterGenerator.hpp"
 #include "interpreter/interpreter.hpp"
+#include "interpreter/interpreterRuntime.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/method.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/frame.inline.hpp"

@@ -63,10 +64,41 @@
 
   return top;
 
 }
 
+void MethodHandles::throw_AME(Klass* rcvr, Method* interface_method, TRAPS) {
+
+  JavaThread *thread = (JavaThread *) THREAD;
+  // Set up the frame anchor if it isn't already
+  bool has_last_Java_frame = thread->has_last_Java_frame();
+  if (!has_last_Java_frame) {
+    intptr_t *sp = thread->zero_stack()->sp();
+    ZeroFrame *frame = thread->top_zero_frame();
+    while (frame) {
+      if (frame->is_interpreter_frame()) {
+        interpreterState istate =
+          frame->as_interpreter_frame()->interpreter_state();
+        if (istate->self_link() == istate)
+          break;
+      }
+
+      sp = ((intptr_t *) frame) + 1;
+      frame = frame->next();
+    }
+
+    assert(frame != NULL, "must be");
+    thread->set_last_Java_frame(frame, sp);
+  }
+  InterpreterRuntime::throw_AbstractMethodErrorVerbose(thread, rcvr, interface_method);
+  // Reset the frame anchor if necessary
+  if (!has_last_Java_frame) {
+    thread->reset_last_Java_frame();
+  }
+
+}
+
 int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) {
 
   JavaThread *thread = (JavaThread *) THREAD;
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();

@@ -122,12 +154,19 @@
     if (ki->interface_klass() == clazz) break;
   }
 
   itableMethodEntry* im = ki->first_method_entry(recv->klass());
   Method* vmtarget = im[vmindex].method();
-
+  // Check that the vmtarget entry is non-null.  A null entry means
+  // that the method no longer exists (got deleted) or is private.
+  // Private class methods can never be an implementation of an
+  // interface method. In those cases, throw AME.
+  if (vmtarget != NULL) {
   invoke_target(vmtarget, THREAD);
+  } else {
+    throw_AME(recv->klass(), target, THREAD);
+  }
 
   return 0;
 }
 
 int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) {
< prev index next >