< prev index next >
src/hotspot/cpu/zero/methodHandles_zero.cpp
Print this page
@ rev 50287 : 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,17 @@
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, hence 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 >