1.1 --- a/src/share/vm/classfile/classLoaderData.cpp Tue Nov 27 14:11:37 2012 -0800 1.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Thu Nov 29 16:50:29 2012 -0500 1.3 @@ -65,13 +65,19 @@ 1.4 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; 1.5 1.6 ClassLoaderData::ClassLoaderData(Handle h_class_loader) : _class_loader(h_class_loader()), 1.7 - _metaspace(NULL), _unloading(false), _klasses(NULL), 1.8 - _claimed(0), _jmethod_ids(NULL), _handles(NULL), 1.9 - _deallocate_list(NULL), _next(NULL), 1.10 + _metaspace(NULL), _unloading(false), _keep_alive(false), _klasses(NULL), 1.11 + _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), 1.12 + _next(NULL), _dependencies(NULL), 1.13 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { 1.14 // empty 1.15 } 1.16 1.17 +void ClassLoaderData::init_dependencies(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 +} 1.22 + 1.23 bool ClassLoaderData::claim() { 1.24 if (_claimed == 1) { 1.25 return false; 1.26 @@ -86,6 +92,7 @@ 1.27 } 1.28 1.29 f->do_oop(&_class_loader); 1.30 + f->do_oop(&_dependencies); 1.31 _handles->oops_do(f); 1.32 if (klass_closure != NULL) { 1.33 classes_do(klass_closure); 1.34 @@ -110,70 +117,100 @@ 1.35 ClassLoaderData * const from_cld = this; 1.36 ClassLoaderData * const to_cld = k->class_loader_data(); 1.37 1.38 - // Records dependency between non-null class loaders only. 1.39 - if (to_cld->is_the_null_class_loader_data() || from_cld->is_the_null_class_loader_data()) { 1.40 + // Dependency to the null class loader data doesn't need to be recorded 1.41 + // because the null class loader data never goes away. 1.42 + if (to_cld->is_the_null_class_loader_data()) { 1.43 return; 1.44 } 1.45 1.46 - // Check that this dependency isn't from the same or parent class_loader 1.47 - oop to = to_cld->class_loader(); 1.48 - oop from = from_cld->class_loader(); 1.49 + oop to; 1.50 + if (to_cld->is_anonymous()) { 1.51 + // Anonymous class dependencies are through the mirror. 1.52 + to = k->java_mirror(); 1.53 + } else { 1.54 + to = to_cld->class_loader(); 1.55 1.56 - oop curr = from; 1.57 - while (curr != NULL) { 1.58 - if (curr == to) { 1.59 - return; // this class loader is in the parent list, no need to add it. 1.60 + // If from_cld is anonymous, even if it's class_loader is a parent of 'to' 1.61 + // we still have to add it. The class_loader won't keep from_cld alive. 1.62 + if (!from_cld->is_anonymous()) { 1.63 + // Check that this dependency isn't from the same or parent class_loader 1.64 + oop from = from_cld->class_loader(); 1.65 + 1.66 + oop curr = from; 1.67 + while (curr != NULL) { 1.68 + if (curr == to) { 1.69 + return; // this class loader is in the parent list, no need to add it. 1.70 + } 1.71 + curr = java_lang_ClassLoader::parent(curr); 1.72 + } 1.73 } 1.74 - curr = java_lang_ClassLoader::parent(curr); 1.75 } 1.76 1.77 // It's a dependency we won't find through GC, add it. This is relatively rare 1.78 - from_cld->add_dependency(to_cld, CHECK); 1.79 + // Must handle over GC point. 1.80 + Handle dependency(THREAD, to); 1.81 + from_cld->add_dependency(dependency, CHECK); 1.82 } 1.83 1.84 -bool ClassLoaderData::has_dependency(ClassLoaderData* dependency) { 1.85 - oop loader = dependency->class_loader(); 1.86 1.87 - // Get objArrayOop out of the class_loader oop and see if this dependency 1.88 - // is there. Don't safepoint! These are all oops. 1.89 - // Dependency list is (oop class_loader, objArrayOop next) 1.90 - objArrayOop ok = (objArrayOop)java_lang_ClassLoader::dependencies(class_loader()); 1.91 +void ClassLoaderData::add_dependency(Handle dependency, TRAPS) { 1.92 + // Check first if this dependency is already in the list. 1.93 + // Save a pointer to the last to add to under the lock. 1.94 + objArrayOop ok = (objArrayOop)_dependencies; 1.95 + objArrayOop last = NULL; 1.96 while (ok != NULL) { 1.97 - if (ok->obj_at(0) == loader) { 1.98 - return true; 1.99 + last = ok; 1.100 + if (ok->obj_at(0) == dependency()) { 1.101 + // Don't need to add it 1.102 + return; 1.103 } 1.104 ok = (objArrayOop)ok->obj_at(1); 1.105 } 1.106 - return false; 1.107 + 1.108 + // Create a new dependency node with fields for (class_loader or mirror, next) 1.109 + objArrayOop deps = oopFactory::new_objectArray(2, CHECK); 1.110 + deps->obj_at_put(0, dependency()); 1.111 + 1.112 + // Must handle over more GC points 1.113 + objArrayHandle new_dependency(THREAD, deps); 1.114 + 1.115 + // Add the dependency under lock 1.116 + assert (last != NULL, "dependencies should be initialized"); 1.117 + objArrayHandle last_handle(THREAD, last); 1.118 + locked_add_dependency(last_handle, new_dependency); 1.119 } 1.120 1.121 -void ClassLoaderData::add_dependency(ClassLoaderData* dependency, TRAPS) { 1.122 - // Minimize the number of duplicates in the list. 1.123 - if (has_dependency(dependency)) { 1.124 - return; 1.125 +void ClassLoaderData::locked_add_dependency(objArrayHandle last_handle, 1.126 + objArrayHandle new_dependency) { 1.127 + 1.128 + // Have to lock and put the new dependency on the end of the dependency 1.129 + // array so the card mark for CMS sees that this dependency is new. 1.130 + // Can probably do this lock free with some effort. 1.131 + MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); 1.132 + 1.133 + oop loader_or_mirror = new_dependency->obj_at(0); 1.134 + 1.135 + // Since the dependencies are only added, add to the end. 1.136 + objArrayOop end = last_handle(); 1.137 + objArrayOop last = NULL; 1.138 + while (end != NULL) { 1.139 + last = end; 1.140 + // check again if another thread added it to the end. 1.141 + if (end->obj_at(0) == loader_or_mirror) { 1.142 + // Don't need to add it 1.143 + return; 1.144 + } 1.145 + end = (objArrayOop)end->obj_at(1); 1.146 } 1.147 - 1.148 - // Create a new dependency node with fields for (class_loader, next) 1.149 - objArrayOop deps = oopFactory::new_objectArray(2, CHECK); 1.150 - deps->obj_at_put(0, dependency->class_loader()); 1.151 - 1.152 - // Add this lock free, using compare and exchange, need barriers for GC 1.153 - // Do the barrier first. 1.154 - HeapWord* addr = java_lang_ClassLoader::dependencies_addr(class_loader()); 1.155 - while (true) { 1.156 - oop old_dependency = java_lang_ClassLoader::dependencies(class_loader()); 1.157 - deps->obj_at_put(1, old_dependency); 1.158 - 1.159 - oop newold = oopDesc::atomic_compare_exchange_oop((oop)deps, addr, old_dependency, true); 1.160 - if (newold == old_dependency) { 1.161 - update_barrier_set((void*)addr, (oop)deps); 1.162 - // we won the race to add this dependency 1.163 - break; 1.164 - } 1.165 + assert (last != NULL, "dependencies should be initialized"); 1.166 + // fill in the first element with the oop in new_dependency. 1.167 + if (last->obj_at(0) == NULL) { 1.168 + last->obj_at_put(0, new_dependency->obj_at(0)); 1.169 + } else { 1.170 + last->obj_at_put(1, new_dependency()); 1.171 } 1.172 } 1.173 1.174 - 1.175 void ClassLoaderDataGraph::clear_claimed_marks() { 1.176 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { 1.177 cld->clear_claimed(); 1.178 @@ -187,7 +224,7 @@ 1.179 // link the new item into the list 1.180 _klasses = k; 1.181 1.182 - if (TraceClassLoaderData && k->class_loader_data() != NULL) { 1.183 + if (TraceClassLoaderData && Verbose && k->class_loader_data() != NULL) { 1.184 ResourceMark rm; 1.185 tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: " 1.186 PTR_FORMAT " loader: " PTR_FORMAT " %s", 1.187 @@ -195,8 +232,7 @@ 1.188 k->external_name(), 1.189 k->class_loader_data(), 1.190 k->class_loader(), 1.191 - k->class_loader() != NULL ? k->class_loader()->klass()->external_name() : "NULL" 1.192 - ); 1.193 + loader_name()); 1.194 } 1.195 } 1.196 1.197 @@ -221,6 +257,38 @@ 1.198 ShouldNotReachHere(); // should have found this class!! 1.199 } 1.200 1.201 + 1.202 +bool ClassLoaderData::is_anonymous() const { 1.203 + Klass* k = _klasses; 1.204 + return (_keep_alive || (k != NULL && k->oop_is_instance() && 1.205 + InstanceKlass::cast(k)->is_anonymous())); 1.206 +} 1.207 + 1.208 +void ClassLoaderData::unload() { 1.209 + _unloading = true; 1.210 + 1.211 + if (TraceClassLoaderData) { 1.212 + ResourceMark rm; 1.213 + tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this); 1.214 + tty->print(" for instance "PTR_FORMAT" of %s", class_loader(), 1.215 + loader_name()); 1.216 + if (is_anonymous()) { 1.217 + tty->print(" for anonymous class "PTR_FORMAT " ", _klasses); 1.218 + } 1.219 + tty->print_cr("]"); 1.220 + } 1.221 +} 1.222 + 1.223 +bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const { 1.224 + bool alive = 1.225 + is_anonymous() ? 1.226 + is_alive_closure->do_object_b(_klasses->java_mirror()) : 1.227 + class_loader() == NULL || is_alive_closure->do_object_b(class_loader()); 1.228 + assert(!alive || claimed(), "must be claimed"); 1.229 + return alive; 1.230 +} 1.231 + 1.232 + 1.233 ClassLoaderData::~ClassLoaderData() { 1.234 Metaspace *m = _metaspace; 1.235 if (m != NULL) { 1.236 @@ -263,8 +331,8 @@ 1.237 if (_metaspace != NULL) { 1.238 return _metaspace; 1.239 } 1.240 - if (class_loader() == NULL) { 1.241 - assert(this == the_null_class_loader_data(), "Must be"); 1.242 + if (this == the_null_class_loader_data()) { 1.243 + assert (class_loader() == NULL, "Must be"); 1.244 size_t word_size = Metaspace::first_chunk_word_size(); 1.245 set_metaspace(new Metaspace(_metaspace_lock, word_size)); 1.246 } else { 1.247 @@ -325,12 +393,19 @@ 1.248 } 1.249 } 1.250 1.251 -#ifndef PRODUCT 1.252 -void ClassLoaderData::print_loader(ClassLoaderData *loader_data, outputStream* out) { 1.253 - oop class_loader = loader_data->class_loader(); 1.254 - out->print("%s", SystemDictionary::loader_name(class_loader)); 1.255 +// These anonymous class loaders are to contain classes used for JSR292 1.256 +ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) { 1.257 + // Add a new class loader data to the graph. 1.258 + ClassLoaderData* cld = ClassLoaderDataGraph::add(NULL, loader, CHECK_NULL); 1.259 + return cld; 1.260 } 1.261 1.262 +const char* ClassLoaderData::loader_name() { 1.263 + // Handles null class loader 1.264 + return SystemDictionary::loader_name(class_loader()); 1.265 +} 1.266 + 1.267 +#ifndef PRODUCT 1.268 // Define to dump klasses 1.269 #undef CLD_DUMP_KLASSES 1.270 1.271 @@ -338,8 +413,7 @@ 1.272 ResourceMark rm; 1.273 out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", 1.274 this, class_loader(), 1.275 - class_loader() != NULL ? class_loader()->klass() : NULL, 1.276 - class_loader() != NULL ? class_loader()->klass()->external_name() : "NULL"); 1.277 + class_loader() != NULL ? class_loader()->klass() : NULL, loader_name()); 1.278 if (claimed()) out->print(" claimed "); 1.279 if (is_unloading()) out->print(" unloading "); 1.280 out->print(" handles " INTPTR_FORMAT, handles()); 1.281 @@ -373,8 +447,8 @@ 1.282 void ClassLoaderData::verify() { 1.283 oop cl = class_loader(); 1.284 1.285 - guarantee(this == class_loader_data(cl), "Must be the same"); 1.286 - guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data(), "must be"); 1.287 + guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same"); 1.288 + guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_anonymous(), "must be"); 1.289 1.290 // Verify the integrity of the allocated space. 1.291 if (metaspace_or_null() != NULL) { 1.292 @@ -387,6 +461,7 @@ 1.293 } 1.294 } 1.295 1.296 + 1.297 // GC root of class loader data created. 1.298 ClassLoaderData* ClassLoaderDataGraph::_head = NULL; 1.299 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; 1.300 @@ -395,19 +470,25 @@ 1.301 1.302 // Add a new class loader data node to the list. Assign the newly created 1.303 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field 1.304 -ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader_data) { 1.305 +ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader, TRAPS) { 1.306 // Not assigned a class loader data yet. 1.307 // Create one. 1.308 ClassLoaderData* *list_head = &_head; 1.309 ClassLoaderData* next = _head; 1.310 - ClassLoaderData* cld = new ClassLoaderData(loader_data); 1.311 + ClassLoaderData* cld = new ClassLoaderData(loader); 1.312 1.313 - // First, Atomically set it. 1.314 - ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); 1.315 - if (old != NULL) { 1.316 - delete cld; 1.317 - // Returns the data. 1.318 - return old; 1.319 + if (cld_addr != NULL) { 1.320 + // First, Atomically set it 1.321 + ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); 1.322 + if (old != NULL) { 1.323 + delete cld; 1.324 + // Returns the data. 1.325 + return old; 1.326 + } 1.327 + } else { 1.328 + // Disallow unloading for this CLD during initialization if there is no 1.329 + // class_loader oop to link this to. 1.330 + cld->set_keep_alive(true); 1.331 } 1.332 1.333 // We won the race, and therefore the task of adding the data to the list of 1.334 @@ -417,16 +498,22 @@ 1.335 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); 1.336 if (exchanged == next) { 1.337 if (TraceClassLoaderData) { 1.338 + ResourceMark rm; 1.339 tty->print("[ClassLoaderData: "); 1.340 tty->print("create class loader data "PTR_FORMAT, cld); 1.341 - tty->print(" for instance "PTR_FORMAT" of ", cld->class_loader()); 1.342 - loader_data->klass()->name()->print_symbol_on(tty); 1.343 + tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(), 1.344 + cld->loader_name()); 1.345 tty->print_cr("]"); 1.346 } 1.347 + // Create dependencies after the CLD is added to the list. Otherwise, 1.348 + // the GC GC will not find the CLD and the _class_loader field will 1.349 + // not be updated. 1.350 + cld->init_dependencies(CHECK_NULL); 1.351 return cld; 1.352 } 1.353 next = exchanged; 1.354 } while (true); 1.355 + 1.356 } 1.357 1.358 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { 1.359 @@ -435,9 +522,19 @@ 1.360 } 1.361 } 1.362 1.363 +void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { 1.364 + for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { 1.365 + if (cld->keep_alive()) { 1.366 + cld->oops_do(f, klass_closure, must_claim); 1.367 + } 1.368 + } 1.369 +} 1.370 + 1.371 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { 1.372 if (ClassUnloading) { 1.373 ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim); 1.374 + // keep any special CLDs alive. 1.375 + ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim); 1.376 } else { 1.377 ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim); 1.378 } 1.379 @@ -516,9 +613,10 @@ 1.380 } 1.381 #endif // PRODUCT 1.382 1.383 + 1.384 // Move class loader data from main list to the unloaded list for unloading 1.385 // and deallocation later. 1.386 -bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive) { 1.387 +bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { 1.388 ClassLoaderData* data = _head; 1.389 ClassLoaderData* prev = NULL; 1.390 bool seen_dead_loader = false; 1.391 @@ -527,8 +625,7 @@ 1.392 bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); 1.393 MetadataOnStackMark md_on_stack; 1.394 while (data != NULL) { 1.395 - if (data->class_loader() == NULL || is_alive->do_object_b(data->class_loader())) { 1.396 - assert(data->claimed(), "class loader data must have been claimed"); 1.397 + if (data->keep_alive() || data->is_alive(is_alive_closure)) { 1.398 if (has_redefined_a_class) { 1.399 data->classes_do(InstanceKlass::purge_previous_versions); 1.400 } 1.401 @@ -539,13 +636,7 @@ 1.402 } 1.403 seen_dead_loader = true; 1.404 ClassLoaderData* dead = data; 1.405 - dead->mark_for_unload(); 1.406 - if (TraceClassLoaderData) { 1.407 - tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, dead); 1.408 - tty->print(" for instance "PTR_FORMAT" of ", dead->class_loader()); 1.409 - dead->class_loader()->klass()->name()->print_symbol_on(tty); 1.410 - tty->print_cr("]"); 1.411 - } 1.412 + dead->unload(); 1.413 data = data->next(); 1.414 // Remove from loader list. 1.415 if (prev != NULL) {