63 #include "utilities/ostream.hpp" |
63 #include "utilities/ostream.hpp" |
64 |
64 |
65 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
65 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
66 |
66 |
67 ClassLoaderData::ClassLoaderData(Handle h_class_loader) : _class_loader(h_class_loader()), |
67 ClassLoaderData::ClassLoaderData(Handle h_class_loader) : _class_loader(h_class_loader()), |
68 _metaspace(NULL), _unloading(false), _klasses(NULL), |
68 _metaspace(NULL), _unloading(false), _keep_alive(false), _klasses(NULL), |
69 _claimed(0), _jmethod_ids(NULL), _handles(NULL), |
69 _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), |
70 _deallocate_list(NULL), _next(NULL), |
70 _next(NULL), _dependencies(NULL), |
71 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { |
71 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { |
72 // empty |
72 // empty |
|
73 } |
|
74 |
|
75 void ClassLoaderData::init_dependencies(TRAPS) { |
|
76 // Create empty dependencies array to add to. CMS requires this to be |
|
77 // an oop so that it can track additions via card marks. We think. |
|
78 _dependencies = (oop)oopFactory::new_objectArray(2, CHECK); |
73 } |
79 } |
74 |
80 |
75 bool ClassLoaderData::claim() { |
81 bool ClassLoaderData::claim() { |
76 if (_claimed == 1) { |
82 if (_claimed == 1) { |
77 return false; |
83 return false; |
108 |
115 |
109 void ClassLoaderData::record_dependency(Klass* k, TRAPS) { |
116 void ClassLoaderData::record_dependency(Klass* k, TRAPS) { |
110 ClassLoaderData * const from_cld = this; |
117 ClassLoaderData * const from_cld = this; |
111 ClassLoaderData * const to_cld = k->class_loader_data(); |
118 ClassLoaderData * const to_cld = k->class_loader_data(); |
112 |
119 |
113 // Records dependency between non-null class loaders only. |
120 // Dependency to the null class loader data doesn't need to be recorded |
114 if (to_cld->is_the_null_class_loader_data() || from_cld->is_the_null_class_loader_data()) { |
121 // because the null class loader data never goes away. |
|
122 if (to_cld->is_the_null_class_loader_data()) { |
115 return; |
123 return; |
116 } |
124 } |
117 |
125 |
118 // Check that this dependency isn't from the same or parent class_loader |
126 oop to; |
119 oop to = to_cld->class_loader(); |
127 if (to_cld->is_anonymous()) { |
120 oop from = from_cld->class_loader(); |
128 // Anonymous class dependencies are through the mirror. |
121 |
129 to = k->java_mirror(); |
122 oop curr = from; |
130 } else { |
123 while (curr != NULL) { |
131 to = to_cld->class_loader(); |
124 if (curr == to) { |
132 |
125 return; // this class loader is in the parent list, no need to add it. |
133 // If from_cld is anonymous, even if it's class_loader is a parent of 'to' |
126 } |
134 // we still have to add it. The class_loader won't keep from_cld alive. |
127 curr = java_lang_ClassLoader::parent(curr); |
135 if (!from_cld->is_anonymous()) { |
|
136 // Check that this dependency isn't from the same or parent class_loader |
|
137 oop from = from_cld->class_loader(); |
|
138 |
|
139 oop curr = from; |
|
140 while (curr != NULL) { |
|
141 if (curr == to) { |
|
142 return; // this class loader is in the parent list, no need to add it. |
|
143 } |
|
144 curr = java_lang_ClassLoader::parent(curr); |
|
145 } |
|
146 } |
128 } |
147 } |
129 |
148 |
130 // It's a dependency we won't find through GC, add it. This is relatively rare |
149 // It's a dependency we won't find through GC, add it. This is relatively rare |
131 from_cld->add_dependency(to_cld, CHECK); |
150 // Must handle over GC point. |
132 } |
151 Handle dependency(THREAD, to); |
133 |
152 from_cld->add_dependency(dependency, CHECK); |
134 bool ClassLoaderData::has_dependency(ClassLoaderData* dependency) { |
153 } |
135 oop loader = dependency->class_loader(); |
154 |
136 |
155 |
137 // Get objArrayOop out of the class_loader oop and see if this dependency |
156 void ClassLoaderData::add_dependency(Handle dependency, TRAPS) { |
138 // is there. Don't safepoint! These are all oops. |
157 // Check first if this dependency is already in the list. |
139 // Dependency list is (oop class_loader, objArrayOop next) |
158 // Save a pointer to the last to add to under the lock. |
140 objArrayOop ok = (objArrayOop)java_lang_ClassLoader::dependencies(class_loader()); |
159 objArrayOop ok = (objArrayOop)_dependencies; |
|
160 objArrayOop last = NULL; |
141 while (ok != NULL) { |
161 while (ok != NULL) { |
142 if (ok->obj_at(0) == loader) { |
162 last = ok; |
143 return true; |
163 if (ok->obj_at(0) == dependency()) { |
|
164 // Don't need to add it |
|
165 return; |
144 } |
166 } |
145 ok = (objArrayOop)ok->obj_at(1); |
167 ok = (objArrayOop)ok->obj_at(1); |
146 } |
168 } |
147 return false; |
169 |
148 } |
170 // Create a new dependency node with fields for (class_loader or mirror, next) |
149 |
|
150 void ClassLoaderData::add_dependency(ClassLoaderData* dependency, TRAPS) { |
|
151 // Minimize the number of duplicates in the list. |
|
152 if (has_dependency(dependency)) { |
|
153 return; |
|
154 } |
|
155 |
|
156 // Create a new dependency node with fields for (class_loader, next) |
|
157 objArrayOop deps = oopFactory::new_objectArray(2, CHECK); |
171 objArrayOop deps = oopFactory::new_objectArray(2, CHECK); |
158 deps->obj_at_put(0, dependency->class_loader()); |
172 deps->obj_at_put(0, dependency()); |
159 |
173 |
160 // Add this lock free, using compare and exchange, need barriers for GC |
174 // Must handle over more GC points |
161 // Do the barrier first. |
175 objArrayHandle new_dependency(THREAD, deps); |
162 HeapWord* addr = java_lang_ClassLoader::dependencies_addr(class_loader()); |
176 |
163 while (true) { |
177 // Add the dependency under lock |
164 oop old_dependency = java_lang_ClassLoader::dependencies(class_loader()); |
178 assert (last != NULL, "dependencies should be initialized"); |
165 deps->obj_at_put(1, old_dependency); |
179 objArrayHandle last_handle(THREAD, last); |
166 |
180 locked_add_dependency(last_handle, new_dependency); |
167 oop newold = oopDesc::atomic_compare_exchange_oop((oop)deps, addr, old_dependency, true); |
181 } |
168 if (newold == old_dependency) { |
182 |
169 update_barrier_set((void*)addr, (oop)deps); |
183 void ClassLoaderData::locked_add_dependency(objArrayHandle last_handle, |
170 // we won the race to add this dependency |
184 objArrayHandle new_dependency) { |
171 break; |
185 |
172 } |
186 // Have to lock and put the new dependency on the end of the dependency |
173 } |
187 // array so the card mark for CMS sees that this dependency is new. |
174 } |
188 // Can probably do this lock free with some effort. |
175 |
189 MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); |
|
190 |
|
191 oop loader_or_mirror = new_dependency->obj_at(0); |
|
192 |
|
193 // Since the dependencies are only added, add to the end. |
|
194 objArrayOop end = last_handle(); |
|
195 objArrayOop last = NULL; |
|
196 while (end != NULL) { |
|
197 last = end; |
|
198 // check again if another thread added it to the end. |
|
199 if (end->obj_at(0) == loader_or_mirror) { |
|
200 // Don't need to add it |
|
201 return; |
|
202 } |
|
203 end = (objArrayOop)end->obj_at(1); |
|
204 } |
|
205 assert (last != NULL, "dependencies should be initialized"); |
|
206 // fill in the first element with the oop in new_dependency. |
|
207 if (last->obj_at(0) == NULL) { |
|
208 last->obj_at_put(0, new_dependency->obj_at(0)); |
|
209 } else { |
|
210 last->obj_at_put(1, new_dependency()); |
|
211 } |
|
212 } |
176 |
213 |
177 void ClassLoaderDataGraph::clear_claimed_marks() { |
214 void ClassLoaderDataGraph::clear_claimed_marks() { |
178 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
215 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
179 cld->clear_claimed(); |
216 cld->clear_claimed(); |
180 } |
217 } |
323 } |
391 } |
324 } |
392 } |
325 } |
393 } |
326 } |
394 } |
327 |
395 |
|
396 // These anonymous class loaders are to contain classes used for JSR292 |
|
397 ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) { |
|
398 // Add a new class loader data to the graph. |
|
399 ClassLoaderData* cld = ClassLoaderDataGraph::add(NULL, loader, CHECK_NULL); |
|
400 return cld; |
|
401 } |
|
402 |
|
403 const char* ClassLoaderData::loader_name() { |
|
404 // Handles null class loader |
|
405 return SystemDictionary::loader_name(class_loader()); |
|
406 } |
|
407 |
328 #ifndef PRODUCT |
408 #ifndef PRODUCT |
329 void ClassLoaderData::print_loader(ClassLoaderData *loader_data, outputStream* out) { |
|
330 oop class_loader = loader_data->class_loader(); |
|
331 out->print("%s", SystemDictionary::loader_name(class_loader)); |
|
332 } |
|
333 |
|
334 // Define to dump klasses |
409 // Define to dump klasses |
335 #undef CLD_DUMP_KLASSES |
410 #undef CLD_DUMP_KLASSES |
336 |
411 |
337 void ClassLoaderData::dump(outputStream * const out) { |
412 void ClassLoaderData::dump(outputStream * const out) { |
338 ResourceMark rm; |
413 ResourceMark rm; |
339 out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", |
414 out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", |
340 this, class_loader(), |
415 this, class_loader(), |
341 class_loader() != NULL ? class_loader()->klass() : NULL, |
416 class_loader() != NULL ? class_loader()->klass() : NULL, loader_name()); |
342 class_loader() != NULL ? class_loader()->klass()->external_name() : "NULL"); |
|
343 if (claimed()) out->print(" claimed "); |
417 if (claimed()) out->print(" claimed "); |
344 if (is_unloading()) out->print(" unloading "); |
418 if (is_unloading()) out->print(" unloading "); |
345 out->print(" handles " INTPTR_FORMAT, handles()); |
419 out->print(" handles " INTPTR_FORMAT, handles()); |
346 out->cr(); |
420 out->cr(); |
347 if (metaspace_or_null() != NULL) { |
421 if (metaspace_or_null() != NULL) { |
384 for (Klass* k = _klasses; k != NULL; k = k->next_link()) { |
458 for (Klass* k = _klasses; k != NULL; k = k->next_link()) { |
385 guarantee(k->class_loader_data() == this, "Must be the same"); |
459 guarantee(k->class_loader_data() == this, "Must be the same"); |
386 k->verify(); |
460 k->verify(); |
387 } |
461 } |
388 } |
462 } |
|
463 |
389 |
464 |
390 // GC root of class loader data created. |
465 // GC root of class loader data created. |
391 ClassLoaderData* ClassLoaderDataGraph::_head = NULL; |
466 ClassLoaderData* ClassLoaderDataGraph::_head = NULL; |
392 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; |
467 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; |
393 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; |
468 ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; |
394 |
469 |
395 |
470 |
396 // Add a new class loader data node to the list. Assign the newly created |
471 // Add a new class loader data node to the list. Assign the newly created |
397 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field |
472 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field |
398 ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader_data) { |
473 ClassLoaderData* ClassLoaderDataGraph::add(ClassLoaderData** cld_addr, Handle loader, TRAPS) { |
399 // Not assigned a class loader data yet. |
474 // Not assigned a class loader data yet. |
400 // Create one. |
475 // Create one. |
401 ClassLoaderData* *list_head = &_head; |
476 ClassLoaderData* *list_head = &_head; |
402 ClassLoaderData* next = _head; |
477 ClassLoaderData* next = _head; |
403 ClassLoaderData* cld = new ClassLoaderData(loader_data); |
478 ClassLoaderData* cld = new ClassLoaderData(loader); |
404 |
479 |
405 // First, Atomically set it. |
480 if (cld_addr != NULL) { |
406 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); |
481 // First, Atomically set it |
407 if (old != NULL) { |
482 ClassLoaderData* old = (ClassLoaderData*) Atomic::cmpxchg_ptr(cld, cld_addr, NULL); |
408 delete cld; |
483 if (old != NULL) { |
409 // Returns the data. |
484 delete cld; |
410 return old; |
485 // Returns the data. |
|
486 return old; |
|
487 } |
|
488 } else { |
|
489 // Disallow unloading for this CLD during initialization if there is no |
|
490 // class_loader oop to link this to. |
|
491 cld->set_keep_alive(true); |
411 } |
492 } |
412 |
493 |
413 // We won the race, and therefore the task of adding the data to the list of |
494 // We won the race, and therefore the task of adding the data to the list of |
414 // class loader data |
495 // class loader data |
415 do { |
496 do { |
416 cld->set_next(next); |
497 cld->set_next(next); |
417 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); |
498 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); |
418 if (exchanged == next) { |
499 if (exchanged == next) { |
419 if (TraceClassLoaderData) { |
500 if (TraceClassLoaderData) { |
|
501 ResourceMark rm; |
420 tty->print("[ClassLoaderData: "); |
502 tty->print("[ClassLoaderData: "); |
421 tty->print("create class loader data "PTR_FORMAT, cld); |
503 tty->print("create class loader data "PTR_FORMAT, cld); |
422 tty->print(" for instance "PTR_FORMAT" of ", cld->class_loader()); |
504 tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(), |
423 loader_data->klass()->name()->print_symbol_on(tty); |
505 cld->loader_name()); |
424 tty->print_cr("]"); |
506 tty->print_cr("]"); |
425 } |
507 } |
|
508 // Create dependencies after the CLD is added to the list. Otherwise, |
|
509 // the GC GC will not find the CLD and the _class_loader field will |
|
510 // not be updated. |
|
511 cld->init_dependencies(CHECK_NULL); |
426 return cld; |
512 return cld; |
427 } |
513 } |
428 next = exchanged; |
514 next = exchanged; |
429 } while (true); |
515 } while (true); |
|
516 |
430 } |
517 } |
431 |
518 |
432 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
519 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
433 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
520 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
434 cld->oops_do(f, klass_closure, must_claim); |
521 cld->oops_do(f, klass_closure, must_claim); |
435 } |
522 } |
436 } |
523 } |
437 |
524 |
|
525 void ClassLoaderDataGraph::keep_alive_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
|
526 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
|
527 if (cld->keep_alive()) { |
|
528 cld->oops_do(f, klass_closure, must_claim); |
|
529 } |
|
530 } |
|
531 } |
|
532 |
438 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
533 void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
439 if (ClassUnloading) { |
534 if (ClassUnloading) { |
440 ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim); |
535 ClassLoaderData::the_null_class_loader_data()->oops_do(f, klass_closure, must_claim); |
|
536 // keep any special CLDs alive. |
|
537 ClassLoaderDataGraph::keep_alive_oops_do(f, klass_closure, must_claim); |
441 } else { |
538 } else { |
442 ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim); |
539 ClassLoaderDataGraph::oops_do(f, klass_closure, must_claim); |
443 } |
540 } |
444 } |
541 } |
445 |
542 |
514 |
611 |
515 return false; |
612 return false; |
516 } |
613 } |
517 #endif // PRODUCT |
614 #endif // PRODUCT |
518 |
615 |
|
616 |
519 // Move class loader data from main list to the unloaded list for unloading |
617 // Move class loader data from main list to the unloaded list for unloading |
520 // and deallocation later. |
618 // and deallocation later. |
521 bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive) { |
619 bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) { |
522 ClassLoaderData* data = _head; |
620 ClassLoaderData* data = _head; |
523 ClassLoaderData* prev = NULL; |
621 ClassLoaderData* prev = NULL; |
524 bool seen_dead_loader = false; |
622 bool seen_dead_loader = false; |
525 // mark metadata seen on the stack and code cache so we can delete |
623 // mark metadata seen on the stack and code cache so we can delete |
526 // unneeded entries. |
624 // unneeded entries. |
527 bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); |
625 bool has_redefined_a_class = JvmtiExport::has_redefined_a_class(); |
528 MetadataOnStackMark md_on_stack; |
626 MetadataOnStackMark md_on_stack; |
529 while (data != NULL) { |
627 while (data != NULL) { |
530 if (data->class_loader() == NULL || is_alive->do_object_b(data->class_loader())) { |
628 if (data->keep_alive() || data->is_alive(is_alive_closure)) { |
531 assert(data->claimed(), "class loader data must have been claimed"); |
|
532 if (has_redefined_a_class) { |
629 if (has_redefined_a_class) { |
533 data->classes_do(InstanceKlass::purge_previous_versions); |
630 data->classes_do(InstanceKlass::purge_previous_versions); |
534 } |
631 } |
535 data->free_deallocate_list(); |
632 data->free_deallocate_list(); |
536 prev = data; |
633 prev = data; |
537 data = data->next(); |
634 data = data->next(); |
538 continue; |
635 continue; |
539 } |
636 } |
540 seen_dead_loader = true; |
637 seen_dead_loader = true; |
541 ClassLoaderData* dead = data; |
638 ClassLoaderData* dead = data; |
542 dead->mark_for_unload(); |
639 dead->unload(); |
543 if (TraceClassLoaderData) { |
|
544 tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, dead); |
|
545 tty->print(" for instance "PTR_FORMAT" of ", dead->class_loader()); |
|
546 dead->class_loader()->klass()->name()->print_symbol_on(tty); |
|
547 tty->print_cr("]"); |
|
548 } |
|
549 data = data->next(); |
640 data = data->next(); |
550 // Remove from loader list. |
641 // Remove from loader list. |
551 if (prev != NULL) { |
642 if (prev != NULL) { |
552 prev->set_next(data); |
643 prev->set_next(data); |
553 } else { |
644 } else { |