83 volatile size_t ClassLoaderDataGraph::_num_array_classes = 0; |
83 volatile size_t ClassLoaderDataGraph::_num_array_classes = 0; |
84 volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0; |
84 volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0; |
85 |
85 |
86 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
86 ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; |
87 |
87 |
88 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : |
88 void ClassLoaderData::init_null_class_loader_data() { |
|
89 assert(_the_null_class_loader_data == NULL, "cannot initialize twice"); |
|
90 assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice"); |
|
91 |
|
92 _the_null_class_loader_data = new ClassLoaderData(Handle(), false); |
|
93 ClassLoaderDataGraph::_head = _the_null_class_loader_data; |
|
94 assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be"); |
|
95 |
|
96 LogTarget(Debug, class, loader, data) lt; |
|
97 if (lt.is_enabled()) { |
|
98 ResourceMark rm; |
|
99 LogStream ls(lt); |
|
100 ls.print("create "); |
|
101 _the_null_class_loader_data->print_value_on(&ls); |
|
102 ls.cr(); |
|
103 } |
|
104 } |
|
105 |
|
106 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) : |
89 _class_loader(h_class_loader()), |
107 _class_loader(h_class_loader()), |
90 _is_anonymous(is_anonymous), |
108 _is_anonymous(is_anonymous), |
91 // An anonymous class loader data doesn't have anything to keep |
109 // An anonymous class loader data doesn't have anything to keep |
92 // it from being unloaded during parsing of the anonymous class. |
110 // it from being unloaded during parsing of the anonymous class. |
93 // The null-class-loader should always be kept alive. |
111 // The null-class-loader should always be kept alive. |
94 _keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0), |
112 _keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0), |
95 _metaspace(NULL), _unloading(false), _klasses(NULL), |
113 _metaspace(NULL), _unloading(false), _klasses(NULL), |
96 _modules(NULL), _packages(NULL), |
114 _modules(NULL), _packages(NULL), |
97 _claimed(0), _modified_oops(true), _accumulated_modified_oops(false), |
115 _claimed(0), _modified_oops(true), _accumulated_modified_oops(false), |
98 _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), |
116 _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), |
99 _next(NULL), _dependencies(dependencies), |
117 _next(NULL), |
100 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, |
118 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, |
101 Monitor::_safepoint_check_never)) { |
119 Monitor::_safepoint_check_never)) { |
102 |
120 |
103 // A ClassLoaderData created solely for an anonymous class should never have a |
121 // A ClassLoaderData created solely for an anonymous class should never have a |
104 // ModuleEntryTable or PackageEntryTable created for it. The defining package |
122 // ModuleEntryTable or PackageEntryTable created for it. The defining package |
110 _unnamed_module = ModuleEntry::create_boot_unnamed_module(this); |
128 _unnamed_module = ModuleEntry::create_boot_unnamed_module(this); |
111 } else { |
129 } else { |
112 // Create unnamed module for all other loaders |
130 // Create unnamed module for all other loaders |
113 _unnamed_module = ModuleEntry::create_unnamed_module(this); |
131 _unnamed_module = ModuleEntry::create_unnamed_module(this); |
114 } |
132 } |
115 } else { |
|
116 _unnamed_module = NULL; |
|
117 } |
|
118 |
|
119 if (!is_anonymous) { |
|
120 _dictionary = create_dictionary(); |
133 _dictionary = create_dictionary(); |
121 } else { |
134 } else { |
|
135 _packages = NULL; |
|
136 _unnamed_module = NULL; |
122 _dictionary = NULL; |
137 _dictionary = NULL; |
123 } |
138 } |
|
139 |
|
140 NOT_PRODUCT(_dependency_count = 0); // number of class loader dependencies |
|
141 |
124 TRACE_INIT_ID(this); |
142 TRACE_INIT_ID(this); |
125 } |
|
126 |
|
127 void ClassLoaderData::init_dependencies(TRAPS) { |
|
128 assert(!Universe::is_fully_initialized(), "should only be called when initializing"); |
|
129 assert(is_the_null_class_loader_data(), "should only call this for the null class loader"); |
|
130 _dependencies.init(CHECK); |
|
131 } |
|
132 |
|
133 void ClassLoaderData::Dependencies::init(TRAPS) { |
|
134 // Create empty dependencies array to add to. CMS requires this to be |
|
135 // an oop so that it can track additions via card marks. We think. |
|
136 _list_head = oopFactory::new_objectArray(2, CHECK); |
|
137 } |
143 } |
138 |
144 |
139 ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { |
145 ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { |
140 Chunk* c = _head; |
146 Chunk* c = _head; |
141 while (c != NULL) { |
147 while (c != NULL) { |
152 } |
158 } |
153 oop* handle = &_head->_data[_head->_size]; |
159 oop* handle = &_head->_data[_head->_size]; |
154 *handle = o; |
160 *handle = o; |
155 OrderAccess::release_store(&_head->_size, _head->_size + 1); |
161 OrderAccess::release_store(&_head->_size, _head->_size + 1); |
156 return handle; |
162 return handle; |
|
163 } |
|
164 |
|
165 int ClassLoaderData::ChunkedHandleList::count() const { |
|
166 int count = 0; |
|
167 Chunk* chunk = _head; |
|
168 while (chunk != NULL) { |
|
169 count += chunk->_size; |
|
170 chunk = chunk->_next; |
|
171 } |
|
172 return count; |
157 } |
173 } |
158 |
174 |
159 inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { |
175 inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { |
160 for (juint i = 0; i < size; i++) { |
176 for (juint i = 0; i < size; i++) { |
161 if (c->_data[i] != NULL) { |
177 if (c->_data[i] != NULL) { |
359 if (from == to || java_lang_ClassLoader::isAncestor(from, to)) { |
368 if (from == to || java_lang_ClassLoader::isAncestor(from, to)) { |
360 return; // this class loader is in the parent list, no need to add it. |
369 return; // this class loader is in the parent list, no need to add it. |
361 } |
370 } |
362 } |
371 } |
363 |
372 |
364 // It's a dependency we won't find through GC, add it. This is relatively rare. |
373 // It's a dependency we won't find through GC, add it. |
365 // Must handle over GC point. |
374 if (!_handles.contains(to)) { |
366 Handle dependency(THREAD, to); |
375 NOT_PRODUCT(Atomic::inc(&_dependency_count)); |
367 from_cld->_dependencies.add(dependency, CHECK); |
376 LogTarget(Trace, class, loader, data) lt; |
368 |
377 if (lt.is_enabled()) { |
369 // Added a potentially young gen oop to the ClassLoaderData |
378 ResourceMark rm; |
370 record_modified_oops(); |
379 LogStream ls(lt); |
371 } |
380 ls.print("adding dependency from "); |
372 |
381 print_value_on(&ls); |
373 |
382 ls.print(" to "); |
374 void ClassLoaderData::Dependencies::add(Handle dependency, TRAPS) { |
383 to_cld->print_value_on(&ls); |
375 // Check first if this dependency is already in the list. |
384 ls.cr(); |
376 // Save a pointer to the last to add to under the lock. |
385 } |
377 objArrayOop ok = _list_head; |
386 Handle dependency(Thread::current(), to); |
378 objArrayOop last = NULL; |
387 add_handle(dependency); |
379 while (ok != NULL) { |
388 // Added a potentially young gen oop to the ClassLoaderData |
380 last = ok; |
389 record_modified_oops(); |
381 if (ok->obj_at(0) == dependency()) { |
390 } |
382 // Don't need to add it |
391 } |
383 return; |
392 |
384 } |
|
385 ok = (objArrayOop)ok->obj_at(1); |
|
386 } |
|
387 |
|
388 // Must handle over GC points |
|
389 assert (last != NULL, "dependencies should be initialized"); |
|
390 objArrayHandle last_handle(THREAD, last); |
|
391 |
|
392 // Create a new dependency node with fields for (class_loader or mirror, next) |
|
393 objArrayOop deps = oopFactory::new_objectArray(2, CHECK); |
|
394 deps->obj_at_put(0, dependency()); |
|
395 |
|
396 // Must handle over GC points |
|
397 objArrayHandle new_dependency(THREAD, deps); |
|
398 |
|
399 // Add the dependency under lock |
|
400 locked_add(last_handle, new_dependency, THREAD); |
|
401 } |
|
402 |
|
403 void ClassLoaderData::Dependencies::locked_add(objArrayHandle last_handle, |
|
404 objArrayHandle new_dependency, |
|
405 Thread* THREAD) { |
|
406 |
|
407 // Have to lock and put the new dependency on the end of the dependency |
|
408 // array so the card mark for CMS sees that this dependency is new. |
|
409 // Can probably do this lock free with some effort. |
|
410 ObjectLocker ol(Handle(THREAD, _list_head), THREAD); |
|
411 |
|
412 oop loader_or_mirror = new_dependency->obj_at(0); |
|
413 |
|
414 // Since the dependencies are only added, add to the end. |
|
415 objArrayOop end = last_handle(); |
|
416 objArrayOop last = NULL; |
|
417 while (end != NULL) { |
|
418 last = end; |
|
419 // check again if another thread added it to the end. |
|
420 if (end->obj_at(0) == loader_or_mirror) { |
|
421 // Don't need to add it |
|
422 return; |
|
423 } |
|
424 end = (objArrayOop)end->obj_at(1); |
|
425 } |
|
426 assert (last != NULL, "dependencies should be initialized"); |
|
427 // fill in the first element with the oop in new_dependency. |
|
428 if (last->obj_at(0) == NULL) { |
|
429 last->obj_at_put(0, new_dependency->obj_at(0)); |
|
430 } else { |
|
431 last->obj_at_put(1, new_dependency()); |
|
432 } |
|
433 } |
|
434 |
393 |
435 void ClassLoaderDataGraph::clear_claimed_marks() { |
394 void ClassLoaderDataGraph::clear_claimed_marks() { |
436 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
395 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
437 cld->clear_claimed(); |
396 cld->clear_claimed(); |
438 } |
397 } |
451 } else { |
410 } else { |
452 ClassLoaderDataGraph::inc_instance_classes(1); |
411 ClassLoaderDataGraph::inc_instance_classes(1); |
453 } |
412 } |
454 } |
413 } |
455 |
414 |
456 if (publicize && k->class_loader_data() != NULL) { |
415 if (publicize) { |
457 ResourceMark rm; |
416 LogTarget(Trace, class, loader, data) lt; |
458 log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: " |
417 if (lt.is_enabled()) { |
459 PTR_FORMAT " loader: " PTR_FORMAT " %s", |
418 ResourceMark rm; |
460 p2i(k), |
419 LogStream ls(lt); |
461 k->external_name(), |
420 ls.print("Adding k: " PTR_FORMAT " %s to ", p2i(k), k->external_name()); |
462 p2i(k->class_loader_data()), |
421 print_value_on(&ls); |
463 p2i((void *)k->class_loader()), |
422 ls.cr(); |
464 loader_name()); |
423 } |
465 } |
424 } |
466 } |
425 } |
467 |
426 |
468 // Class iterator used by the compiler. It gets some number of classes at |
427 // Class iterator used by the compiler. It gets some number of classes at |
469 // a safepoint to decay invocation counters on the methods. |
428 // a safepoint to decay invocation counters on the methods. |
576 |
535 |
577 LogTarget(Debug, class, loader, data) lt; |
536 LogTarget(Debug, class, loader, data) lt; |
578 if (lt.is_enabled()) { |
537 if (lt.is_enabled()) { |
579 ResourceMark rm; |
538 ResourceMark rm; |
580 LogStream ls(lt); |
539 LogStream ls(lt); |
581 ls.print(": unload loader data " INTPTR_FORMAT, p2i(this)); |
540 ls.print("unload "); |
582 ls.print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), |
541 print_value_on(&ls); |
583 loader_name()); |
|
584 if (is_anonymous()) { |
|
585 ls.print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); |
|
586 } |
|
587 ls.cr(); |
542 ls.cr(); |
588 } |
543 } |
589 |
544 |
590 // Some items on the _deallocate_list need to free their C heap structures |
545 // Some items on the _deallocate_list need to free their C heap structures |
591 // if they are not already on the _klasses list. |
546 // if they are not already on the _klasses list. |
777 if ((metaspace = _metaspace) == NULL) { |
732 if ((metaspace = _metaspace) == NULL) { |
778 if (this == the_null_class_loader_data()) { |
733 if (this == the_null_class_loader_data()) { |
779 assert (class_loader() == NULL, "Must be"); |
734 assert (class_loader() == NULL, "Must be"); |
780 metaspace = new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType); |
735 metaspace = new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType); |
781 } else if (is_anonymous()) { |
736 } else if (is_anonymous()) { |
782 if (class_loader() != NULL) { |
|
783 log_trace(class, loader, data)("is_anonymous: %s", class_loader()->klass()->internal_name()); |
|
784 } |
|
785 metaspace = new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType); |
737 metaspace = new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType); |
786 } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { |
738 } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { |
787 if (class_loader() != NULL) { |
|
788 log_trace(class, loader, data)("is_reflection: %s", class_loader()->klass()->internal_name()); |
|
789 } |
|
790 metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); |
739 metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); |
791 } else { |
740 } else { |
792 metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType); |
741 metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType); |
793 } |
742 } |
794 // Ensure _metaspace is stable, since it is examined without a lock |
743 // Ensure _metaspace is stable, since it is examined without a lock |
806 |
755 |
807 void ClassLoaderData::remove_handle(OopHandle h) { |
756 void ClassLoaderData::remove_handle(OopHandle h) { |
808 assert(!is_unloading(), "Do not remove a handle for a CLD that is unloading"); |
757 assert(!is_unloading(), "Do not remove a handle for a CLD that is unloading"); |
809 oop* ptr = h.ptr_raw(); |
758 oop* ptr = h.ptr_raw(); |
810 if (ptr != NULL) { |
759 if (ptr != NULL) { |
811 assert(_handles.contains(ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr)); |
760 assert(_handles.contains(*ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr)); |
812 // This root is not walked in safepoints, and hence requires an appropriate |
761 // This root is not walked in safepoints, and hence requires an appropriate |
813 // decorator that e.g. maintains the SATB invariant in SATB collectors. |
762 // decorator that e.g. maintains the SATB invariant in SATB collectors. |
814 RootAccess<IN_CONCURRENT_ROOT>::oop_store(ptr, oop(NULL)); |
763 RootAccess<IN_CONCURRENT_ROOT>::oop_store(ptr, oop(NULL)); |
815 } |
764 } |
816 } |
765 } |
900 } |
849 } |
901 } |
850 } |
902 } |
851 } |
903 |
852 |
904 // These anonymous class loaders are to contain classes used for JSR292 |
853 // These anonymous class loaders are to contain classes used for JSR292 |
905 ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) { |
854 ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(Handle loader) { |
906 // Add a new class loader data to the graph. |
855 // Add a new class loader data to the graph. |
907 Handle lh(THREAD, loader); |
856 return ClassLoaderDataGraph::add(loader, true); |
908 return ClassLoaderDataGraph::add(lh, true, THREAD); |
857 } |
909 } |
858 |
910 |
859 const char* ClassLoaderData::loader_name() const { |
911 const char* ClassLoaderData::loader_name() { |
|
912 // Handles null class loader |
860 // Handles null class loader |
913 return SystemDictionary::loader_name(class_loader()); |
861 return SystemDictionary::loader_name(class_loader()); |
914 } |
862 } |
915 |
863 |
|
864 |
|
865 void ClassLoaderData::print_value_on(outputStream* out) const { |
|
866 if (class_loader() != NULL) { |
|
867 out->print("loader data: " INTPTR_FORMAT " for instance ", p2i(this)); |
|
868 class_loader()->print_value_on(out); // includes loader_name() and address of class loader instance |
|
869 } else { |
|
870 // loader data: 0xsomeaddr of <bootloader> |
|
871 out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name()); |
|
872 } |
|
873 if (is_anonymous()) { |
|
874 out->print(" anonymous"); |
|
875 } |
|
876 } |
|
877 |
916 #ifndef PRODUCT |
878 #ifndef PRODUCT |
917 // Define to dump klasses |
879 void ClassLoaderData::print_on(outputStream* out) const { |
918 #undef CLD_DUMP_KLASSES |
880 out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", |
919 |
881 p2i(this), p2i((void *)class_loader()), loader_name()); |
920 void ClassLoaderData::dump(outputStream * const out) { |
882 if (is_anonymous()) out->print(" anonymous"); |
921 out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: " PTR_FORMAT " %s {", |
883 if (claimed()) out->print(" claimed"); |
922 p2i(this), p2i((void *)class_loader()), |
884 if (is_unloading()) out->print(" unloading"); |
923 p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); |
885 out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); |
924 if (claimed()) out->print(" claimed "); |
886 |
925 if (is_unloading()) out->print(" unloading "); |
|
926 out->cr(); |
|
927 if (metaspace_or_null() != NULL) { |
|
928 out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); |
|
929 metaspace_or_null()->dump(out); |
|
930 } else { |
|
931 out->print_cr("metaspace: NULL"); |
|
932 } |
|
933 |
|
934 #ifdef CLD_DUMP_KLASSES |
|
935 if (Verbose) { |
|
936 Klass* k = _klasses; |
|
937 while (k != NULL) { |
|
938 out->print_cr("klass " PTR_FORMAT ", %s", p2i(k), k->name()->as_C_string()); |
|
939 assert(k != k->next_link(), "no loops!"); |
|
940 k = k->next_link(); |
|
941 } |
|
942 } |
|
943 #endif // CLD_DUMP_KLASSES |
|
944 #undef CLD_DUMP_KLASSES |
|
945 if (_jmethod_ids != NULL) { |
887 if (_jmethod_ids != NULL) { |
946 Method::print_jmethod_ids(this, out); |
888 Method::print_jmethod_ids(this, out); |
947 } |
889 } |
|
890 out->print(" handles count %d", _handles.count()); |
|
891 out->print(" dependencies %d", _dependency_count); |
948 out->print_cr("}"); |
892 out->print_cr("}"); |
949 } |
893 } |
950 #endif // PRODUCT |
894 #endif // PRODUCT |
951 |
895 |
952 void ClassLoaderData::verify() { |
896 void ClassLoaderData::verify() { |
986 bool ClassLoaderDataGraph::_should_purge = false; |
930 bool ClassLoaderDataGraph::_should_purge = false; |
987 bool ClassLoaderDataGraph::_metaspace_oom = false; |
931 bool ClassLoaderDataGraph::_metaspace_oom = false; |
988 |
932 |
989 // Add a new class loader data node to the list. Assign the newly created |
933 // Add a new class loader data node to the list. Assign the newly created |
990 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field |
934 // ClassLoaderData into the java/lang/ClassLoader object as a hidden field |
991 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { |
935 ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) { |
992 // We need to allocate all the oops for the ClassLoaderData before allocating the |
|
993 // actual ClassLoaderData object. |
|
994 ClassLoaderData::Dependencies dependencies(CHECK_NULL); |
|
995 |
|
996 NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the |
936 NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the |
997 // ClassLoaderData in the graph since the CLD |
937 // ClassLoaderData in the graph since the CLD |
998 // contains unhandled oops |
938 // contains unhandled oops |
999 |
939 |
1000 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies); |
940 ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); |
1001 |
941 |
1002 |
942 |
1003 if (!is_anonymous) { |
943 if (!is_anonymous) { |
1004 // First, Atomically set it |
944 // First, Atomically set it |
1005 ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL); |
945 ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL); |
1019 cld->set_next(next); |
959 cld->set_next(next); |
1020 ClassLoaderData* exchanged = Atomic::cmpxchg(cld, list_head, next); |
960 ClassLoaderData* exchanged = Atomic::cmpxchg(cld, list_head, next); |
1021 if (exchanged == next) { |
961 if (exchanged == next) { |
1022 LogTarget(Debug, class, loader, data) lt; |
962 LogTarget(Debug, class, loader, data) lt; |
1023 if (lt.is_enabled()) { |
963 if (lt.is_enabled()) { |
1024 PauseNoSafepointVerifier pnsv(&no_safepoints); // Need safe points for JavaCalls::call_virtual |
964 ResourceMark rm; |
1025 LogStream ls(lt); |
965 LogStream ls(lt); |
1026 print_creation(&ls, loader, cld, CHECK_NULL); |
966 ls.print("create "); |
|
967 cld->print_value_on(&ls); |
|
968 ls.cr(); |
1027 } |
969 } |
1028 return cld; |
970 return cld; |
1029 } |
971 } |
1030 next = exchanged; |
972 next = exchanged; |
1031 } while (true); |
973 } while (true); |
1032 } |
974 } |
1033 |
|
1034 void ClassLoaderDataGraph::print_creation(outputStream* out, Handle loader, ClassLoaderData* cld, TRAPS) { |
|
1035 Handle string; |
|
1036 if (loader.not_null()) { |
|
1037 // Include the result of loader.toString() in the output. This allows |
|
1038 // the user of the log to identify the class loader instance. |
|
1039 JavaValue result(T_OBJECT); |
|
1040 Klass* spec_klass = SystemDictionary::ClassLoader_klass(); |
|
1041 JavaCalls::call_virtual(&result, |
|
1042 loader, |
|
1043 spec_klass, |
|
1044 vmSymbols::toString_name(), |
|
1045 vmSymbols::void_string_signature(), |
|
1046 CHECK); |
|
1047 assert(result.get_type() == T_OBJECT, "just checking"); |
|
1048 string = Handle(THREAD, (oop)result.get_jobject()); |
|
1049 } |
|
1050 |
|
1051 ResourceMark rm; |
|
1052 out->print("create class loader data " INTPTR_FORMAT, p2i(cld)); |
|
1053 out->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), |
|
1054 cld->loader_name()); |
|
1055 |
|
1056 if (string.not_null()) { |
|
1057 out->print(": "); |
|
1058 java_lang_String::print(string(), out); |
|
1059 } |
|
1060 out->cr(); |
|
1061 } |
|
1062 |
|
1063 |
975 |
1064 void ClassLoaderDataGraph::oops_do(OopClosure* f, bool must_claim) { |
976 void ClassLoaderDataGraph::oops_do(OopClosure* f, bool must_claim) { |
1065 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
977 for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { |
1066 cld->oops_do(f, must_claim); |
978 cld->oops_do(f, must_claim); |
1067 } |
979 } |
1475 ClassLoaderDataGraphMetaspaceIterator::~ClassLoaderDataGraphMetaspaceIterator() {} |
1387 ClassLoaderDataGraphMetaspaceIterator::~ClassLoaderDataGraphMetaspaceIterator() {} |
1476 |
1388 |
1477 #ifndef PRODUCT |
1389 #ifndef PRODUCT |
1478 // callable from debugger |
1390 // callable from debugger |
1479 extern "C" int print_loader_data_graph() { |
1391 extern "C" int print_loader_data_graph() { |
1480 ClassLoaderDataGraph::dump_on(tty); |
1392 ResourceMark rm; |
|
1393 ClassLoaderDataGraph::print_on(tty); |
1481 return 0; |
1394 return 0; |
1482 } |
1395 } |
1483 |
1396 |
1484 void ClassLoaderDataGraph::verify() { |
1397 void ClassLoaderDataGraph::verify() { |
1485 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
1398 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
1486 data->verify(); |
1399 data->verify(); |
1487 } |
1400 } |
1488 } |
1401 } |
1489 |
1402 |
1490 void ClassLoaderDataGraph::dump_on(outputStream * const out) { |
1403 void ClassLoaderDataGraph::print_on(outputStream * const out) { |
1491 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
1404 for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { |
1492 data->dump(out); |
1405 data->print_on(out); |
1493 } |
1406 } |
1494 MetaspaceAux::dump(out); |
|
1495 } |
1407 } |
1496 #endif // PRODUCT |
1408 #endif // PRODUCT |
1497 |
|
1498 void ClassLoaderData::print_value_on(outputStream* out) const { |
|
1499 if (class_loader() == NULL) { |
|
1500 out->print("NULL class loader"); |
|
1501 } else { |
|
1502 out->print("class loader " INTPTR_FORMAT " ", p2i(this)); |
|
1503 class_loader()->print_value_on(out); |
|
1504 } |
|
1505 } |
|
1506 |
|
1507 void ClassLoaderData::print_on(outputStream* out) const { |
|
1508 if (class_loader() == NULL) { |
|
1509 out->print("NULL class loader"); |
|
1510 } else { |
|
1511 out->print("class loader " INTPTR_FORMAT " ", p2i(this)); |
|
1512 class_loader()->print_on(out); |
|
1513 } |
|
1514 } |
|
1515 |
1409 |
1516 #if INCLUDE_TRACE |
1410 #if INCLUDE_TRACE |
1517 |
1411 |
1518 Ticks ClassLoaderDataGraph::_class_unload_time; |
1412 Ticks ClassLoaderDataGraph::_class_unload_time; |
1519 |
1413 |