提交 8bfd6ada 编写于 作者: S sspitsyn

7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments

Summary: Restore the appendix argument after PopFrame() call
Reviewed-by: twisti, coleenp
Contributed-by: serguei.spitsyn@oracle.com
上级 e72dd36e
...@@ -1887,6 +1887,27 @@ void TemplateInterpreterGenerator::generate_throw_exception() { ...@@ -1887,6 +1887,27 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ set_method_data_pointer_for_bcp(); __ set_method_data_pointer_for_bcp();
} }
#if INCLUDE_JVMTI
if (EnableInvokeDynamic) {
Label L_done;
__ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode
__ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done);
// The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
// Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
__ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp);
__ br_null(G1_scratch, false, Assembler::pn, L_done);
__ delayed()->nop();
__ st_ptr(G1_scratch, Lesp, wordSize);
__ bind(L_done);
}
#endif // INCLUDE_JVMTI
// Resume bytecode interpretation at the current bcp // Resume bytecode interpretation at the current bcp
__ dispatch_next(vtos); __ dispatch_next(vtos);
// end of JVMTI PopFrame support // end of JVMTI PopFrame support
......
...@@ -1920,6 +1920,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() { ...@@ -1920,6 +1920,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
__ get_thread(thread); __ get_thread(thread);
__ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
#if INCLUDE_JVMTI
if (EnableInvokeDynamic) {
Label L_done;
const Register local0 = rdi;
__ cmpb(Address(rsi, 0), Bytecodes::_invokestatic);
__ jcc(Assembler::notEqual, L_done);
// The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
// Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
__ get_method(rdx);
__ movptr(rax, Address(local0, 0));
__ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi);
__ testptr(rax, rax);
__ jcc(Assembler::zero, L_done);
__ movptr(Address(rbx, 0), rax);
__ bind(L_done);
}
#endif // INCLUDE_JVMTI
__ dispatch_next(vtos); __ dispatch_next(vtos);
// end of PopFrame support // end of PopFrame support
......
...@@ -1929,6 +1929,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() { ...@@ -1929,6 +1929,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
__ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()),
JavaThread::popframe_inactive); JavaThread::popframe_inactive);
#if INCLUDE_JVMTI
if (EnableInvokeDynamic) {
Label L_done;
const Register local0 = r14;
__ cmpb(Address(r13, 0), Bytecodes::_invokestatic);
__ jcc(Assembler::notEqual, L_done);
// The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
// Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
__ get_method(rdx);
__ movptr(rax, Address(local0, 0));
__ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13);
__ testptr(rax, rax);
__ jcc(Assembler::zero, L_done);
__ movptr(Address(rbx, 0), rax);
__ bind(L_done);
}
#endif // INCLUDE_JVMTI
__ dispatch_next(vtos); __ dispatch_next(vtos);
// end of PopFrame support // end of PopFrame support
......
...@@ -2557,6 +2557,26 @@ void java_lang_ref_SoftReference::set_clock(jlong value) { ...@@ -2557,6 +2557,26 @@ void java_lang_ref_SoftReference::set_clock(jlong value) {
*offset = value; *offset = value;
} }
// Support for java_lang_invoke_DirectMethodHandle
int java_lang_invoke_DirectMethodHandle::_member_offset;
oop java_lang_invoke_DirectMethodHandle::member(oop dmh) {
oop member_name = NULL;
bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh);
assert(is_dmh, "a DirectMethodHandle oop is expected");
if (is_dmh) {
member_name = dmh->obj_field(member_offset_in_bytes());
}
return member_name;
}
void java_lang_invoke_DirectMethodHandle::compute_offsets() {
Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass();
if (klass_oop != NULL && EnableInvokeDynamic) {
compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature());
}
}
// Support for java_lang_invoke_MethodHandle // Support for java_lang_invoke_MethodHandle
...@@ -3205,6 +3225,7 @@ void JavaClasses::compute_offsets() { ...@@ -3205,6 +3225,7 @@ void JavaClasses::compute_offsets() {
java_lang_ThreadGroup::compute_offsets(); java_lang_ThreadGroup::compute_offsets();
if (EnableInvokeDynamic) { if (EnableInvokeDynamic) {
java_lang_invoke_MethodHandle::compute_offsets(); java_lang_invoke_MethodHandle::compute_offsets();
java_lang_invoke_DirectMethodHandle::compute_offsets();
java_lang_invoke_MemberName::compute_offsets(); java_lang_invoke_MemberName::compute_offsets();
java_lang_invoke_LambdaForm::compute_offsets(); java_lang_invoke_LambdaForm::compute_offsets();
java_lang_invoke_MethodType::compute_offsets(); java_lang_invoke_MethodType::compute_offsets();
......
...@@ -976,6 +976,32 @@ class java_lang_invoke_MethodHandle: AllStatic { ...@@ -976,6 +976,32 @@ class java_lang_invoke_MethodHandle: AllStatic {
static int form_offset_in_bytes() { return _form_offset; } static int form_offset_in_bytes() { return _form_offset; }
}; };
// Interface to java.lang.invoke.DirectMethodHandle objects
class java_lang_invoke_DirectMethodHandle: AllStatic {
friend class JavaClasses;
private:
static int _member_offset; // the MemberName of this DMH
static void compute_offsets();
public:
// Accessors
static oop member(oop mh);
// Testers
static bool is_subclass(Klass* klass) {
return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
}
// Accessors for code generation:
static int member_offset_in_bytes() { return _member_offset; }
};
// Interface to java.lang.invoke.LambdaForm objects // Interface to java.lang.invoke.LambdaForm objects
// (These are a private interface for managing adapter code generation.) // (These are a private interface for managing adapter code generation.)
......
...@@ -151,6 +151,7 @@ class SymbolPropertyTable; ...@@ -151,6 +151,7 @@ class SymbolPropertyTable;
do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \ do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \
\ \
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \
do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \
do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \
......
...@@ -255,6 +255,7 @@ ...@@ -255,6 +255,7 @@
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \
template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \
template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \
template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \
template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \
...@@ -352,6 +353,7 @@ ...@@ -352,6 +353,7 @@
template(thread_id_name, "tid") \ template(thread_id_name, "tid") \
template(newInstance0_name, "newInstance0") \ template(newInstance0_name, "newInstance0") \
template(limit_name, "limit") \ template(limit_name, "limit") \
template(member_name, "member") \
template(forName_name, "forName") \ template(forName_name, "forName") \
template(forName0_name, "forName0") \ template(forName0_name, "forName0") \
template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \ template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \
......
...@@ -1209,3 +1209,26 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa ...@@ -1209,3 +1209,26 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa
size_of_arguments * Interpreter::stackElementSize); size_of_arguments * Interpreter::stackElementSize);
IRT_END IRT_END
#endif #endif
#if INCLUDE_JVMTI
// This is a support of the JVMTI PopFrame interface.
// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument
// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters.
// The dmh argument is a reference to a DirectMethoHandle that has a member name field.
IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh,
Method* method, address bcp))
Bytecodes::Code code = Bytecodes::code_at(method, bcp);
if (code != Bytecodes::_invokestatic) {
return;
}
ConstantPool* cpool = method->constants();
int cp_index = Bytes::get_native_u2(bcp + 1) + ConstantPool::CPCACHE_INDEX_TAG;
Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index));
Symbol* mname = cpool->name_ref_at(cp_index);
if (MethodHandles::has_member_arg(cname, mname)) {
oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh);
thread->set_vm_result(member_name);
}
IRT_END
#endif // INCLUDE_JVMTI
...@@ -95,6 +95,9 @@ class InterpreterRuntime: AllStatic { ...@@ -95,6 +95,9 @@ class InterpreterRuntime: AllStatic {
static void create_exception(JavaThread* thread, char* name, char* message); static void create_exception(JavaThread* thread, char* name, char* message);
static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj); static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception); static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
#if INCLUDE_JVMTI
static void member_name_arg_or_null(JavaThread* thread, address dmh, Method* m, address bcp);
#endif
static void throw_pending_exception(JavaThread* thread); static void throw_pending_exception(JavaThread* thread);
// Statics & fields // Statics & fields
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册