1.1 --- a/src/share/vm/classfile/classLoaderData.cpp Tue Apr 09 15:32:45 2013 +0200 1.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Wed Apr 10 13:27:35 2013 +0200 1.3 @@ -70,15 +70,19 @@ 1.4 _is_anonymous(is_anonymous), _keep_alive(is_anonymous), // initially 1.5 _metaspace(NULL), _unloading(false), _klasses(NULL), 1.6 _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), 1.7 - _next(NULL), _dependencies(NULL), 1.8 + _next(NULL), _dependencies(), 1.9 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { 1.10 // empty 1.11 } 1.12 1.13 void ClassLoaderData::init_dependencies(TRAPS) { 1.14 + _dependencies.init(CHECK); 1.15 +} 1.16 + 1.17 +void ClassLoaderData::Dependencies::init(TRAPS) { 1.18 // Create empty dependencies array to add to. CMS requires this to be 1.19 // an oop so that it can track additions via card marks. We think. 1.20 - _dependencies = (oop)oopFactory::new_objectArray(2, CHECK); 1.21 + _list_head = oopFactory::new_objectArray(2, CHECK); 1.22 } 1.23 1.24 bool ClassLoaderData::claim() { 1.25 @@ -95,13 +99,17 @@ 1.26 } 1.27 1.28 f->do_oop(&_class_loader); 1.29 - f->do_oop(&_dependencies); 1.30 + _dependencies.oops_do(f); 1.31 _handles->oops_do(f); 1.32 if (klass_closure != NULL) { 1.33 classes_do(klass_closure); 1.34 } 1.35 } 1.36 1.37 +void ClassLoaderData::Dependencies::oops_do(OopClosure* f) { 1.38 + f->do_oop((oop*)&_list_head); 1.39 +} 1.40 + 1.41 void ClassLoaderData::classes_do(KlassClosure* klass_closure) { 1.42 for (Klass* k = _klasses; k != NULL; k = k->next_link()) { 1.43 klass_closure->do_klass(k); 1.44 @@ -154,14 +162,14 @@ 1.45 // It's a dependency we won't find through GC, add it. This is relatively rare 1.46 // Must handle over GC point. 1.47 Handle dependency(THREAD, to); 1.48 - from_cld->add_dependency(dependency, CHECK); 1.49 + from_cld->_dependencies.add(dependency, CHECK); 1.50 } 1.51 1.52 1.53 -void ClassLoaderData::add_dependency(Handle dependency, TRAPS) { 1.54 +void ClassLoaderData::Dependencies::add(Handle dependency, TRAPS) { 1.55 // Check first if this dependency is already in the list. 1.56 // Save a pointer to the last to add to under the lock. 1.57 - objArrayOop ok = (objArrayOop)_dependencies; 1.58 + objArrayOop ok = _list_head; 1.59 objArrayOop last = NULL; 1.60 while (ok != NULL) { 1.61 last = ok; 1.62 @@ -184,16 +192,17 @@ 1.63 objArrayHandle new_dependency(THREAD, deps); 1.64 1.65 // Add the dependency under lock 1.66 - locked_add_dependency(last_handle, new_dependency); 1.67 + locked_add(last_handle, new_dependency, THREAD); 1.68 } 1.69 1.70 -void ClassLoaderData::locked_add_dependency(objArrayHandle last_handle, 1.71 - objArrayHandle new_dependency) { 1.72 +void ClassLoaderData::Dependencies::locked_add(objArrayHandle last_handle, 1.73 + objArrayHandle new_dependency, 1.74 + Thread* THREAD) { 1.75 1.76 // Have to lock and put the new dependency on the end of the dependency 1.77 // array so the card mark for CMS sees that this dependency is new. 1.78 // Can probably do this lock free with some effort. 1.79 - MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); 1.80 + ObjectLocker ol(Handle(THREAD, _list_head), THREAD); 1.81 1.82 oop loader_or_mirror = new_dependency->obj_at(0); 1.83