src/share/vm/oops/instanceKlass.cpp

changeset 5971
b8860472c377
parent 5896
d37a0525c0fe
child 6024
e64f1fe9756b
     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  

mercurial