comparison src/share/vm/oops/instanceKlass.cpp @ 1324:e392695de029

6935224: Adding new DTrace probes to work with Palantir Summary: Adding probes related to thread scheduling and class initialization Reviewed-by: kamg, never
author fparain
date Wed, 17 Mar 2010 11:01:05 +0100
parents 4e6abf09f540
children a7b84a5e16c6 f03d0a26bf83
comparison
equal deleted inserted replaced
1323:cd20a6f46fec 1324:e392695de029
23 */ 23 */
24 24
25 # include "incls/_precompiled.incl" 25 # include "incls/_precompiled.incl"
26 # include "incls/_instanceKlass.cpp.incl" 26 # include "incls/_instanceKlass.cpp.incl"
27 27
28 #ifdef DTRACE_ENABLED
29
30 HS_DTRACE_PROBE_DECL4(hotspot, class__initialization__required,
31 char*, intptr_t, oop, intptr_t);
32 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__recursive,
33 char*, intptr_t, oop, intptr_t, int);
34 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__concurrent,
35 char*, intptr_t, oop, intptr_t, int);
36 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__erroneous,
37 char*, intptr_t, oop, intptr_t, int);
38 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__super__failed,
39 char*, intptr_t, oop, intptr_t, int);
40 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__clinit,
41 char*, intptr_t, oop, intptr_t, int);
42 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__error,
43 char*, intptr_t, oop, intptr_t, int);
44 HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end,
45 char*, intptr_t, oop, intptr_t, int);
46
47 #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type) \
48 { \
49 char* data = NULL; \
50 int len = 0; \
51 symbolOop name = (clss)->name(); \
52 if (name != NULL) { \
53 data = (char*)name->bytes(); \
54 len = name->utf8_length(); \
55 } \
56 HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \
57 data, len, (clss)->class_loader(), thread_type); \
58 }
59
60 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \
61 { \
62 char* data = NULL; \
63 int len = 0; \
64 symbolOop name = (clss)->name(); \
65 if (name != NULL) { \
66 data = (char*)name->bytes(); \
67 len = name->utf8_length(); \
68 } \
69 HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \
70 data, len, (clss)->class_loader(), thread_type, wait); \
71 }
72
73 #else // ndef DTRACE_ENABLED
74
75 #define DTRACE_CLASSINIT_PROBE(type, clss, thread_type)
76 #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait)
77
78 #endif // ndef DTRACE_ENABLED
79
28 bool instanceKlass::should_be_initialized() const { 80 bool instanceKlass::should_be_initialized() const {
29 return !is_initialized(); 81 return !is_initialized();
30 } 82 }
31 83
32 klassVtable* instanceKlass::vtable() const { 84 klassVtable* instanceKlass::vtable() const {
290 void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) { 342 void instanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
291 // Make sure klass is linked (verified) before initialization 343 // Make sure klass is linked (verified) before initialization
292 // A class could already be verified, since it has been reflected upon. 344 // A class could already be verified, since it has been reflected upon.
293 this_oop->link_class(CHECK); 345 this_oop->link_class(CHECK);
294 346
347 DTRACE_CLASSINIT_PROBE(required, instanceKlass::cast(this_oop()), -1);
348
349 bool wait = false;
350
295 // refer to the JVM book page 47 for description of steps 351 // refer to the JVM book page 47 for description of steps
296 // Step 1 352 // Step 1
297 { ObjectLocker ol(this_oop, THREAD); 353 { ObjectLocker ol(this_oop, THREAD);
298 354
299 Thread *self = THREAD; // it's passed the current thread 355 Thread *self = THREAD; // it's passed the current thread
301 // Step 2 357 // Step 2
302 // If we were to use wait() instead of waitInterruptibly() then 358 // If we were to use wait() instead of waitInterruptibly() then
303 // we might end up throwing IE from link/symbol resolution sites 359 // we might end up throwing IE from link/symbol resolution sites
304 // that aren't expected to throw. This would wreak havoc. See 6320309. 360 // that aren't expected to throw. This would wreak havoc. See 6320309.
305 while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) { 361 while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
362 wait = true;
306 ol.waitUninterruptibly(CHECK); 363 ol.waitUninterruptibly(CHECK);
307 } 364 }
308 365
309 // Step 3 366 // Step 3
310 if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) 367 if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
368 DTRACE_CLASSINIT_PROBE_WAIT(recursive, instanceKlass::cast(this_oop()), -1,wait);
311 return; 369 return;
370 }
312 371
313 // Step 4 372 // Step 4
314 if (this_oop->is_initialized()) 373 if (this_oop->is_initialized()) {
374 DTRACE_CLASSINIT_PROBE_WAIT(concurrent, instanceKlass::cast(this_oop()), -1,wait);
315 return; 375 return;
376 }
316 377
317 // Step 5 378 // Step 5
318 if (this_oop->is_in_error_state()) { 379 if (this_oop->is_in_error_state()) {
380 DTRACE_CLASSINIT_PROBE_WAIT(erroneous, instanceKlass::cast(this_oop()), -1,wait);
319 ResourceMark rm(THREAD); 381 ResourceMark rm(THREAD);
320 const char* desc = "Could not initialize class "; 382 const char* desc = "Could not initialize class ";
321 const char* className = this_oop->external_name(); 383 const char* className = this_oop->external_name();
322 size_t msglen = strlen(desc) + strlen(className) + 1; 384 size_t msglen = strlen(desc) + strlen(className) + 1;
323 char* message = NEW_C_HEAP_ARRAY(char, msglen); 385 char* message = NEW_C_HEAP_ARRAY(char, msglen);
346 { 408 {
347 EXCEPTION_MARK; 409 EXCEPTION_MARK;
348 this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads 410 this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
349 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below 411 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below
350 } 412 }
413 DTRACE_CLASSINIT_PROBE_WAIT(super__failed, instanceKlass::cast(this_oop()), -1,wait);
351 THROW_OOP(e()); 414 THROW_OOP(e());
352 } 415 }
353 } 416 }
354 417
355 // Step 8 418 // Step 8
356 { 419 {
357 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); 420 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
358 JavaThread* jt = (JavaThread*)THREAD; 421 JavaThread* jt = (JavaThread*)THREAD;
422 DTRACE_CLASSINIT_PROBE_WAIT(clinit, instanceKlass::cast(this_oop()), -1,wait);
359 // Timer includes any side effects of class initialization (resolution, 423 // Timer includes any side effects of class initialization (resolution,
360 // etc), but not recursive entry into call_class_initializer(). 424 // etc), but not recursive entry into call_class_initializer().
361 PerfClassTraceTime timer(ClassLoader::perf_class_init_time(), 425 PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
362 ClassLoader::perf_class_init_selftime(), 426 ClassLoader::perf_class_init_selftime(),
363 ClassLoader::perf_classes_inited(), 427 ClassLoader::perf_classes_inited(),
381 { 445 {
382 EXCEPTION_MARK; 446 EXCEPTION_MARK;
383 this_oop->set_initialization_state_and_notify(initialization_error, THREAD); 447 this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
384 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below 448 CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, class initialization error is thrown below
385 } 449 }
450 DTRACE_CLASSINIT_PROBE_WAIT(error, instanceKlass::cast(this_oop()), -1,wait);
386 if (e->is_a(SystemDictionary::Error_klass())) { 451 if (e->is_a(SystemDictionary::Error_klass())) {
387 THROW_OOP(e()); 452 THROW_OOP(e());
388 } else { 453 } else {
389 JavaCallArguments args(e); 454 JavaCallArguments args(e);
390 THROW_ARG(vmSymbolHandles::java_lang_ExceptionInInitializerError(), 455 THROW_ARG(vmSymbolHandles::java_lang_ExceptionInInitializerError(),
391 vmSymbolHandles::throwable_void_signature(), 456 vmSymbolHandles::throwable_void_signature(),
392 &args); 457 &args);
393 } 458 }
394 } 459 }
460 DTRACE_CLASSINIT_PROBE_WAIT(end, instanceKlass::cast(this_oop()), -1,wait);
395 } 461 }
396 462
397 463
398 // Note: implementation moved to static method to expose the this pointer. 464 // Note: implementation moved to static method to expose the this pointer.
399 void instanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) { 465 void instanceKlass::set_initialization_state_and_notify(ClassState state, TRAPS) {