Mercurial > hg > graal-compiler
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) { |