1.1 --- a/src/share/vm/oops/instanceKlass.cpp Mon Oct 21 17:26:46 2013 -0700 1.2 +++ b/src/share/vm/oops/instanceKlass.cpp Tue Oct 22 14:29:02 2013 -0700 1.3 @@ -498,13 +498,27 @@ 1.4 1.5 oop InstanceKlass::init_lock() const { 1.6 // return the init lock from the mirror 1.7 - return java_lang_Class::init_lock(java_mirror()); 1.8 + oop lock = java_lang_Class::init_lock(java_mirror()); 1.9 + assert((oop)lock != NULL || !is_not_initialized(), // initialized or in_error state 1.10 + "only fully initialized state can have a null lock"); 1.11 + return lock; 1.12 +} 1.13 + 1.14 +// Set the initialization lock to null so the object can be GC'ed. Any racing 1.15 +// threads to get this lock will see a null lock and will not lock. 1.16 +// That's okay because they all check for initialized state after getting 1.17 +// the lock and return. 1.18 +void InstanceKlass::fence_and_clear_init_lock() { 1.19 + // make sure previous stores are all done, notably the init_state. 1.20 + OrderAccess::storestore(); 1.21 + java_lang_Class::set_init_lock(java_mirror(), NULL); 1.22 + assert(!is_not_initialized(), "class must be initialized now"); 1.23 } 1.24 1.25 void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) { 1.26 EXCEPTION_MARK; 1.27 oop init_lock = this_oop->init_lock(); 1.28 - ObjectLocker ol(init_lock, THREAD); 1.29 + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); 1.30 1.31 // abort if someone beat us to the initialization 1.32 if (!this_oop->is_not_initialized()) return; // note: not equivalent to is_initialized() 1.33 @@ -523,6 +537,7 @@ 1.34 } else { 1.35 // linking successfull, mark class as initialized 1.36 this_oop->set_init_state (fully_initialized); 1.37 + this_oop->fence_and_clear_init_lock(); 1.38 // trace 1.39 if (TraceClassInitialization) { 1.40 ResourceMark rm(THREAD); 1.41 @@ -649,7 +664,7 @@ 1.42 // verification & rewriting 1.43 { 1.44 oop init_lock = this_oop->init_lock(); 1.45 - ObjectLocker ol(init_lock, THREAD); 1.46 + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); 1.47 // rewritten will have been set if loader constraint error found 1.48 // on an earlier link attempt 1.49 // don't verify or rewrite if already rewritten 1.50 @@ -772,7 +787,7 @@ 1.51 // Step 1 1.52 { 1.53 oop init_lock = this_oop->init_lock(); 1.54 - ObjectLocker ol(init_lock, THREAD); 1.55 + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); 1.56 1.57 Thread *self = THREAD; // it's passed the current thread 1.58 1.59 @@ -920,8 +935,9 @@ 1.60 1.61 void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) { 1.62 oop init_lock = this_oop->init_lock(); 1.63 - ObjectLocker ol(init_lock, THREAD); 1.64 + ObjectLocker ol(init_lock, THREAD, init_lock != NULL); 1.65 this_oop->set_init_state(state); 1.66 + this_oop->fence_and_clear_init_lock(); 1.67 ol.notify_all(CHECK); 1.68 } 1.69