< 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 >