# HG changeset patch # User dcubed # Date 1236027783 25200 # Node ID c55428da3cec014421a3e4086b2ff549c719747f # Parent f82c3012ec86a0660ef404b8e527d4e261b38bd3 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 diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -2465,7 +2465,10 @@ // InterpreterRuntime::post_method_entry(); // } // 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() { @@ -2497,6 +2500,13 @@ CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), 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); + } } diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -2161,6 +2161,18 @@ __ 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 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 diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -1512,6 +1512,15 @@ call_VM_leaf( 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); + } } diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -1593,6 +1593,14 @@ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), 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); + } } diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -1532,6 +1532,14 @@ 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 const Register swap_reg = rax; // Must use rax, for cmpxchg instruction diff -r f82c3012ec86 -r c55428da3cec hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -1506,6 +1506,17 @@ 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 // Register definitions used by locking and unlocking diff -r f82c3012ec86 -r c55428da3cec hotspot/src/share/vm/includeDB_core --- a/hotspot/src/share/vm/includeDB_core Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/share/vm/includeDB_core Mon Mar 02 14:03:03 2009 -0700 @@ -2093,6 +2093,7 @@ interp_masm_.cpp interpreterRuntime.hpp interp_masm_.cpp interpreter.hpp interp_masm_.cpp jvmtiExport.hpp +interp_masm_.cpp jvmtiRedefineClassesTrace.hpp interp_masm_.cpp jvmtiThreadState.hpp interp_masm_.cpp markOop.hpp interp_masm_.cpp methodDataOop.hpp @@ -3669,6 +3670,7 @@ sharedRuntime.cpp interpreter.hpp sharedRuntime.cpp javaCalls.hpp sharedRuntime.cpp jvmtiExport.hpp +sharedRuntime.cpp jvmtiRedefineClassesTrace.hpp sharedRuntime.cpp nativeInst_.hpp sharedRuntime.cpp nativeLookup.hpp sharedRuntime.cpp oop.inline.hpp @@ -3698,6 +3700,7 @@ sharedRuntime_.cpp debugInfoRec.hpp sharedRuntime_.cpp icBuffer.hpp sharedRuntime_.cpp interpreter.hpp +sharedRuntime_.cpp jvmtiRedefineClassesTrace.hpp sharedRuntime_.cpp sharedRuntime.hpp sharedRuntime_.cpp vframeArray.hpp sharedRuntime_.cpp vmreg_.inline.hpp diff -r f82c3012ec86 -r c55428da3cec hotspot/src/share/vm/oops/klassVtable.cpp --- a/hotspot/src/share/vm/oops/klassVtable.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/share/vm/oops/klassVtable.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -992,6 +992,10 @@ methodOop new_method = new_methods[j]; 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++) { if (ime->method() == old_method) { ime->initialize(new_method); @@ -1008,7 +1012,6 @@ new_method->name()->as_C_string(), new_method->signature()->as_C_string())); } - break; } ime++; } diff -r f82c3012ec86 -r c55428da3cec hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp Mon Mar 02 14:03:03 2009 -0700 @@ -49,8 +49,8 @@ // 0x00000400 | 1024 - previous class weak reference mgmt during // add previous ops (GC) // 0x00000800 | 2048 - previous class breakpoint mgmt -// 0x00001000 | 4096 - unused -// 0x00002000 | 8192 - unused +// 0x00001000 | 4096 - detect calls to obsolete methods +// 0x00002000 | 8192 - fail a guarantee() in addition to detection // 0x00004000 | 16384 - unused // 0x00008000 | 32768 - old/new method matching/add/delete // 0x00010000 | 65536 - impl details: CP size info diff -r f82c3012ec86 -r c55428da3cec hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Mar 02 14:03:03 2009 -0700 @@ -395,6 +395,32 @@ 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 // for given exception address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, diff -r f82c3012ec86 -r c55428da3cec hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Mon Mar 02 14:00:23 2009 -0700 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Mon Mar 02 14:03:03 2009 -0700 @@ -166,6 +166,9 @@ 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); + // 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. static address native_method_throw_unsatisfied_link_error_entry();