mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
Restore the appendix argument after PopFrame() call Reviewed-by: twisti, coleenp
This commit is contained in:
parent
68198af05c
commit
4974d1aef2
@ -1887,6 +1887,27 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
if (ProfileInterpreter) {
|
||||
__ 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
|
||||
__ dispatch_next(vtos);
|
||||
// end of JVMTI PopFrame support
|
||||
|
||||
@ -1920,6 +1920,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
__ get_thread(thread);
|
||||
__ 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);
|
||||
// end of PopFrame support
|
||||
|
||||
|
||||
@ -1929,6 +1929,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
__ movl(Address(r15_thread, JavaThread::popframe_condition_offset()),
|
||||
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);
|
||||
// end of PopFrame support
|
||||
|
||||
|
||||
@ -2557,6 +2557,26 @@ void java_lang_ref_SoftReference::set_clock(jlong 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
|
||||
|
||||
@ -3205,6 +3225,7 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_ThreadGroup::compute_offsets();
|
||||
if (EnableInvokeDynamic) {
|
||||
java_lang_invoke_MethodHandle::compute_offsets();
|
||||
java_lang_invoke_DirectMethodHandle::compute_offsets();
|
||||
java_lang_invoke_MemberName::compute_offsets();
|
||||
java_lang_invoke_LambdaForm::compute_offsets();
|
||||
java_lang_invoke_MethodType::compute_offsets();
|
||||
|
||||
@ -976,6 +976,32 @@ class java_lang_invoke_MethodHandle: AllStatic {
|
||||
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
|
||||
// (These are a private interface for managing adapter code generation.)
|
||||
|
||||
|
||||
@ -151,6 +151,7 @@ class SymbolPropertyTable;
|
||||
do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \
|
||||
\
|
||||
/* 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(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \
|
||||
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \
|
||||
|
||||
@ -255,6 +255,7 @@
|
||||
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
|
||||
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
|
||||
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_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \
|
||||
template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \
|
||||
@ -352,6 +353,7 @@
|
||||
template(thread_id_name, "tid") \
|
||||
template(newInstance0_name, "newInstance0") \
|
||||
template(limit_name, "limit") \
|
||||
template(member_name, "member") \
|
||||
template(forName_name, "forName") \
|
||||
template(forName0_name, "forName0") \
|
||||
template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \
|
||||
|
||||
@ -1209,3 +1209,26 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa
|
||||
size_of_arguments * Interpreter::stackElementSize);
|
||||
IRT_END
|
||||
#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 {
|
||||
static void create_exception(JavaThread* thread, char* name, char* message);
|
||||
static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
|
||||
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);
|
||||
|
||||
// Statics & fields
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user