提交 063714b3 编写于 作者: D dcubed

6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined

Summary: Remove incorrect optimization in klassItable::adjust_method_entries(). Add RedefineClasses() tracing support for obsolete method entry.
Reviewed-by: acorn, swamyv
上级 2543ed9a
...@@ -2465,7 +2465,10 @@ void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { ...@@ -2465,7 +2465,10 @@ void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
// InterpreterRuntime::post_method_entry(); // InterpreterRuntime::post_method_entry();
// } // }
// if (DTraceMethodProbes) { // if (DTraceMethodProbes) {
// SharedRuntime::dtrace_method_entry(method, reciever); // SharedRuntime::dtrace_method_entry(method, receiver);
// }
// if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
// SharedRuntime::rc_trace_method_entry(method, receiver);
// } // }
void InterpreterMacroAssembler::notify_method_entry() { void InterpreterMacroAssembler::notify_method_entry() {
...@@ -2497,6 +2500,13 @@ void InterpreterMacroAssembler::notify_method_entry() { ...@@ -2497,6 +2500,13 @@ void InterpreterMacroAssembler::notify_method_entry() {
CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
G2_thread, Lmethod); G2_thread, Lmethod);
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
call_VM_leaf(noreg,
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
G2_thread, Lmethod);
}
} }
......
...@@ -2161,6 +2161,18 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ...@@ -2161,6 +2161,18 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ restore(); __ restore();
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
// create inner frame
__ save_frame(0);
__ mov(G2_thread, L7_thread_cache);
__ set_oop_constant(JNIHandles::make_local(method()), O1);
__ call_VM_leaf(L7_thread_cache,
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
G2_thread, O1);
__ restore();
}
// We are in the jni frame unless saved_frame is true in which case // We are in the jni frame unless saved_frame is true in which case
// we are in one frame deeper (the "inner" frame). If we are in the // we are in one frame deeper (the "inner" frame). If we are in the
// "inner" frames the args are in the Iregs and if the jni frame then // "inner" frames the args are in the Iregs and if the jni frame then
......
...@@ -1512,6 +1512,15 @@ void InterpreterMacroAssembler::notify_method_entry() { ...@@ -1512,6 +1512,15 @@ void InterpreterMacroAssembler::notify_method_entry() {
call_VM_leaf( call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), rcx, rbx); CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), rcx, rbx);
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
get_thread(rcx);
get_method(rbx);
call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
rcx, rbx);
}
} }
......
...@@ -1593,6 +1593,14 @@ void InterpreterMacroAssembler::notify_method_entry() { ...@@ -1593,6 +1593,14 @@ void InterpreterMacroAssembler::notify_method_entry() {
call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
r15_thread, c_rarg1); r15_thread, c_rarg1);
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
get_method(c_rarg1);
call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
r15_thread, c_rarg1);
}
} }
......
...@@ -1532,6 +1532,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, ...@@ -1532,6 +1532,14 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
thread, rax); thread, rax);
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
__ movoop(rax, JNIHandles::make_local(method()));
__ call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
thread, rax);
}
// These are register definitions we need for locking/unlocking // These are register definitions we need for locking/unlocking
const Register swap_reg = rax; // Must use rax, for cmpxchg instruction const Register swap_reg = rax; // Must use rax, for cmpxchg instruction
......
...@@ -1506,6 +1506,17 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, ...@@ -1506,6 +1506,17 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
restore_args(masm, total_c_args, c_arg, out_regs); restore_args(masm, total_c_args, c_arg, out_regs);
} }
// RedefineClasses() tracing support for obsolete method entry
if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
// protect the args we've loaded
save_args(masm, total_c_args, c_arg, out_regs);
__ movoop(c_rarg1, JNIHandles::make_local(method()));
__ call_VM_leaf(
CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
r15_thread, c_rarg1);
restore_args(masm, total_c_args, c_arg, out_regs);
}
// Lock a synchronized method // Lock a synchronized method
// Register definitions used by locking and unlocking // Register definitions used by locking and unlocking
......
...@@ -2093,6 +2093,7 @@ interp_masm_<arch_model>.cpp interp_masm_<arch_model>.hpp ...@@ -2093,6 +2093,7 @@ interp_masm_<arch_model>.cpp interp_masm_<arch_model>.hpp
interp_masm_<arch_model>.cpp interpreterRuntime.hpp interp_masm_<arch_model>.cpp interpreterRuntime.hpp
interp_masm_<arch_model>.cpp interpreter.hpp interp_masm_<arch_model>.cpp interpreter.hpp
interp_masm_<arch_model>.cpp jvmtiExport.hpp interp_masm_<arch_model>.cpp jvmtiExport.hpp
interp_masm_<arch_model>.cpp jvmtiRedefineClassesTrace.hpp
interp_masm_<arch_model>.cpp jvmtiThreadState.hpp interp_masm_<arch_model>.cpp jvmtiThreadState.hpp
interp_masm_<arch_model>.cpp markOop.hpp interp_masm_<arch_model>.cpp markOop.hpp
interp_masm_<arch_model>.cpp methodDataOop.hpp interp_masm_<arch_model>.cpp methodDataOop.hpp
...@@ -3669,6 +3670,7 @@ sharedRuntime.cpp interpreterRuntime.hpp ...@@ -3669,6 +3670,7 @@ sharedRuntime.cpp interpreterRuntime.hpp
sharedRuntime.cpp interpreter.hpp sharedRuntime.cpp interpreter.hpp
sharedRuntime.cpp javaCalls.hpp sharedRuntime.cpp javaCalls.hpp
sharedRuntime.cpp jvmtiExport.hpp sharedRuntime.cpp jvmtiExport.hpp
sharedRuntime.cpp jvmtiRedefineClassesTrace.hpp
sharedRuntime.cpp nativeInst_<arch>.hpp sharedRuntime.cpp nativeInst_<arch>.hpp
sharedRuntime.cpp nativeLookup.hpp sharedRuntime.cpp nativeLookup.hpp
sharedRuntime.cpp oop.inline.hpp sharedRuntime.cpp oop.inline.hpp
...@@ -3698,6 +3700,7 @@ sharedRuntime_<arch_model>.cpp compiledICHolderOop.hpp ...@@ -3698,6 +3700,7 @@ sharedRuntime_<arch_model>.cpp compiledICHolderOop.hpp
sharedRuntime_<arch_model>.cpp debugInfoRec.hpp sharedRuntime_<arch_model>.cpp debugInfoRec.hpp
sharedRuntime_<arch_model>.cpp icBuffer.hpp sharedRuntime_<arch_model>.cpp icBuffer.hpp
sharedRuntime_<arch_model>.cpp interpreter.hpp sharedRuntime_<arch_model>.cpp interpreter.hpp
sharedRuntime_<arch_model>.cpp jvmtiRedefineClassesTrace.hpp
sharedRuntime_<arch_model>.cpp sharedRuntime.hpp sharedRuntime_<arch_model>.cpp sharedRuntime.hpp
sharedRuntime_<arch_model>.cpp vframeArray.hpp sharedRuntime_<arch_model>.cpp vframeArray.hpp
sharedRuntime_<arch_model>.cpp vmreg_<arch>.inline.hpp sharedRuntime_<arch_model>.cpp vmreg_<arch>.inline.hpp
......
...@@ -992,6 +992,10 @@ void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_m ...@@ -992,6 +992,10 @@ void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_m
methodOop new_method = new_methods[j]; methodOop new_method = new_methods[j];
itableMethodEntry* ime = method_entry(0); itableMethodEntry* ime = method_entry(0);
// The itable can describe more than one interface and the same
// method signature can be specified by more than one interface.
// This means we have to do an exhaustive search to find all the
// old_method references.
for (int i = 0; i < _size_method_table; i++) { for (int i = 0; i < _size_method_table; i++) {
if (ime->method() == old_method) { if (ime->method() == old_method) {
ime->initialize(new_method); ime->initialize(new_method);
...@@ -1008,7 +1012,6 @@ void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_m ...@@ -1008,7 +1012,6 @@ void klassItable::adjust_method_entries(methodOop* old_methods, methodOop* new_m
new_method->name()->as_C_string(), new_method->name()->as_C_string(),
new_method->signature()->as_C_string())); new_method->signature()->as_C_string()));
} }
break;
} }
ime++; ime++;
} }
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
// 0x00000400 | 1024 - previous class weak reference mgmt during // 0x00000400 | 1024 - previous class weak reference mgmt during
// add previous ops (GC) // add previous ops (GC)
// 0x00000800 | 2048 - previous class breakpoint mgmt // 0x00000800 | 2048 - previous class breakpoint mgmt
// 0x00001000 | 4096 - unused // 0x00001000 | 4096 - detect calls to obsolete methods
// 0x00002000 | 8192 - unused // 0x00002000 | 8192 - fail a guarantee() in addition to detection
// 0x00004000 | 16384 - unused // 0x00004000 | 16384 - unused
// 0x00008000 | 32768 - old/new method matching/add/delete // 0x00008000 | 32768 - old/new method matching/add/delete
// 0x00010000 | 65536 - impl details: CP size info // 0x00010000 | 65536 - impl details: CP size info
......
...@@ -395,6 +395,32 @@ void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, symbolOop ...@@ -395,6 +395,32 @@ void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, symbolOop
throw_and_post_jvmti_exception(thread, h_exception); throw_and_post_jvmti_exception(thread, h_exception);
} }
// The interpreter code to call this tracing function is only
// called/generated when TraceRedefineClasses has the right bits
// set. Since obsolete methods are never compiled, we don't have
// to modify the compilers to generate calls to this function.
//
JRT_LEAF(int, SharedRuntime::rc_trace_method_entry(
JavaThread* thread, methodOopDesc* method))
assert(RC_TRACE_IN_RANGE(0x00001000, 0x00002000), "wrong call");
if (method->is_obsolete()) {
// We are calling an obsolete method, but this is not necessarily
// an error. Our method could have been redefined just after we
// fetched the methodOop from the constant pool.
// RC_TRACE macro has an embedded ResourceMark
RC_TRACE_WITH_THREAD(0x00001000, thread,
("calling obsolete method '%s'",
method->name_and_sig_as_C_string()));
if (RC_TRACE_ENABLED(0x00002000)) {
// this option is provided to debug calls to obsolete methods
guarantee(false, "faulting at call to an obsolete method.");
}
}
return 0;
JRT_END
// ret_pc points into caller; we are returning caller's exception handler // ret_pc points into caller; we are returning caller's exception handler
// for given exception // for given exception
address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
......
...@@ -166,6 +166,9 @@ class SharedRuntime: AllStatic { ...@@ -166,6 +166,9 @@ class SharedRuntime: AllStatic {
static void throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception); static void throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception);
static void throw_and_post_jvmti_exception(JavaThread *thread, symbolOop name, const char *message = NULL); static void throw_and_post_jvmti_exception(JavaThread *thread, symbolOop name, const char *message = NULL);
// RedefineClasses() tracing support for obsolete method entry
static int rc_trace_method_entry(JavaThread* thread, methodOopDesc* m);
// To be used as the entry point for unresolved native methods. // To be used as the entry point for unresolved native methods.
static address native_method_throw_unsatisfied_link_error_entry(); static address native_method_throw_unsatisfied_link_error_entry();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册