1 /* |
1 /* |
2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
52 #include "classfile/javaClasses.hpp" |
52 #include "classfile/javaClasses.hpp" |
53 #include "classfile/metadataOnStackMark.hpp" |
53 #include "classfile/metadataOnStackMark.hpp" |
54 #include "classfile/systemDictionary.hpp" |
54 #include "classfile/systemDictionary.hpp" |
55 #include "code/codeCache.hpp" |
55 #include "code/codeCache.hpp" |
56 #include "gc/shared/gcLocker.hpp" |
56 #include "gc/shared/gcLocker.hpp" |
|
57 #include "logging/log.hpp" |
57 #include "memory/metadataFactory.hpp" |
58 #include "memory/metadataFactory.hpp" |
58 #include "memory/metaspaceShared.hpp" |
59 #include "memory/metaspaceShared.hpp" |
59 #include "memory/oopFactory.hpp" |
60 #include "memory/oopFactory.hpp" |
60 #include "oops/objArrayOop.inline.hpp" |
61 #include "oops/objArrayOop.inline.hpp" |
61 #include "oops/oop.inline.hpp" |
62 #include "oops/oop.inline.hpp" |
62 #include "runtime/atomic.inline.hpp" |
63 #include "runtime/atomic.inline.hpp" |
|
64 #include "runtime/javaCalls.hpp" |
63 #include "runtime/jniHandles.hpp" |
65 #include "runtime/jniHandles.hpp" |
64 #include "runtime/mutex.hpp" |
66 #include "runtime/mutex.hpp" |
65 #include "runtime/safepoint.hpp" |
67 #include "runtime/safepoint.hpp" |
66 #include "runtime/synchronizer.hpp" |
68 #include "runtime/synchronizer.hpp" |
67 #include "utilities/growableArray.hpp" |
69 #include "utilities/growableArray.hpp" |
284 OrderAccess::storestore(); |
286 OrderAccess::storestore(); |
285 // link the new item into the list |
287 // link the new item into the list |
286 _klasses = k; |
288 _klasses = k; |
287 } |
289 } |
288 |
290 |
289 if (publicize && TraceClassLoaderData && Verbose && k->class_loader_data() != NULL) { |
291 if (publicize && k->class_loader_data() != NULL) { |
290 ResourceMark rm; |
292 ResourceMark rm; |
291 tty->print_cr("[TraceClassLoaderData] Adding k: " PTR_FORMAT " %s to CLD: " |
293 log_trace(classloaderdata)("Adding k: " PTR_FORMAT " %s to CLD: " |
292 PTR_FORMAT " loader: " PTR_FORMAT " %s", |
294 PTR_FORMAT " loader: " PTR_FORMAT " %s", |
293 p2i(k), |
295 p2i(k), |
294 k->external_name(), |
296 k->external_name(), |
295 p2i(k->class_loader_data()), |
297 p2i(k->class_loader_data()), |
296 p2i((void *)k->class_loader()), |
298 p2i((void *)k->class_loader()), |
324 _unloading = true; |
326 _unloading = true; |
325 |
327 |
326 // Tell serviceability tools these classes are unloading |
328 // Tell serviceability tools these classes are unloading |
327 classes_do(InstanceKlass::notify_unload_class); |
329 classes_do(InstanceKlass::notify_unload_class); |
328 |
330 |
329 if (TraceClassLoaderData) { |
331 if (log_is_enabled(Debug, classloaderdata)) { |
330 ResourceMark rm; |
332 ResourceMark rm; |
331 tty->print("[ClassLoaderData: unload loader data " INTPTR_FORMAT, p2i(this)); |
333 outputStream* log = LogHandle(classloaderdata)::debug_stream(); |
332 tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), |
334 log->print(": unload loader data " INTPTR_FORMAT, p2i(this)); |
|
335 log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), |
333 loader_name()); |
336 loader_name()); |
334 if (is_anonymous()) { |
337 if (is_anonymous()) { |
335 tty->print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); |
338 log->print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); |
336 } |
339 } |
337 tty->print_cr("]"); |
340 log->cr(); |
338 } |
341 } |
339 } |
342 } |
340 |
343 |
341 oop ClassLoaderData::keep_alive_object() const { |
344 oop ClassLoaderData::keep_alive_object() const { |
342 assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); |
345 assert(!keep_alive(), "Don't use with CLDs that are artificially kept alive"); |
406 } |
409 } |
407 if (this == the_null_class_loader_data()) { |
410 if (this == the_null_class_loader_data()) { |
408 assert (class_loader() == NULL, "Must be"); |
411 assert (class_loader() == NULL, "Must be"); |
409 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); |
412 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); |
410 } else if (is_anonymous()) { |
413 } else if (is_anonymous()) { |
411 if (TraceClassLoaderData && Verbose && class_loader() != NULL) { |
414 if (class_loader() != NULL) { |
412 tty->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name()); |
415 log_trace(classloaderdata)("is_anonymous: %s", class_loader()->klass()->internal_name()); |
413 } |
416 } |
414 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); |
417 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); |
415 } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { |
418 } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { |
416 if (TraceClassLoaderData && Verbose && class_loader() != NULL) { |
419 if (class_loader() != NULL) { |
417 tty->print_cr("is_reflection: %s", class_loader()->klass()->internal_name()); |
420 log_trace(classloaderdata)("is_reflection: %s", class_loader()->klass()->internal_name()); |
418 } |
421 } |
419 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); |
422 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); |
420 } else { |
423 } else { |
421 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); |
424 set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); |
422 } |
425 } |
599 |
602 |
600 do { |
603 do { |
601 cld->set_next(next); |
604 cld->set_next(next); |
602 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); |
605 ClassLoaderData* exchanged = (ClassLoaderData*)Atomic::cmpxchg_ptr(cld, list_head, next); |
603 if (exchanged == next) { |
606 if (exchanged == next) { |
604 if (TraceClassLoaderData) { |
607 if (log_is_enabled(Debug, classloaderdata)) { |
605 ResourceMark rm; |
608 PauseNoSafepointVerifier pnsv(&no_safepoints); // Need safe points for JavaCalls::call_virtual |
606 tty->print("[ClassLoaderData: "); |
609 log_creation(loader, cld, CHECK_NULL); |
607 tty->print("create class loader data " INTPTR_FORMAT, p2i(cld)); |
|
608 tty->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), |
|
609 cld->loader_name()); |
|
610 tty->print_cr("]"); |
|
611 } |
610 } |
612 return cld; |
611 return cld; |
613 } |
612 } |
614 next = exchanged; |
613 next = exchanged; |
615 } while (true); |
614 } while (true); |
616 |
615 } |
617 } |
616 |
|
617 void ClassLoaderDataGraph::log_creation(Handle loader, ClassLoaderData* cld, TRAPS) { |
|
618 Handle string; |
|
619 if (loader.not_null()) { |
|
620 // Include the result of loader.toString() in the output. This allows |
|
621 // the user of the log to identify the class loader instance. |
|
622 JavaValue result(T_OBJECT); |
|
623 KlassHandle spec_klass(THREAD, SystemDictionary::ClassLoader_klass()); |
|
624 JavaCalls::call_virtual(&result, |
|
625 loader, |
|
626 spec_klass, |
|
627 vmSymbols::toString_name(), |
|
628 vmSymbols::void_string_signature(), |
|
629 CHECK); |
|
630 assert(result.get_type() == T_OBJECT, "just checking"); |
|
631 string = (oop)result.get_jobject(); |
|
632 } |
|
633 |
|
634 ResourceMark rm; |
|
635 outputStream* log = LogHandle(classloaderdata)::debug_stream(); |
|
636 log->print("create class loader data " INTPTR_FORMAT, p2i(cld)); |
|
637 log->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), |
|
638 cld->loader_name()); |
|
639 |
|
640 if (string.not_null()) { |
|
641 log->print(": "); |
|
642 java_lang_String::print(string(), log); |
|
643 } |
|
644 log->cr(); |
|
645 } |
|
646 |
618 |
647 |
619 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
648 void ClassLoaderDataGraph::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) { |
620 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
649 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
621 cld->oops_do(f, klass_closure, must_claim); |
650 cld->oops_do(f, klass_closure, must_claim); |
622 } |
651 } |
707 ClassLoaderData* curr = _head; |
736 ClassLoaderData* curr = _head; |
708 while (curr != _saved_head) { |
737 while (curr != _saved_head) { |
709 if (!curr->claimed()) { |
738 if (!curr->claimed()) { |
710 array->push(curr); |
739 array->push(curr); |
711 |
740 |
712 if (TraceClassLoaderData) { |
741 if (log_is_enabled(Debug, classloaderdata)) { |
713 tty->print("[ClassLoaderData] found new CLD: "); |
742 outputStream* log = LogHandle(classloaderdata)::debug_stream(); |
714 curr->print_value_on(tty); |
743 log->print("found new CLD: "); |
715 tty->cr(); |
744 curr->print_value_on(log); |
|
745 log->cr(); |
716 } |
746 } |
717 } |
747 } |
718 |
748 |
719 curr = curr->_next; |
749 curr = curr->_next; |
720 } |
750 } |