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) { |