# HG changeset patch # User fparain # Date 1268820065 -3600 # Node ID 0cce506a01582073b825039b6c52ef764c426325 # Parent a7a4e66595ec0bd1df5357fc31904229e77882c2 6935224: Adding new DTrace probes to work with Palantir Summary: Adding probes related to thread scheduling and class initialization Reviewed-by: kamg, never diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/os/solaris/dtrace/hotspot.d --- a/hotspot/src/os/solaris/dtrace/hotspot.d Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/os/solaris/dtrace/hotspot.d Wed Mar 17 11:01:05 2010 +0100 @@ -25,9 +25,20 @@ provider hotspot { probe class__loaded(char*, uintptr_t, void*, uintptr_t); probe class__unloaded(char*, uintptr_t, void*, uintptr_t); + probe class__initialization__required(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__recursive(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__concurrent(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__erroneous(char*, uintptr_t, void*, intptr_t, int); + probe class__initialization__super__failed(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__clinit(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__error(char*, uintptr_t, void*, intptr_t,int); + probe class__initialization__end(char*, uintptr_t, void*, intptr_t,int); probe vm__init__begin(); probe vm__init__end(); probe vm__shutdown(); + probe vmops__request(char*, uintptr_t, int); + probe vmops__begin(char*, uintptr_t, int); + probe vmops__end(char*, uintptr_t, int); probe gc__begin(uintptr_t); probe gc__end(); probe mem__pool__gc__begin( @@ -38,6 +49,12 @@ uintptr_t, uintptr_t, uintptr_t, uintptr_t); probe thread__start(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t); probe thread__stop(char*, uintptr_t, uintptr_t, uintptr_t, uintptr_t); + probe thread__sleep__begin(long long); + probe thread__sleep__end(int); + probe thread__yield(); + probe thread__park__begin(uintptr_t, int, long long); + probe thread__park__end(uintptr_t); + probe thread__unpark(uintptr_t); probe method__compile__begin( char*, uintptr_t, char*, uintptr_t, char*, uintptr_t, char*, uintptr_t); probe method__compile__end( diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/os/solaris/vm/attachListener_solaris.cpp --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -668,13 +668,18 @@ } } - if (strcmp(name, "ExtendedDTraceProbes") != 0) { - out->print_cr("flag '%s' cannot be changed", name); - return JNI_ERR; + if (strcmp(name, "ExtendedDTraceProbes") == 0) { + DTrace::set_extended_dprobes(flag); + return JNI_OK; } - DTrace::set_extended_dprobes(flag); - return JNI_OK; + if (strcmp(name, "DTraceMonitorProbes") == 0) { + DTrace::set_monitor_dprobes(flag); + return JNI_OK; + } + + out->print_cr("flag '%s' cannot be changed", name); + return JNI_ERR; } void AttachListener::pd_detachall() { diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/includeDB_core --- a/hotspot/src/share/vm/includeDB_core Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/includeDB_core Wed Mar 17 11:01:05 2010 +0100 @@ -2024,6 +2024,7 @@ instanceKlass.cpp collectedHeap.inline.hpp instanceKlass.cpp compileBroker.hpp +instanceKlass.cpp dtrace.hpp instanceKlass.cpp fieldDescriptor.hpp instanceKlass.cpp genOopClosures.inline.hpp instanceKlass.cpp handles.inline.hpp @@ -2483,6 +2484,7 @@ jvm.cpp collectedHeap.inline.hpp jvm.cpp copy.hpp jvm.cpp defaultStream.hpp +jvm.cpp dtrace.hpp jvm.cpp dtraceJSDT.hpp jvm.cpp events.hpp jvm.cpp handles.inline.hpp @@ -4449,6 +4451,7 @@ unsafe.cpp allocation.inline.hpp unsafe.cpp copy.hpp +unsafe.cpp dtrace.hpp unsafe.cpp globals.hpp unsafe.cpp interfaceSupport.hpp unsafe.cpp jni.h @@ -4620,6 +4623,7 @@ vmThread.cpp collectedHeap.hpp vmThread.cpp compileBroker.hpp +vmThread.cpp dtrace.hpp vmThread.cpp events.hpp vmThread.cpp interfaceSupport.hpp vmThread.cpp methodOop.hpp diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -25,6 +25,58 @@ # include "incls/_precompiled.incl" # include "incls/_instanceKlass.cpp.incl" +#ifdef DTRACE_ENABLED + +HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required, + char*, intptr_t, oop, intptr_t); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error, + char*, intptr_t, oop, intptr_t, int); +HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, + char*, intptr_t, oop, intptr_t, int); + +#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \ + { \ + char* data = NULL; \ + int len = 0; \ + symbolOop name = (clss)->name(); \ + if (name != NULL) { \ + data = (char*)name->bytes(); \ + len = name->utf8_length(); \ + } \ + HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ + data, len, (clss)->class_loader(), thread_type); \ + } + +#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ + { \ + char* data = NULL; \ + int len = 0; \ + symbolOop name = (clss)->name(); \ + if (name != NULL) { \ + data = (char*)name->bytes(); \ + len = name->utf8_length(); \ + } \ + HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ + data, len, (clss)->class_loader(), thread_type, wait); \ + } + +#else // ndef DTRACE_ENABLED + +#define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) +#define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) + +#endif // ndef DTRACE_ENABLED + bool instanceKlass::should_be_initialized() const { return !is_initialized(); } @@ -292,6 +344,10 @@ // A class could already be verified, since it has been reflected upon. this_oop->link_class(CHECK); + DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1); + + bool wait = false; + // refer to the JVM book page 47 for description of steps // Step 1 { ObjectLocker ol(this_oop, THREAD); @@ -303,19 +359,25 @@ // we might end up throwing IE from link/symbol resolution sites // that aren't expected to throw. This would wreak havoc. See 6320309. while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) { + wait = true; ol.waitUninterruptibly(CHECK); } // Step 3 - if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) + if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) { + DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait); return; + } // Step 4 - if (this_oop->is_initialized()) + if (this_oop->is_initialized()) { + DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait); return; + } // Step 5 if (this_oop->is_in_error_state()) { + DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait); ResourceMark rm(THREAD); const char* desc = "Could not initialize class "; const char* className = this_oop->external_name(); @@ -348,6 +410,7 @@ this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below } + DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait); THROW_OOP(e()); } } @@ -356,6 +419,7 @@ { assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); JavaThread* jt = (JavaThread*)THREAD; + DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait); // Timer includes any side effects of class initialization (resolution, // etc), but not recursive entry into call_class_initializer(). PerfClassTraceTime timer(ClassLoader::perf_class_init_time(), @@ -383,6 +447,7 @@ this_oop->set_initialization_state_and_notify(initialization_error, THREAD); CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below } + DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait); if (e->is_a(SystemDictionary::Error_klass())) { THROW_OOP(e()); } else { @@ -392,6 +457,7 @@ &args); } } + DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait); } diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -26,6 +26,10 @@ #include "incls/_jvm.cpp.incl" #include +HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__begin, long long); +HS_DTRACE_PROBE_DECL1(hotspot, thread__sleep__end, int); +HS_DTRACE_PROBE_DECL0(hotspot, thread__yield); + /* NOTE about use of any ctor or function call that can trigger a safepoint/GC: such ctors and calls MUST NOT come between an oop declaration/init and its @@ -2762,6 +2766,7 @@ JVM_ENTRY(void, JVM_Yield(JNIEnv *env, jclass threadClass)) JVMWrapper("JVM_Yield"); if (os::dont_yield()) return; + HS_DTRACE_PROBE0(hotspot, thread__yield); // When ConvertYieldToSleep is off (default), this matches the classic VM use of yield. // Critical for similar threading behaviour if (ConvertYieldToSleep) { @@ -2787,6 +2792,8 @@ // And set new thread state to SLEEPING. JavaThreadSleepState jtss(thread); + HS_DTRACE_PROBE1(hotspot, thread__sleep__begin, millis); + if (millis == 0) { // When ConvertSleepToYield is on, this matches the classic VM implementation of // JVM_Sleep. Critical for similar threading behaviour (Win32) @@ -2807,6 +2814,7 @@ // An asynchronous exception (e.g., ThreadDeathException) could have been thrown on // us while we were sleeping. We do not overwrite those. if (!HAS_PENDING_EXCEPTION) { + HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1); // TODO-FIXME: THROW_MSG returns which means we will not call set_state() // to properly restore the thread state. That's likely wrong. THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted"); @@ -2814,6 +2822,7 @@ } thread->osthread()->set_state(old_state); } + HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0); JVM_END JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass)) diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -29,6 +29,10 @@ #include "incls/_precompiled.incl" #include "incls/_unsafe.cpp.incl" +HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long); +HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t); +HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t); + #define MAX_OBJECT_SIZE \ ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \ + ((julong)max_jint * sizeof(double)) ) @@ -1083,8 +1087,10 @@ UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) UnsafeWrapper("Unsafe_Park"); + HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time); JavaThreadParkedState jtps(thread, time != 0); thread->parker()->park(isAbsolute != 0, time); + HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker()); UNSAFE_END UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) @@ -1116,6 +1122,7 @@ } } if (p != NULL) { + HS_DTRACE_PROBE1(hotspot, thread__unpark, p); p->unpark(); } UNSAFE_END diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/runtime/vmThread.cpp --- a/hotspot/src/share/vm/runtime/vmThread.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/runtime/vmThread.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -25,6 +25,10 @@ # include "incls/_precompiled.incl" # include "incls/_vmThread.cpp.incl" +HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int); +HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int); +HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int); + // Dummy VM operation to act as first element in our circular double-linked list class VM_Dummy: public VM_Operation { VMOp_Type type() const { return VMOp_Dummy; } @@ -132,6 +136,10 @@ //----------------------------------------------------------------- // High-level interface bool VMOperationQueue::add(VM_Operation *op) { + + HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()), + op->evaluation_mode()); + // Encapsulates VM queue policy. Currently, that // only involves putting them on the right list if (op->evaluate_at_safepoint()) { @@ -325,7 +333,11 @@ { PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time()); + HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()), + op->evaluation_mode()); op->evaluate(); + HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()), + op->evaluation_mode()); } // Last access of info in _cur_vm_operation! diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/services/dtraceAttacher.cpp --- a/hotspot/src/share/vm/services/dtraceAttacher.cpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/services/dtraceAttacher.cpp Wed Mar 17 11:01:05 2010 +0100 @@ -135,4 +135,9 @@ } } +void DTrace::set_monitor_dprobes(bool flag) { + // explicit setting of DTraceMonitorProbes flag + set_bool_flag("DTraceMonitorProbes", flag); +} + #endif /* SOLARIS */ diff -r a7a4e66595ec -r 0cce506a0158 hotspot/src/share/vm/services/dtraceAttacher.hpp --- a/hotspot/src/share/vm/services/dtraceAttacher.hpp Tue Mar 16 20:47:17 2010 -0700 +++ b/hotspot/src/share/vm/services/dtraceAttacher.hpp Wed Mar 17 11:01:05 2010 +0100 @@ -41,4 +41,6 @@ static void detach_all_clients(); // set ExtendedDTraceProbes flag static void set_extended_dprobes(bool value); + // set DTraceMonitorProbes flag + static void set_monitor_dprobes(bool value); };