--- a/src/hotspot/cpu/zero/methodHandles_zero.cpp Sat Jun 23 01:32:41 2018 -0400
+++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp Tue Jun 05 11:55:39 2018 +0200
@@ -26,6 +26,7 @@
#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"
@@ -65,6 +66,37 @@
}
+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;
@@ -124,8 +156,15 @@
itableMethodEntry* im = ki->first_method_entry(recv->klass());
Method* vmtarget = im[vmindex].method();
-
- invoke_target(vmtarget, THREAD);
+ // 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;
}