--- old/src/hotspot/share/classfile/classFileParser.cpp 2018-03-02 22:42:54.869661313 -0500 +++ new/src/hotspot/share/classfile/classFileParser.cpp 2018-03-02 22:42:53.815838187 -0500 @@ -4381,7 +4381,7 @@ // add super class dependency Klass* const super = defined_klass->super(); if (super != NULL) { - defining_loader_data->record_dependency(super, CHECK); + defining_loader_data->record_dependency(super); } // add super interface dependencies @@ -4389,7 +4389,7 @@ if (local_interfaces != NULL) { const int length = local_interfaces->length(); for (int i = 0; i < length; i++) { - defining_loader_data->record_dependency(local_interfaces->at(i), CHECK); + defining_loader_data->record_dependency(local_interfaces->at(i)); } } } @@ -5362,6 +5362,16 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loadhook, TRAPS) { assert(ik != NULL, "invariant"); + // Set name and CLD before adding to CLD + ik->set_class_loader_data(_loader_data); + ik->set_name(_class_name); + + // Add all classes to our internal class loader list here, + // including classes in the bootstrap (NULL) class loader. + const bool publicize = !is_internal(); + + _loader_data->add_class(ik, publicize); + set_klass_to_deallocate(ik); assert(_field_info != NULL, "invariant"); @@ -5376,7 +5386,6 @@ ik->set_should_verify_class(_need_verify); // Not yet: supers are done below to support the new subtype-checking fields - ik->set_class_loader_data(_loader_data); ik->set_nonstatic_field_size(_field_info->nonstatic_field_size); ik->set_has_nonstatic_fields(_field_info->has_nonstatic_fields); assert(_fac != NULL, "invariant"); @@ -5407,8 +5416,6 @@ // has to be changed accordingly. ik->set_initial_method_idnum(ik->methods()->length()); - ik->set_name(_class_name); - if (is_anonymous()) { // _this_class_index is a CONSTANT_Class entry that refers to this // anonymous class itself. If this class needs to refer to its own methods or --- old/src/hotspot/share/classfile/classLoaderData.cpp 2018-03-02 22:43:06.140575350 -0500 +++ new/src/hotspot/share/classfile/classLoaderData.cpp 2018-03-02 22:43:05.660530180 -0500 @@ -85,7 +85,25 @@ ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; -ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : +void ClassLoaderData::init_null_class_loader_data() { + assert(_the_null_class_loader_data == NULL, "cannot initialize twice"); + assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice"); + + _the_null_class_loader_data = new ClassLoaderData(Handle(), false); + ClassLoaderDataGraph::_head = _the_null_class_loader_data; + assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be"); + + LogTarget(Debug, class, loader, data) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + ls.print("create "); + _the_null_class_loader_data->print_value_on(&ls); + ls.cr(); + } +} + +ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) : _class_loader(h_class_loader()), _is_anonymous(is_anonymous), // An anonymous class loader data doesn't have anything to keep @@ -96,7 +114,7 @@ _modules(NULL), _packages(NULL), _claimed(0), _modified_oops(true), _accumulated_modified_oops(false), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), - _next(NULL), _dependencies(dependencies), + _next(NULL), _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, Monitor::_safepoint_check_never)) { @@ -112,28 +130,16 @@ // Create unnamed module for all other loaders _unnamed_module = ModuleEntry::create_unnamed_module(this); } - } else { - _unnamed_module = NULL; - } - - if (!is_anonymous) { _dictionary = create_dictionary(); } else { + _packages = NULL; + _unnamed_module = NULL; _dictionary = NULL; } - TRACE_INIT_ID(this); -} -void ClassLoaderData::init_dependencies(TRAPS) { - assert(!Universe::is_fully_initialized(), "should only be called when initializing"); - assert(is_the_null_class_loader_data(), "should only call this for the null class loader"); - _dependencies.init(CHECK); -} + NOT_PRODUCT(_dependency_count = 0); // number of class loader dependencies -void ClassLoaderData::Dependencies::init(TRAPS) { - // Create empty dependencies array to add to. CMS requires this to be - // an oop so that it can track additions via card marks. We think. - _list_head = oopFactory::new_objectArray(2, CHECK); + TRACE_INIT_ID(this); } ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { @@ -156,6 +162,16 @@ return handle; } +int ClassLoaderData::ChunkedHandleList::count() const { + int count = 0; + Chunk* chunk = _head; + while (chunk != NULL) { + count += chunk->_size; + chunk = chunk->_next; + } + return count; +} + inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { for (juint i = 0; i < size; i++) { if (c->_data[i] != NULL) { @@ -175,16 +191,15 @@ } } -#ifdef ASSERT class VerifyContainsOopClosure : public OopClosure { - oop* _target; + oop _target; bool _found; public: - VerifyContainsOopClosure(oop* target) : _target(target), _found(false) {} + VerifyContainsOopClosure(oop target) : _target(target), _found(false) {} void do_oop(oop* p) { - if (p == _target) { + if (p != NULL && *p == _target) { _found = true; } } @@ -199,12 +214,11 @@ } }; -bool ClassLoaderData::ChunkedHandleList::contains(oop* p) { +bool ClassLoaderData::ChunkedHandleList::contains(oop p) { VerifyContainsOopClosure cl(p); oops_do(&cl); return cl.found(); } -#endif // ASSERT bool ClassLoaderData::claim() { if (_claimed == 1) { @@ -244,14 +258,9 @@ } f->do_oop(&_class_loader); - _dependencies.oops_do(f); _handles.oops_do(f); } -void ClassLoaderData::Dependencies::oops_do(OopClosure* f) { - f->do_oop((oop*)&_list_head); -} - void ClassLoaderData::classes_do(KlassClosure* klass_closure) { // Lock-free access requires load_acquire for (Klass* k = OrderAccess::load_acquire(&_klasses); k != NULL; k = k->next_link()) { @@ -326,7 +335,7 @@ } } -void ClassLoaderData::record_dependency(const Klass* k, TRAPS) { +void ClassLoaderData::record_dependency(const Klass* k) { assert(k != NULL, "invariant"); ClassLoaderData * const from_cld = this; @@ -361,76 +370,26 @@ } } - // It's a dependency we won't find through GC, add it. This is relatively rare. - // Must handle over GC point. - Handle dependency(THREAD, to); - from_cld->_dependencies.add(dependency, CHECK); - - // Added a potentially young gen oop to the ClassLoaderData - record_modified_oops(); -} - - -void ClassLoaderData::Dependencies::add(Handle dependency, TRAPS) { - // Check first if this dependency is already in the list. - // Save a pointer to the last to add to under the lock. - objArrayOop ok = _list_head; - objArrayOop last = NULL; - while (ok != NULL) { - last = ok; - if (ok->obj_at(0) == dependency()) { - // Don't need to add it - return; - } - ok = (objArrayOop)ok->obj_at(1); + // It's a dependency we won't find through GC, add it. + if (!_handles.contains(to)) { + NOT_PRODUCT(Atomic::inc(&_dependency_count)); + LogTarget(Trace, class, loader, data) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + ls.print("adding dependency from "); + print_value_on(&ls); + ls.print(" to "); + to_cld->print_value_on(&ls); + ls.cr(); + } + Handle dependency(Thread::current(), to); + add_handle(dependency); + // Added a potentially young gen oop to the ClassLoaderData + record_modified_oops(); } - - // Must handle over GC points - assert (last != NULL, "dependencies should be initialized"); - objArrayHandle last_handle(THREAD, last); - - // Create a new dependency node with fields for (class_loader or mirror, next) - objArrayOop deps = oopFactory::new_objectArray(2, CHECK); - deps->obj_at_put(0, dependency()); - - // Must handle over GC points - objArrayHandle new_dependency(THREAD, deps); - - // Add the dependency under lock - locked_add(last_handle, new_dependency, THREAD); } -void ClassLoaderData::Dependencies::locked_add(objArrayHandle last_handle, - objArrayHandle new_dependency, - Thread* THREAD) { - - // Have to lock and put the new dependency on the end of the dependency - // array so the card mark for CMS sees that this dependency is new. - // Can probably do this lock free with some effort. - ObjectLocker ol(Handle(THREAD, _list_head), THREAD); - - oop loader_or_mirror = new_dependency->obj_at(0); - - // Since the dependencies are only added, add to the end. - objArrayOop end = last_handle(); - objArrayOop last = NULL; - while (end != NULL) { - last = end; - // check again if another thread added it to the end. - if (end->obj_at(0) == loader_or_mirror) { - // Don't need to add it - return; - } - end = (objArrayOop)end->obj_at(1); - } - assert (last != NULL, "dependencies should be initialized"); - // fill in the first element with the oop in new_dependency. - if (last->obj_at(0) == NULL) { - last->obj_at_put(0, new_dependency->obj_at(0)); - } else { - last->obj_at_put(1, new_dependency()); - } -} void ClassLoaderDataGraph::clear_claimed_marks() { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { @@ -453,15 +412,15 @@ } } - if (publicize && k->class_loader_data() != NULL) { - ResourceMark rm; - log_trace(class, loader, data)("Adding k: " PTR_FORMAT " %s to CLD: " - PTR_FORMAT " loader: " PTR_FORMAT " %s", - p2i(k), - k->external_name(), - p2i(k->class_loader_data()), - p2i((void *)k->class_loader()), - loader_name()); + if (publicize) { + LogTarget(Trace, class, loader, data) lt; + if (lt.is_enabled()) { + ResourceMark rm; + LogStream ls(lt); + ls.print("Adding k: " PTR_FORMAT " %s to ", p2i(k), k->external_name()); + print_value_on(&ls); + ls.cr(); + } } } @@ -578,12 +537,8 @@ if (lt.is_enabled()) { ResourceMark rm; LogStream ls(lt); - ls.print(": unload loader data " INTPTR_FORMAT, p2i(this)); - ls.print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)class_loader()), - loader_name()); - if (is_anonymous()) { - ls.print(" for anonymous class " INTPTR_FORMAT " ", p2i(_klasses)); - } + ls.print("unload "); + print_value_on(&ls); ls.cr(); } @@ -779,14 +734,8 @@ assert (class_loader() == NULL, "Must be"); metaspace = new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType); } else if (is_anonymous()) { - if (class_loader() != NULL) { - log_trace(class, loader, data)("is_anonymous: %s", class_loader()->klass()->internal_name()); - } metaspace = new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType); } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { - if (class_loader() != NULL) { - log_trace(class, loader, data)("is_reflection: %s", class_loader()->klass()->internal_name()); - } metaspace = new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); } else { metaspace = new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType); @@ -808,7 +757,7 @@ assert(!is_unloading(), "Do not remove a handle for a CLD that is unloading"); oop* ptr = h.ptr_raw(); if (ptr != NULL) { - assert(_handles.contains(ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr)); + assert(_handles.contains(*ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr)); // This root is not walked in safepoints, and hence requires an appropriate // decorator that e.g. maintains the SATB invariant in SATB collectors. RootAccess::oop_store(ptr, oop(NULL)); @@ -902,49 +851,44 @@ } // These anonymous class loaders are to contain classes used for JSR292 -ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) { +ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(Handle loader) { // Add a new class loader data to the graph. - Handle lh(THREAD, loader); - return ClassLoaderDataGraph::add(lh, true, THREAD); + return ClassLoaderDataGraph::add(loader, true); } -const char* ClassLoaderData::loader_name() { +const char* ClassLoaderData::loader_name() const { // Handles null class loader return SystemDictionary::loader_name(class_loader()); } -#ifndef PRODUCT -// Define to dump klasses -#undef CLD_DUMP_KLASSES -void ClassLoaderData::dump(outputStream * const out) { - out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: " PTR_FORMAT " %s {", - p2i(this), p2i((void *)class_loader()), - p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); - if (claimed()) out->print(" claimed "); - if (is_unloading()) out->print(" unloading "); - out->cr(); - if (metaspace_or_null() != NULL) { - out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); - metaspace_or_null()->dump(out); +void ClassLoaderData::print_value_on(outputStream* out) const { + if (class_loader() != NULL) { + out->print("loader data: " INTPTR_FORMAT " for instance ", p2i(this)); + class_loader()->print_value_on(out); // includes loader_name() and address of class loader instance } else { - out->print_cr("metaspace: NULL"); + // loader data: 0xsomeaddr of + out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name()); } - -#ifdef CLD_DUMP_KLASSES - if (Verbose) { - Klass* k = _klasses; - while (k != NULL) { - out->print_cr("klass " PTR_FORMAT ", %s", p2i(k), k->name()->as_C_string()); - assert(k != k->next_link(), "no loops!"); - k = k->next_link(); - } + if (is_anonymous()) { + out->print(" anonymous"); } -#endif // CLD_DUMP_KLASSES -#undef CLD_DUMP_KLASSES +} + +#ifndef PRODUCT +void ClassLoaderData::print_on(outputStream* out) const { + out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", + p2i(this), p2i((void *)class_loader()), loader_name()); + if (is_anonymous()) out->print(" anonymous"); + if (claimed()) out->print(" claimed"); + if (is_unloading()) out->print(" unloading"); + out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); + if (_jmethod_ids != NULL) { Method::print_jmethod_ids(this, out); } + out->print(" handles count %d", _handles.count()); + out->print(" dependencies %d", _dependency_count); out->print_cr("}"); } #endif // PRODUCT @@ -988,16 +932,12 @@ // Add a new class loader data node to the list. Assign the newly created // ClassLoaderData into the java/lang/ClassLoader object as a hidden field -ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { - // We need to allocate all the oops for the ClassLoaderData before allocating the - // actual ClassLoaderData object. - ClassLoaderData::Dependencies dependencies(CHECK_NULL); - +ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) { NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the // ClassLoaderData in the graph since the CLD // contains unhandled oops - ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous, dependencies); + ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); if (!is_anonymous) { @@ -1021,9 +961,11 @@ if (exchanged == next) { LogTarget(Debug, class, loader, data) lt; if (lt.is_enabled()) { - PauseNoSafepointVerifier pnsv(&no_safepoints); // Need safe points for JavaCalls::call_virtual - LogStream ls(lt); - print_creation(&ls, loader, cld, CHECK_NULL); + ResourceMark rm; + LogStream ls(lt); + ls.print("create "); + cld->print_value_on(&ls); + ls.cr(); } return cld; } @@ -1031,36 +973,6 @@ } while (true); } -void ClassLoaderDataGraph::print_creation(outputStream* out, Handle loader, ClassLoaderData* cld, TRAPS) { - Handle string; - if (loader.not_null()) { - // Include the result of loader.toString() in the output. This allows - // the user of the log to identify the class loader instance. - JavaValue result(T_OBJECT); - Klass* spec_klass = SystemDictionary::ClassLoader_klass(); - JavaCalls::call_virtual(&result, - loader, - spec_klass, - vmSymbols::toString_name(), - vmSymbols::void_string_signature(), - CHECK); - assert(result.get_type() == T_OBJECT, "just checking"); - string = Handle(THREAD, (oop)result.get_jobject()); - } - - ResourceMark rm; - out->print("create class loader data " INTPTR_FORMAT, p2i(cld)); - out->print(" for instance " INTPTR_FORMAT " of %s", p2i((void *)cld->class_loader()), - cld->loader_name()); - - if (string.not_null()) { - out->print(": "); - java_lang_String::print(string(), out); - } - out->cr(); -} - - void ClassLoaderDataGraph::oops_do(OopClosure* f, bool must_claim) { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { cld->oops_do(f, must_claim); @@ -1477,7 +1389,8 @@ #ifndef PRODUCT // callable from debugger extern "C" int print_loader_data_graph() { - ClassLoaderDataGraph::dump_on(tty); + ResourceMark rm; + ClassLoaderDataGraph::print_on(tty); return 0; } @@ -1487,32 +1400,13 @@ } } -void ClassLoaderDataGraph::dump_on(outputStream * const out) { +void ClassLoaderDataGraph::print_on(outputStream * const out) { for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { - data->dump(out); + data->print_on(out); } - MetaspaceAux::dump(out); } #endif // PRODUCT -void ClassLoaderData::print_value_on(outputStream* out) const { - if (class_loader() == NULL) { - out->print("NULL class loader"); - } else { - out->print("class loader " INTPTR_FORMAT " ", p2i(this)); - class_loader()->print_value_on(out); - } -} - -void ClassLoaderData::print_on(outputStream* out) const { - if (class_loader() == NULL) { - out->print("NULL class loader"); - } else { - out->print("class loader " INTPTR_FORMAT " ", p2i(this)); - class_loader()->print_on(out); - } -} - #if INCLUDE_TRACE Ticks ClassLoaderDataGraph::_class_unload_time; --- old/src/hotspot/share/classfile/classLoaderData.hpp 2018-03-02 22:43:16.792241392 -0500 +++ new/src/hotspot/share/classfile/classLoaderData.hpp 2018-03-02 22:43:16.229825195 -0500 @@ -83,10 +83,10 @@ static volatile size_t _num_instance_classes; static volatile size_t _num_array_classes; - static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); + static ClassLoaderData* add(Handle class_loader, bool anonymous); static void post_class_unload_events(); public: - static ClassLoaderData* find_or_create(Handle class_loader, TRAPS); + static ClassLoaderData* find_or_create(Handle class_loader); static void purge(); static void clear_claimed_marks(); // oops do @@ -151,10 +151,9 @@ static bool has_metaspace_oom() { return _metaspace_oom; } static void set_metaspace_oom(bool value) { _metaspace_oom = value; } - static void dump_on(outputStream * const out) PRODUCT_RETURN; - static void dump() { dump_on(tty); } + static void print_on(outputStream * const out) PRODUCT_RETURN; + static void print() { print_on(tty); } static void verify(); - static void print_creation(outputStream* out, Handle loader, ClassLoaderData* cld, TRAPS); static bool unload_list_contains(const void* x); @@ -181,22 +180,8 @@ class ClassLoaderData : public CHeapObj { friend class VMStructs; - private: - class Dependencies VALUE_OBJ_CLASS_SPEC { - objArrayOop _list_head; - void locked_add(objArrayHandle last, - objArrayHandle new_dependency, - Thread* THREAD); - public: - Dependencies() : _list_head(NULL) {} - Dependencies(TRAPS) : _list_head(NULL) { - init(CHECK); - } - void add(Handle dependency, TRAPS); - void init(TRAPS); - void oops_do(OopClosure* f); - }; + private: class ChunkedHandleList VALUE_OBJ_CLASS_SPEC { struct Chunk : public CHeapObj { static const size_t CAPACITY = 32; @@ -219,10 +204,10 @@ // Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock(). // However, multiple threads can execute oops_do concurrently with add. oop* add(oop o); -#ifdef ASSERT - bool contains(oop* p); -#endif + bool contains(oop p); void oops_do(OopClosure* f); + + int count() const; }; friend class ClassLoaderDataGraph; @@ -237,8 +222,6 @@ oop _class_loader; // oop used to uniquely identify a class loader // class loader or a canonical class path - Dependencies _dependencies; // holds dependencies from this class loader - // data to others. Metaspace * volatile _metaspace; // Meta-space where meta-data defined by the // classes in the class loader are allocated. @@ -261,6 +244,8 @@ ChunkedHandleList _handles; // Handles to constant pool arrays, Modules, etc, which // have the same life cycle of the corresponding ClassLoader. + NOT_PRODUCT(volatile int _dependency_count;) // number of class loader dependencies + Klass* volatile _klasses; // The classes defined by the class loader. PackageEntryTable* volatile _packages; // The packages defined by the class loader. ModuleEntryTable* volatile _modules; // The modules defined by the class loader. @@ -289,7 +274,7 @@ void set_next(ClassLoaderData* next) { _next = next; } ClassLoaderData* next() const { return _next; } - ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies); + ClassLoaderData(Handle h_class_loader, bool is_anonymous); ~ClassLoaderData(); // The CLD are not placed in the Heap, so the Card Table or @@ -341,15 +326,7 @@ bool is_anonymous() const { return _is_anonymous; } - static void init_null_class_loader_data() { - assert(_the_null_class_loader_data == NULL, "cannot initialize twice"); - assert(ClassLoaderDataGraph::_head == NULL, "cannot initialize twice"); - - // We explicitly initialize the Dependencies object at a later phase in the initialization - _the_null_class_loader_data = new ClassLoaderData(Handle(), false, Dependencies()); - ClassLoaderDataGraph::_head = _the_null_class_loader_data; - assert(_the_null_class_loader_data->is_the_null_class_loader_data(), "Must be"); - } + static void init_null_class_loader_data(); bool is_the_null_class_loader_data() const { return this == _the_null_class_loader_data; @@ -397,12 +374,11 @@ void set_jmethod_ids(JNIMethodBlock* new_block) { _jmethod_ids = new_block; } void print() { print_on(tty); } - void print_on(outputStream* out) const; + void print_on(outputStream* out) const PRODUCT_RETURN; void print_value() { print_value_on(tty); } void print_value_on(outputStream* out) const; - void dump(outputStream * const out) PRODUCT_RETURN; void verify(); - const char* loader_name(); + const char* loader_name() const; OopHandle add_handle(Handle h); void remove_handle(OopHandle h); @@ -410,8 +386,7 @@ void add_class(Klass* k, bool publicize = true); void remove_class(Klass* k); bool contains_klass(Klass* k); - void record_dependency(const Klass* to, TRAPS); - void init_dependencies(TRAPS); + void record_dependency(const Klass* to); PackageEntryTable* packages() { return _packages; } ModuleEntry* unnamed_module() { return _unnamed_module; } ModuleEntryTable* modules(); @@ -424,8 +399,7 @@ static ClassLoaderData* class_loader_data(oop loader); static ClassLoaderData* class_loader_data_or_null(oop loader); - static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS); - static void print_loader(ClassLoaderData *loader_data, outputStream *out); + static ClassLoaderData* anonymous_class_loader_data(Handle loader); TRACE_DEFINE_TRACE_ID_METHODS; }; --- old/src/hotspot/share/classfile/classLoaderData.inline.hpp 2018-03-02 22:43:27.427649432 -0500 +++ new/src/hotspot/share/classfile/classLoaderData.inline.hpp 2018-03-02 22:43:26.896653113 -0500 @@ -40,7 +40,7 @@ } -inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader, TRAPS) { +inline ClassLoaderData *ClassLoaderDataGraph::find_or_create(Handle loader) { guarantee(loader() != NULL && oopDesc::is_oop(loader()), "Loader must be oop"); // Gets the class loader data out of the java/lang/ClassLoader object, if non-null // it's already in the loader_data, so no need to add @@ -48,7 +48,7 @@ if (loader_data) { return loader_data; } - return ClassLoaderDataGraph::add(loader, false, THREAD); + return ClassLoaderDataGraph::add(loader, false); } size_t ClassLoaderDataGraph::num_instance_classes() { --- old/src/hotspot/share/classfile/dictionary.cpp 2018-03-02 22:43:36.744753131 -0500 +++ new/src/hotspot/share/classfile/dictionary.cpp 2018-03-02 22:43:36.209887977 -0500 @@ -604,13 +604,16 @@ Klass* e = probe->instance_klass(); bool is_defining_class = (loader_data() == e->class_loader_data()); - st->print("%4d: %s%s, loader ", index, is_defining_class ? " " : "^", e->external_name()); - ClassLoaderData* loader_data = e->class_loader_data(); - if (loader_data == NULL) { + st->print("%4d: %s%s", index, is_defining_class ? " " : "^", e->external_name()); + ClassLoaderData* cld = e->class_loader_data(); + if (cld == NULL) { // Shared class not restored yet in shared dictionary - st->print(""); - } else { - loader_data->print_value_on(st); + st->print(", loader data "); + } else if (!loader_data()->is_the_null_class_loader_data()) { + // Class loader output for the dictionary for the null class loader data is + // redundant and obvious. + st->print(", "); + cld->print_value_on(st); } st->cr(); } --- old/src/hotspot/share/classfile/javaClasses.cpp 2018-03-02 22:43:46.267412513 -0500 +++ new/src/hotspot/share/classfile/javaClasses.cpp 2018-03-02 22:43:45.612050987 -0500 @@ -2856,7 +2856,7 @@ module->obj_field_put(name_offset, value); } -ModuleEntry* java_lang_Module::module_entry(oop module, TRAPS) { +ModuleEntry* java_lang_Module::module_entry(oop module) { assert(_module_entry_offset != -1, "Uninitialized module_entry_offset"); assert(module != NULL, "module can't be null"); assert(oopDesc::is_oop(module), "module must be oop"); @@ -2866,8 +2866,8 @@ // If the inject field containing the ModuleEntry* is null then return the // class loader's unnamed module. oop loader = java_lang_Module::loader(module); - Handle h_loader = Handle(THREAD, loader); - ClassLoaderData* loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL); + Handle h_loader = Handle(Thread::current(), loader); + ClassLoaderData* loader_cld = SystemDictionary::register_loader(h_loader); return loader_cld->unnamed_module(); } return module_entry; --- old/src/hotspot/share/classfile/javaClasses.hpp 2018-03-02 22:43:55.785917543 -0500 +++ new/src/hotspot/share/classfile/javaClasses.hpp 2018-03-02 22:43:55.271242810 -0500 @@ -771,7 +771,7 @@ static oop name(oop module); static void set_name(oop module, oop value); - static ModuleEntry* module_entry(oop module, TRAPS); + static ModuleEntry* module_entry(oop module); static void set_module_entry(oop module, ModuleEntry* module_entry); friend class JavaClasses; --- old/src/hotspot/share/classfile/modules.cpp 2018-03-02 22:44:05.280985228 -0500 +++ new/src/hotspot/share/classfile/modules.cpp 2018-03-02 22:44:04.669894552 -0500 @@ -84,27 +84,27 @@ return java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version)); } -static ModuleEntryTable* get_module_entry_table(Handle h_loader, TRAPS) { +static ModuleEntryTable* get_module_entry_table(Handle h_loader) { // This code can be called during start-up, before the classLoader's classLoader data got // created. So, call register_loader() to make sure the classLoader data gets created. - ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL); + ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader); return loader_cld->modules(); } -static PackageEntryTable* get_package_entry_table(Handle h_loader, TRAPS) { +static PackageEntryTable* get_package_entry_table(Handle h_loader) { // This code can be called during start-up, before the classLoader's classLoader data got // created. So, call register_loader() to make sure the classLoader data gets created. - ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL); + ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader); return loader_cld->packages(); } static ModuleEntry* get_module_entry(jobject module, TRAPS) { - Handle module_h(THREAD, JNIHandles::resolve(module)); - if (!java_lang_Module::is_instance(module_h())) { + oop m = JNIHandles::resolve(module); + if (!java_lang_Module::is_instance(m)) { THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "module is not an instance of type java.lang.Module"); } - return java_lang_Module::module_entry(module_h(), CHECK_NULL); + return java_lang_Module::module_entry(m); } static PackageEntry* get_package_entry(ModuleEntry* module_entry, const char* package_name, TRAPS) { @@ -123,7 +123,7 @@ ResourceMark rm(THREAD); if (Modules::verify_package_name(package->as_C_string())) { PackageEntryTable* const package_entry_table = - get_package_entry_table(h_loader, CHECK_NULL); + get_package_entry_table(h_loader); assert(package_entry_table != NULL, "Unexpected null package entry table"); return package_entry_table->lookup_only(package); } @@ -185,7 +185,7 @@ Handle h_loader(THREAD, loader); // Ensure the boot loader's PackageEntryTable has been created - PackageEntryTable* package_table = get_package_entry_table(h_loader, CHECK); + PackageEntryTable* package_table = get_package_entry_table(h_loader); assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table"); // Ensure java.base's ModuleEntry has been created @@ -345,7 +345,7 @@ pkg_list->append(pkg_symbol); } - ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK); + ModuleEntryTable* module_table = get_module_entry_table(h_loader); assert(module_table != NULL, "module entry table shouldn't be null"); // Create symbol* entry for module name. @@ -381,7 +381,7 @@ MutexLocker ml(Module_lock, THREAD); if (num_packages > 0) { - package_table = get_package_entry_table(h_loader, CHECK); + package_table = get_package_entry_table(h_loader); assert(package_table != NULL, "Missing package_table"); // Check that none of the packages exist in the class loader's package table. --- old/src/hotspot/share/classfile/systemDictionary.cpp 2018-03-02 22:44:14.894991303 -0500 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2018-03-02 22:44:14.253614191 -0500 @@ -149,9 +149,9 @@ CDS_ONLY(SystemDictionaryShared::initialize(CHECK);) } -ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) { +ClassLoaderData* SystemDictionary::register_loader(Handle class_loader) { if (class_loader() == NULL) return ClassLoaderData::the_null_class_loader_data(); - return ClassLoaderDataGraph::find_or_create(class_loader, THREAD); + return ClassLoaderDataGraph::find_or_create(class_loader); } // ---------------------------------------------------------------------------- @@ -663,7 +663,7 @@ // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); - ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); + ClassLoaderData* loader_data = register_loader(class_loader); Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(name); @@ -988,7 +988,7 @@ // Create a new CLD for anonymous class, that uses the same class loader // as the host_klass guarantee(host_klass->class_loader() == class_loader(), "should be the same"); - loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL); + loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader); } else { loader_data = ClassLoaderData::class_loader_data(class_loader()); } @@ -1075,7 +1075,7 @@ DoObjectLock = false; } - ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL); + ClassLoaderData* loader_data = register_loader(class_loader); // Make sure we are synchronized on the class loader before we proceed Handle lockObject = compute_loader_lock_object(class_loader, THREAD); @@ -2513,11 +2513,10 @@ } (*appendix_result) = Handle(THREAD, appendix); // the target is stored in the cpCache and if a reference to this - // MethodName is dropped we need a way to make sure the + // MemberName is dropped we need a way to make sure the // class_loader containing this method is kept alive. - // FIXME: the appendix might also preserve this dependency. ClassLoaderData* this_key = accessing_klass->class_loader_data(); - this_key->record_dependency(m->method_holder(), CHECK_NULL); // Can throw OOM + this_key->record_dependency(m->method_holder()); return methodHandle(THREAD, m); } } --- old/src/hotspot/share/classfile/systemDictionary.hpp 2018-03-02 22:44:25.317541506 -0500 +++ new/src/hotspot/share/classfile/systemDictionary.hpp 2018-03-02 22:44:24.718595013 -0500 @@ -493,7 +493,7 @@ static void compute_java_loaders(TRAPS); // Register a new class loader - static ClassLoaderData* register_loader(Handle class_loader, TRAPS); + static ClassLoaderData* register_loader(Handle class_loader); protected: // Mirrors for primitive classes (created eagerly) static oop check_mirror(oop m) { --- old/src/hotspot/share/classfile/systemDictionaryShared.cpp 2018-03-02 22:44:34.763187490 -0500 +++ new/src/hotspot/share/classfile/systemDictionaryShared.cpp 2018-03-02 22:44:34.130860947 -0500 @@ -497,7 +497,7 @@ // Fix for 4474172; see evaluation for more details class_loader = Handle( THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); - ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); + ClassLoaderData *loader_data = register_loader(class_loader); Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(name); --- old/src/hotspot/share/memory/metaspace.cpp 2018-03-02 22:44:44.229532513 -0500 +++ new/src/hotspot/share/memory/metaspace.cpp 2018-03-02 22:44:43.529182116 -0500 @@ -3994,7 +3994,7 @@ if (log.is_debug()) { if (loader_data->metaspace_or_null() != NULL) { LogStream ls(log.debug()); - loader_data->dump(&ls); + loader_data->print_value_on(&ls); } } LogStream ls(log.info()); --- old/src/hotspot/share/memory/universe.cpp 2018-03-02 22:44:54.604734077 -0500 +++ new/src/hotspot/share/memory/universe.cpp 2018-03-02 22:44:53.584038365 -0500 @@ -446,10 +446,6 @@ assert(i == _fullgc_alot_dummy_array->length(), "just checking"); } #endif - - // Initialize dependency array for null class loader - ClassLoaderData::the_null_class_loader_data()->init_dependencies(CHECK); - } void Universe::initialize_basic_type_mirrors(TRAPS) { --- old/src/hotspot/share/oops/constantPool.cpp 2018-03-02 22:45:04.551798562 -0500 +++ new/src/hotspot/share/oops/constantPool.cpp 2018-03-02 22:45:03.767128976 -0500 @@ -493,7 +493,7 @@ // Make this class loader depend upon the class loader owning the class reference ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data(); - this_key->record_dependency(k, CHECK_NULL); // Can throw OOM + this_key->record_dependency(k); // logging for class+resolve. if (log_is_enabled(Debug, class, resolve)){ --- old/src/hotspot/share/oops/instanceKlass.cpp 2018-03-02 22:45:15.247857181 -0500 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2018-03-02 22:45:14.269468280 -0500 @@ -184,13 +184,6 @@ return NULL; } - assert(ik != NULL, "invariant"); - - const bool publicize = !parser.is_internal(); - - // Add all classes to our internal class loader list here, - // including classes in the bootstrap (NULL) class loader. - loader_data->add_class(ik, publicize); return ik; } --- old/src/hotspot/share/oops/method.cpp 2018-03-02 22:45:26.986724586 -0500 +++ new/src/hotspot/share/oops/method.cpp 2018-03-02 22:45:26.326283165 -0500 @@ -2190,8 +2190,8 @@ } #ifndef PRODUCT -void Method::print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) { - out->print_cr("jni_method_id count = %d", loader_data->jmethod_ids()->count_methods()); +void Method::print_jmethod_ids(const ClassLoaderData* loader_data, outputStream* out) { + out->print(" jni_method_id count = %d", loader_data->jmethod_ids()->count_methods()); } #endif // PRODUCT --- old/src/hotspot/share/oops/method.hpp 2018-03-02 22:45:37.978061671 -0500 +++ new/src/hotspot/share/oops/method.hpp 2018-03-02 22:45:37.341134779 -0500 @@ -814,7 +814,7 @@ // Clear methods static void clear_jmethod_ids(ClassLoaderData* loader_data); - static void print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN; + static void print_jmethod_ids(const ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN; // Get this method's jmethodID -- allocate if it doesn't exist jmethodID jmethod_id() { return method_holder()->get_jmethod_id(this); } --- old/src/hotspot/share/runtime/java.cpp 2018-03-02 22:45:49.603054352 -0500 +++ new/src/hotspot/share/runtime/java.cpp 2018-03-02 22:45:48.834112612 -0500 @@ -341,7 +341,9 @@ } if (PrintSystemDictionaryAtExit) { + ResourceMark rm; SystemDictionary::print(); + ClassLoaderDataGraph::print(); } if (LogTouchedMethods && PrintTouchedMethodsAtExit) { @@ -483,7 +485,7 @@ Universe::print_on(&ls_info); if (log.is_trace()) { LogStream ls_trace(log.trace()); - ClassLoaderDataGraph::dump_on(&ls_trace); + ClassLoaderDataGraph::print_on(&ls_trace); } } --- old/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java 2018-03-02 22:46:03.177952338 -0500 +++ new/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java 2018-03-02 22:46:02.434532278 -0500 @@ -81,7 +81,7 @@ output = CDSTestUtils.executeAndLog(pb, "jcmd-systemdictionary-verbose"); try { output.shouldContain("Shared Dictionary"); - output.shouldContain("Dictionary for class loader 0x"); + output.shouldContain("Dictionary for loader data: 0x"); output.shouldContain("^java.lang.String"); } catch (RuntimeException e) { output.shouldContain("Unknown diagnostic command"); --- old/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java 2018-03-02 22:46:12.752672940 -0500 +++ new/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java 2018-03-02 22:46:12.252785667 -0500 @@ -71,7 +71,7 @@ pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.systemdictionary", "-verbose"}); output = CDSTestUtils.executeAndLog(pb, "jcmd-systemdictionary"); try { - output.shouldContain("Dictionary for class loader 0x"); + output.shouldContain("Dictionary for loader data: 0x"); output.shouldContain("^java.lang.String"); } catch (RuntimeException e) { output.shouldContain("Unknown diagnostic command"); --- old/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java 2018-03-02 22:46:22.164528946 -0500 +++ new/test/hotspot/jtreg/runtime/logging/ClassLoadUnloadTest.java 2018-03-02 22:46:21.679425437 -0500 @@ -124,7 +124,7 @@ // -Xlog:class+loader+data=trace pb = exec("-Xlog:class+loader+data=trace"); - checkFor("[class,loader,data]", "create class loader data"); + checkFor("[class,loader,data]", "create loader data"); } }