< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com

*** 1,7 **** /* ! * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 124,143 **** java_lang_String::as_utf8_string(cl_name_and_id); assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id"); _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id); } ! ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) : _metaspace(NULL), _metaspace_lock(new Mutex(Mutex::leaf+1, "Metaspace allocation lock", true, Mutex::_safepoint_check_never)), ! _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous), _modified_oops(true), _accumulated_modified_oops(false), // An unsafe anonymous class loader data doesn't have anything to keep // it from being unloaded during parsing of the unsafe anonymous class. // The null-class-loader should always be kept alive. ! _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0), _claim(0), _handles(), _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL), _jmethod_ids(NULL), _deallocate_list(NULL), --- 124,143 ---- java_lang_String::as_utf8_string(cl_name_and_id); assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id"); _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id); } ! ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder) : _metaspace(NULL), _metaspace_lock(new Mutex(Mutex::leaf+1, "Metaspace allocation lock", true, Mutex::_safepoint_check_never)), ! _unloading(false), _has_class_mirror_holder(has_class_mirror_holder), _modified_oops(true), _accumulated_modified_oops(false), // An unsafe anonymous class loader data doesn't have anything to keep // it from being unloaded during parsing of the unsafe anonymous class. // The null-class-loader should always be kept alive. ! _keep_alive((has_class_mirror_holder || h_class_loader.is_null()) ? 1 : 0), _claim(0), _handles(), _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL), _jmethod_ids(NULL), _deallocate_list(NULL),
*** 148,164 **** _class_loader = _handles.add(h_class_loader()); _class_loader_klass = h_class_loader->klass(); initialize_name(h_class_loader); } ! if (!is_unsafe_anonymous) { ! // The holder is initialized later for unsafe anonymous classes, and before calling anything ! // that call class_loader(). initialize_holder(h_class_loader); ! // A ClassLoaderData created solely for an unsafe anonymous class should never have a ! // ModuleEntryTable or PackageEntryTable created for it. The defining package // and module for an unsafe anonymous class will be found in its host class. _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); if (h_class_loader.is_null()) { // Create unnamed module for boot loader _unnamed_module = ModuleEntry::create_boot_unnamed_module(this); --- 148,164 ---- _class_loader = _handles.add(h_class_loader()); _class_loader_klass = h_class_loader->klass(); initialize_name(h_class_loader); } ! if (!has_class_mirror_holder) { ! // The holder is initialized later for weak hidden and unsafe anonymous classes, ! // and before calling anything that call class_loader(). initialize_holder(h_class_loader); ! // A ClassLoaderData created solely for an weak hidden or unsafe anonymous class should ! // never have a ModuleEntryTable or PackageEntryTable created for it. The defining package // and module for an unsafe anonymous class will be found in its host class. _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); if (h_class_loader.is_null()) { // Create unnamed module for boot loader _unnamed_module = ModuleEntry::create_boot_unnamed_module(this);
*** 289,312 **** return true; } } } ! // Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive // while the class is being parsed, and if the class appears on the module fixup list. ! // Due to the uniqueness that no other class shares the unsafe anonymous class' name or ! // ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while // it is being defined, therefore _keep_alive is not volatile or atomic. void ClassLoaderData::inc_keep_alive() { ! if (is_unsafe_anonymous()) { assert(_keep_alive > 0, "Invalid keep alive increment count"); _keep_alive++; } } void ClassLoaderData::dec_keep_alive() { ! if (is_unsafe_anonymous()) { assert(_keep_alive > 0, "Invalid keep alive decrement count"); _keep_alive--; } } --- 289,312 ---- return true; } } } ! // Weak hidden and unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive // while the class is being parsed, and if the class appears on the module fixup list. ! // Due to the uniqueness that no other class shares the hidden or unsafe anonymous class' name or ! // ClassLoaderData, no other non-GC thread has knowledge of the hidden or unsafe anonymous class while // it is being defined, therefore _keep_alive is not volatile or atomic. void ClassLoaderData::inc_keep_alive() { ! if (has_class_mirror_holder()) { assert(_keep_alive > 0, "Invalid keep alive increment count"); _keep_alive++; } } void ClassLoaderData::dec_keep_alive() { ! if (has_class_mirror_holder()) { assert(_keep_alive > 0, "Invalid keep alive decrement count"); _keep_alive--; } }
*** 408,432 **** ClassLoaderData * const from_cld = this; ClassLoaderData * const to_cld = k->class_loader_data(); // Do not need to record dependency if the dependency is to a class whose // class loader data is never freed. (i.e. the dependency's class loader ! // is one of the three builtin class loaders and the dependency is not ! // unsafe anonymous.) if (to_cld->is_permanent_class_loader_data()) { return; } oop to; ! if (to_cld->is_unsafe_anonymous()) { ! // Just return if an unsafe anonymous class is attempting to record a dependency ! // to itself. (Note that every unsafe anonymous class has its own unique class // loader data.) if (to_cld == from_cld) { return; } ! // Unsafe anonymous class dependencies are through the mirror. to = k->java_mirror(); } else { to = to_cld->class_loader(); oop from = from_cld->class_loader(); --- 408,432 ---- ClassLoaderData * const from_cld = this; ClassLoaderData * const to_cld = k->class_loader_data(); // Do not need to record dependency if the dependency is to a class whose // class loader data is never freed. (i.e. the dependency's class loader ! // is one of the three builtin class loaders and the dependency's class ! // loader data has a ClassLoader holder, not a Class holder.) if (to_cld->is_permanent_class_loader_data()) { return; } oop to; ! if (to_cld->has_class_mirror_holder()) { ! // Just return if a weak hidden or unsafe anonymous class is attempting to record a dependency ! // to itself. (Note that every weak hidden or unsafe anonymous class has its own unique class // loader data.) if (to_cld == from_cld) { return; } ! // Hidden and unsafe anonymous class dependencies are through the mirror. to = k->java_mirror(); } else { to = to_cld->class_loader(); oop from = from_cld->class_loader();
*** 570,580 **** const int _boot_loader_dictionary_size = 1009; const int _default_loader_dictionary_size = 107; Dictionary* ClassLoaderData::create_dictionary() { ! assert(!is_unsafe_anonymous(), "unsafe anonymous class loader data do not have a dictionary"); int size; bool resizable = false; if (_the_null_class_loader_data == NULL) { size = _boot_loader_dictionary_size; resizable = true; --- 570,580 ---- const int _boot_loader_dictionary_size = 1009; const int _default_loader_dictionary_size = 107; Dictionary* ClassLoaderData::create_dictionary() { ! assert(!has_class_mirror_holder(), "class mirror holder cld does not have a dictionary"); int size; bool resizable = false; if (_the_null_class_loader_data == NULL) { size = _boot_loader_dictionary_size; resizable = true;
*** 616,626 **** } } // Unloading support bool ClassLoaderData::is_alive() const { ! bool alive = keep_alive() // null class loader and incomplete unsafe anonymous klasses. || (_holder.peek() != NULL); // and not cleaned by the GC weak handle processing. return alive; } --- 616,626 ---- } } // Unloading support bool ClassLoaderData::is_alive() const { ! bool alive = keep_alive() // null class loader and incomplete weak hidden or unsafe anonymous klasses. || (_holder.peek() != NULL); // and not cleaned by the GC weak handle processing. return alive; }
*** 714,750 **** } } // Returns true if this class loader data is for the app class loader // or a user defined system class loader. (Note that the class loader ! // data may be unsafe anonymous.) bool ClassLoaderData::is_system_class_loader_data() const { return SystemDictionary::is_system_class_loader(class_loader()); } // Returns true if this class loader data is for the platform class loader. ! // (Note that the class loader data may be unsafe anonymous.) bool ClassLoaderData::is_platform_class_loader_data() const { return SystemDictionary::is_platform_class_loader(class_loader()); } // Returns true if the class loader for this class loader data is one of // the 3 builtin (boot application/system or platform) class loaders, // including a user-defined system class loader. Note that if the class ! // loader data is for an unsafe anonymous class then it may get freed by a GC ! // even if its class loader is one of these loaders. bool ClassLoaderData::is_builtin_class_loader_data() const { return (is_boot_class_loader_data() || SystemDictionary::is_system_class_loader(class_loader()) || SystemDictionary::is_platform_class_loader(class_loader())); } // Returns true if this class loader data is a class loader data // that is not ever freed by a GC. It must be the CLD for one of the builtin ! // class loaders and not the CLD for an unsafe anonymous class. bool ClassLoaderData::is_permanent_class_loader_data() const { ! return is_builtin_class_loader_data() && !is_unsafe_anonymous(); } ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() { // If the metaspace has not been allocated, create a new one. Might want // to create smaller arena for Reflection class loaders also. --- 714,750 ---- } } // Returns true if this class loader data is for the app class loader // or a user defined system class loader. (Note that the class loader ! // data may have a Class holder.) bool ClassLoaderData::is_system_class_loader_data() const { return SystemDictionary::is_system_class_loader(class_loader()); } // Returns true if this class loader data is for the platform class loader. ! // (Note that the class loader data may have a Class holder.) bool ClassLoaderData::is_platform_class_loader_data() const { return SystemDictionary::is_platform_class_loader(class_loader()); } // Returns true if the class loader for this class loader data is one of // the 3 builtin (boot application/system or platform) class loaders, // including a user-defined system class loader. Note that if the class ! // loader data is for a weak hidden or unsafe anonymous class then it may ! // get freed by a GC even if its class loader is one of these loaders. bool ClassLoaderData::is_builtin_class_loader_data() const { return (is_boot_class_loader_data() || SystemDictionary::is_system_class_loader(class_loader()) || SystemDictionary::is_platform_class_loader(class_loader())); } // Returns true if this class loader data is a class loader data // that is not ever freed by a GC. It must be the CLD for one of the builtin ! // class loaders and not the CLD for a weak hidden or unsafe anonymous class. bool ClassLoaderData::is_permanent_class_loader_data() const { ! return is_builtin_class_loader_data() && !has_class_mirror_holder(); } ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() { // If the metaspace has not been allocated, create a new one. Might want // to create smaller arena for Reflection class loaders also.
*** 757,768 **** // Check if _metaspace got allocated while we were waiting for this lock. if ((metaspace = _metaspace) == NULL) { if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType); ! } else if (is_unsafe_anonymous()) { ! metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::UnsafeAnonymousMetaspaceType); } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); } else { metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::StandardMetaspaceType); } --- 757,768 ---- // Check if _metaspace got allocated while we were waiting for this lock. if ((metaspace = _metaspace) == NULL) { if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType); ! } else if (has_class_mirror_holder()) { ! metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ClassMirrorHolderMetaspaceType); } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); } else { metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::StandardMetaspaceType); }
*** 875,886 **** remove_class(ik); } } } ! // These CLDs are to contain unsafe anonymous classes used for JSR292 ! ClassLoaderData* ClassLoaderData::unsafe_anonymous_class_loader_data(Handle loader) { // Add a new class loader data to the graph. return ClassLoaderDataGraph::add(loader, true); } // Caller needs ResourceMark --- 875,886 ---- remove_class(ik); } } } ! // These CLDs are to contain weak hidden or unsafe anonymous classes used for JSR292 ! ClassLoaderData* ClassLoaderData::has_class_mirror_holder_cld(Handle loader) { // Add a new class loader data to the graph. return ClassLoaderDataGraph::add(loader, true); } // Caller needs ResourceMark
*** 918,939 **** class_loader()->print_value_on(out); // includes loader_name_and_id() and address of class loader instance } else { // loader data: 0xsomeaddr of 'bootstrap' out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id()); } ! if (is_unsafe_anonymous()) { ! out->print(" unsafe anonymous"); } } void ClassLoaderData::print_value() const { print_value_on(tty); } #ifndef PRODUCT void ClassLoaderData::print_on(outputStream* out) const { out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id()); ! if (is_unsafe_anonymous()) out->print(" unsafe 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) { --- 918,939 ---- class_loader()->print_value_on(out); // includes loader_name_and_id() and address of class loader instance } else { // loader data: 0xsomeaddr of 'bootstrap' out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id()); } ! if (_has_class_mirror_holder) { ! out->print(" has a class holder"); } } void ClassLoaderData::print_value() const { print_value_on(tty); } #ifndef PRODUCT void ClassLoaderData::print_on(outputStream* out) const { out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id()); ! if (has_class_mirror_holder()) out->print(" has a class holder"); if (claimed()) out->print(" claimed"); if (is_unloading()) out->print(" unloading"); out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); if (_jmethod_ids != NULL) {
*** 949,960 **** void ClassLoaderData::verify() { assert_locked_or_safepoint(_metaspace_lock); oop cl = class_loader(); ! guarantee(this == class_loader_data(cl) || is_unsafe_anonymous(), "Must be the same"); ! guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_unsafe_anonymous(), "must be"); // Verify the integrity of the allocated space. if (metaspace_or_null() != NULL) { metaspace_or_null()->verify(); } --- 949,960 ---- void ClassLoaderData::verify() { assert_locked_or_safepoint(_metaspace_lock); oop cl = class_loader(); ! guarantee(this == class_loader_data(cl) || has_class_mirror_holder(), "Must be the same"); ! guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || has_class_mirror_holder(), "must be"); // Verify the integrity of the allocated space. if (metaspace_or_null() != NULL) { metaspace_or_null()->verify(); }
< prev index next >