8209301: JVM rename is_anonymous, host_klass to unsafe specific terminology ahead of Unsafe.defineAnonymousClass deprecation

Clean up VM anonymous class terminology.

Reviewed-by: coleenp, dholmes, mchung
This commit is contained in:
Lois Foltan 2018-08-20 08:25:57 -04:00
parent 6ccb60937c
commit 75ed173e15
64 changed files with 359 additions and 354 deletions

View file

@ -1006,7 +1006,7 @@ bool AOTCodeHeap::reconcile_dynamic_klass(AOTCompiledMethod *caller, InstanceKla
InstanceKlass* dyno = InstanceKlass::cast(dyno_klass); InstanceKlass* dyno = InstanceKlass::cast(dyno_klass);
if (!dyno->is_anonymous()) { if (!dyno->is_unsafe_anonymous()) {
if (_klasses_got[dyno_data->_got_index] != dyno) { if (_klasses_got[dyno_data->_got_index] != dyno) {
// compile-time class different from runtime class, fail and deoptimize // compile-time class different from runtime class, fail and deoptimize
sweep_dependent_methods(holder_data); sweep_dependent_methods(holder_data);

View file

@ -42,7 +42,7 @@ GrowableArray<AOTLib*>* AOTLoader::_libraries = new(ResourceObj::C_HEAP, mtCode)
#define FOR_ALL_AOT_LIBRARIES(lib) for (GrowableArrayIterator<AOTLib*> lib = libraries()->begin(); lib != libraries()->end(); ++lib) #define FOR_ALL_AOT_LIBRARIES(lib) for (GrowableArrayIterator<AOTLib*> lib = libraries()->begin(); lib != libraries()->end(); ++lib)
void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) { void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) {
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
// don't even bother // don't even bother
return; return;
} }
@ -54,7 +54,7 @@ void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) {
} }
uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) { uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) {
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
// don't even bother // don't even bother
return 0; return 0;
} }

View file

@ -1844,7 +1844,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
// invoke-special-super // invoke-special-super
if (bc_raw == Bytecodes::_invokespecial && !target->is_object_initializer()) { if (bc_raw == Bytecodes::_invokespecial && !target->is_object_initializer()) {
ciInstanceKlass* sender_klass = ciInstanceKlass* sender_klass =
calling_klass->is_anonymous() ? calling_klass->host_klass() : calling_klass->is_unsafe_anonymous() ? calling_klass->unsafe_anonymous_host() :
calling_klass; calling_klass;
if (sender_klass->is_interface()) { if (sender_klass->is_interface()) {
int index = state()->stack_size() - (target->arg_size_no_receiver() + 1); int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);

View file

@ -222,9 +222,9 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
// Even if general trusting is disabled, trust system-built closures in these packages. // Even if general trusting is disabled, trust system-built closures in these packages.
if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke")) if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
return true; return true;
// Trust VM anonymous classes. They are private API (sun.misc.Unsafe) and can't be serialized, // Trust VM unsafe anonymous classes. They are private API (jdk.internal.misc.Unsafe)
// so there is no hacking of finals going on with them. // and can't be serialized, so there is no hacking of finals going on with them.
if (holder->is_anonymous()) if (holder->is_unsafe_anonymous())
return true; return true;
// Trust final fields in all boxed classes // Trust final fields in all boxed classes
if (holder->is_box_klass()) if (holder->is_box_klass())

View file

@ -62,7 +62,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
_nonstatic_field_size = ik->nonstatic_field_size(); _nonstatic_field_size = ik->nonstatic_field_size();
_has_nonstatic_fields = ik->has_nonstatic_fields(); _has_nonstatic_fields = ik->has_nonstatic_fields();
_has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods(); _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods();
_is_anonymous = ik->is_anonymous(); _is_unsafe_anonymous = ik->is_unsafe_anonymous();
_nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
_has_injected_fields = -1; _has_injected_fields = -1;
_implementor = NULL; // we will fill these lazily _implementor = NULL; // we will fill these lazily
@ -73,13 +73,13 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
// InstanceKlass are created for both weak and strong metadata. Ensuring this metadata // InstanceKlass are created for both weak and strong metadata. Ensuring this metadata
// alive covers the cases where there are weak roots without performance cost. // alive covers the cases where there are weak roots without performance cost.
oop holder = ik->holder_phantom(); oop holder = ik->holder_phantom();
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
// Though ciInstanceKlass records class loader oop, it's not enough to keep // Though ciInstanceKlass records class loader oop, it's not enough to keep
// VM anonymous classes alive (loader == NULL). Klass holder should be used instead. // VM unsafe anonymous classes alive (loader == NULL). Klass holder should
// It is enough to record a ciObject, since cached elements are never removed // be used instead. It is enough to record a ciObject, since cached elements are never removed
// during ciObjectFactory lifetime. ciObjectFactory itself is created for // during ciObjectFactory lifetime. ciObjectFactory itself is created for
// every compilation and lives for the whole duration of the compilation. // every compilation and lives for the whole duration of the compilation.
assert(holder != NULL, "holder of anonymous class is the mirror which is never null"); assert(holder != NULL, "holder of unsafe anonymous class is the mirror which is never null");
(void)CURRENT_ENV->get_object(holder); (void)CURRENT_ENV->get_object(holder);
} }
@ -122,7 +122,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
_has_nonstatic_fields = false; _has_nonstatic_fields = false;
_nonstatic_fields = NULL; _nonstatic_fields = NULL;
_has_injected_fields = -1; _has_injected_fields = -1;
_is_anonymous = false; _is_unsafe_anonymous = false;
_loader = loader; _loader = loader;
_protection_domain = protection_domain; _protection_domain = protection_domain;
_is_shared = false; _is_shared = false;
@ -615,12 +615,12 @@ ciInstanceKlass* ciInstanceKlass::implementor() {
return impl; return impl;
} }
ciInstanceKlass* ciInstanceKlass::host_klass() { ciInstanceKlass* ciInstanceKlass::unsafe_anonymous_host() {
assert(is_loaded(), "must be loaded"); assert(is_loaded(), "must be loaded");
if (is_anonymous()) { if (is_unsafe_anonymous()) {
VM_ENTRY_MARK VM_ENTRY_MARK
Klass* host_klass = get_instanceKlass()->host_klass(); Klass* unsafe_anonymous_host = get_instanceKlass()->unsafe_anonymous_host();
return CURRENT_ENV->get_instance_klass(host_klass); return CURRENT_ENV->get_instance_klass(unsafe_anonymous_host);
} }
return NULL; return NULL;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,7 @@ private:
bool _has_subklass; bool _has_subklass;
bool _has_nonstatic_fields; bool _has_nonstatic_fields;
bool _has_nonstatic_concrete_methods; bool _has_nonstatic_concrete_methods;
bool _is_anonymous; bool _is_unsafe_anonymous;
ciFlags _flags; ciFlags _flags;
jint _nonstatic_field_size; jint _nonstatic_field_size;
@ -179,8 +179,8 @@ public:
return _has_nonstatic_concrete_methods; return _has_nonstatic_concrete_methods;
} }
bool is_anonymous() { bool is_unsafe_anonymous() {
return _is_anonymous; return _is_unsafe_anonymous;
} }
ciInstanceKlass* get_canonical_holder(int offset); ciInstanceKlass* get_canonical_holder(int offset);
@ -260,7 +260,7 @@ public:
return NULL; return NULL;
} }
ciInstanceKlass* host_klass(); ciInstanceKlass* unsafe_anonymous_host();
bool can_be_instantiated() { bool can_be_instantiated() {
assert(is_loaded(), "must be loaded"); assert(is_loaded(), "must be loaded");

View file

@ -2091,7 +2091,7 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
// Privileged code can use all annotations. Other code silently drops some. // Privileged code can use all annotations. Other code silently drops some.
const bool privileged = loader_data->is_the_null_class_loader_data() || const bool privileged = loader_data->is_the_null_class_loader_data() ||
loader_data->is_platform_class_loader_data() || loader_data->is_platform_class_loader_data() ||
loader_data->is_anonymous(); loader_data->is_unsafe_anonymous();
switch (sid) { switch (sid) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): { case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): {
if (_location != _in_method) break; // only allow for methods if (_location != _in_method) break; // only allow for methods
@ -5591,7 +5591,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
ik->set_this_class_index(_this_class_index); ik->set_this_class_index(_this_class_index);
if (is_anonymous()) { if (is_unsafe_anonymous()) {
// _this_class_index is a CONSTANT_Class entry that refers to this // _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 // anonymous class itself. If this class needs to refer to its own methods or
// fields, it would use a CONSTANT_MethodRef, etc, which would reference // fields, it would use a CONSTANT_MethodRef, etc, which would reference
@ -5607,9 +5607,9 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
ik->set_has_nonstatic_concrete_methods(_has_nonstatic_concrete_methods); ik->set_has_nonstatic_concrete_methods(_has_nonstatic_concrete_methods);
ik->set_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods); ik->set_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods);
if (_host_klass != NULL) { if (_unsafe_anonymous_host != NULL) {
assert (ik->is_anonymous(), "should be the same"); assert (ik->is_unsafe_anonymous(), "should be the same");
ik->set_host_klass(_host_klass); ik->set_unsafe_anonymous_host(_unsafe_anonymous_host);
} }
// Set PackageEntry for this_klass // Set PackageEntry for this_klass
@ -5760,15 +5760,15 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
debug_only(ik->verify();) debug_only(ik->verify();)
} }
// For an anonymous class that is in the unnamed package, move it to its host class's // For an unsafe anonymous class that is in the unnamed package, move it to its host class's
// package by prepending its host class's package name to its class name and setting // package by prepending its host class's package name to its class name and setting
// its _class_name field. // its _class_name field.
void ClassFileParser::prepend_host_package_name(const InstanceKlass* host_klass, TRAPS) { void ClassFileParser::prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
assert(strrchr(_class_name->as_C_string(), '/') == NULL, assert(strrchr(_class_name->as_C_string(), '/') == NULL,
"Anonymous class should not be in a package"); "Unsafe anonymous class should not be in a package");
const char* host_pkg_name = const char* host_pkg_name =
ClassLoader::package_from_name(host_klass->name()->as_C_string(), NULL); ClassLoader::package_from_name(unsafe_anonymous_host->name()->as_C_string(), NULL);
if (host_pkg_name != NULL) { if (host_pkg_name != NULL) {
size_t host_pkg_len = strlen(host_pkg_name); size_t host_pkg_len = strlen(host_pkg_name);
@ -5778,7 +5778,7 @@ void ClassFileParser::prepend_host_package_name(const InstanceKlass* host_klass,
// Copy host package name and trailing /. // Copy host package name and trailing /.
strncpy(new_anon_name, host_pkg_name, host_pkg_len); strncpy(new_anon_name, host_pkg_name, host_pkg_len);
new_anon_name[host_pkg_len] = '/'; new_anon_name[host_pkg_len] = '/';
// Append anonymous class name. The anonymous class name can contain odd // Append unsafe anonymous class name. The unsafe anonymous class name can contain odd
// characters. So, do a strncpy instead of using sprintf("%s..."). // characters. So, do a strncpy instead of using sprintf("%s...").
strncpy(new_anon_name + host_pkg_len + 1, (char *)_class_name->base(), class_name_len); strncpy(new_anon_name + host_pkg_len + 1, (char *)_class_name->base(), class_name_len);
@ -5793,19 +5793,19 @@ void ClassFileParser::prepend_host_package_name(const InstanceKlass* host_klass,
// nothing. If the anonymous class is in the unnamed package then move it to its // nothing. If the anonymous class is in the unnamed package then move it to its
// host's package. If the classes are in different packages then throw an IAE // host's package. If the classes are in different packages then throw an IAE
// exception. // exception.
void ClassFileParser::fix_anonymous_class_name(TRAPS) { void ClassFileParser::fix_unsafe_anonymous_class_name(TRAPS) {
assert(_host_klass != NULL, "Expected an anonymous class"); assert(_unsafe_anonymous_host != NULL, "Expected an unsafe anonymous class");
const jbyte* anon_last_slash = UTF8::strrchr(_class_name->base(), const jbyte* anon_last_slash = UTF8::strrchr(_class_name->base(),
_class_name->utf8_length(), '/'); _class_name->utf8_length(), '/');
if (anon_last_slash == NULL) { // Unnamed package if (anon_last_slash == NULL) { // Unnamed package
prepend_host_package_name(_host_klass, CHECK); prepend_host_package_name(_unsafe_anonymous_host, CHECK);
} else { } else {
if (!_host_klass->is_same_class_package(_host_klass->class_loader(), _class_name)) { if (!_unsafe_anonymous_host->is_same_class_package(_unsafe_anonymous_host->class_loader(), _class_name)) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
err_msg("Host class %s and anonymous class %s are in different packages", err_msg("Host class %s and anonymous class %s are in different packages",
_host_klass->name()->as_C_string(), _class_name->as_C_string())); _unsafe_anonymous_host->name()->as_C_string(), _class_name->as_C_string()));
} }
} }
} }
@ -5825,14 +5825,14 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
Symbol* name, Symbol* name,
ClassLoaderData* loader_data, ClassLoaderData* loader_data,
Handle protection_domain, Handle protection_domain,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
Publicity pub_level, Publicity pub_level,
TRAPS) : TRAPS) :
_stream(stream), _stream(stream),
_requested_name(name), _requested_name(name),
_loader_data(loader_data), _loader_data(loader_data),
_host_klass(host_klass), _unsafe_anonymous_host(unsafe_anonymous_host),
_cp_patches(cp_patches), _cp_patches(cp_patches),
_num_patched_klasses(0), _num_patched_klasses(0),
_max_num_patched_klasses(0), _max_num_patched_klasses(0),
@ -6140,8 +6140,8 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
// if this is an anonymous class fix up its name if it's in the unnamed // if this is an anonymous class fix up its name if it's in the unnamed
// package. Otherwise, throw IAE if it is in a different package than // package. Otherwise, throw IAE if it is in a different package than
// its host class. // its host class.
if (_host_klass != NULL) { if (_unsafe_anonymous_host != NULL) {
fix_anonymous_class_name(CHECK); fix_unsafe_anonymous_class_name(CHECK);
} }
// Verification prevents us from creating names with dots in them, this // Verification prevents us from creating names with dots in them, this
@ -6166,9 +6166,9 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
warning("DumpLoadedClassList and CDS are not supported in exploded build"); warning("DumpLoadedClassList and CDS are not supported in exploded build");
DumpLoadedClassList = NULL; DumpLoadedClassList = NULL;
} else if (SystemDictionaryShared::is_sharing_possible(_loader_data) && } else if (SystemDictionaryShared::is_sharing_possible(_loader_data) &&
_host_klass == NULL) { _unsafe_anonymous_host == NULL) {
// Only dump the classes that can be stored into CDS archive. // Only dump the classes that can be stored into CDS archive.
// Anonymous classes such as generated LambdaForm classes are also not included. // Unsafe anonymous classes such as generated LambdaForm classes are also not included.
oop class_loader = _loader_data->class_loader(); oop class_loader = _loader_data->class_loader();
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
bool skip = false; bool skip = false;

View file

@ -82,7 +82,7 @@ class ClassFileParser {
const Symbol* _requested_name; const Symbol* _requested_name;
Symbol* _class_name; Symbol* _class_name;
mutable ClassLoaderData* _loader_data; mutable ClassLoaderData* _loader_data;
const InstanceKlass* _host_klass; const InstanceKlass* _unsafe_anonymous_host;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries GrowableArray<Handle>* _cp_patches; // overrides for CP entries
int _num_patched_klasses; int _num_patched_klasses;
int _max_num_patched_klasses; int _max_num_patched_klasses;
@ -173,8 +173,8 @@ class ClassFileParser {
ConstantPool* cp, ConstantPool* cp,
TRAPS); TRAPS);
void prepend_host_package_name(const InstanceKlass* host_klass, TRAPS); void prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS);
void fix_anonymous_class_name(TRAPS); void fix_unsafe_anonymous_class_name(TRAPS);
void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS); void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS);
void set_klass(InstanceKlass* instance); void set_klass(InstanceKlass* instance);
@ -501,7 +501,7 @@ class ClassFileParser {
Symbol* name, Symbol* name,
ClassLoaderData* loader_data, ClassLoaderData* loader_data,
Handle protection_domain, Handle protection_domain,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
Publicity pub_level, Publicity pub_level,
TRAPS); TRAPS);
@ -524,10 +524,10 @@ class ClassFileParser {
u2 this_class_index() const { return _this_class_index; } u2 this_class_index() const { return _this_class_index; }
u2 super_class_index() const { return _super_class_index; } u2 super_class_index() const { return _super_class_index; }
bool is_anonymous() const { return _host_klass != NULL; } bool is_unsafe_anonymous() const { return _unsafe_anonymous_host != NULL; }
bool is_interface() const { return _access_flags.is_interface(); } bool is_interface() const { return _access_flags.is_interface(); }
const InstanceKlass* host_klass() const { return _host_klass; } const InstanceKlass* unsafe_anonymous_host() const { return _unsafe_anonymous_host; }
const GrowableArray<Handle>* cp_patches() const { return _cp_patches; } const GrowableArray<Handle>* cp_patches() const { return _cp_patches; }
ClassLoaderData* loader_data() const { return _loader_data; } ClassLoaderData* loader_data() const { return _loader_data; }
const Symbol* class_name() const { return _class_name; } const Symbol* class_name() const { return _class_name; }

View file

@ -1400,7 +1400,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
name, name,
loader_data, loader_data,
protection_domain, protection_domain,
NULL, // host_klass NULL, // unsafe_anonymous_host
NULL, // cp_patches NULL, // cp_patches
THREAD); THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
@ -1443,8 +1443,8 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
assert(DumpSharedSpaces, "sanity"); assert(DumpSharedSpaces, "sanity");
assert(stream != NULL, "sanity"); assert(stream != NULL, "sanity");
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
// We do not archive anonymous classes. // We do not archive unsafe anonymous classes.
return; return;
} }

View file

@ -141,16 +141,16 @@ void ClassLoaderData::initialize_name(Handle class_loader) {
_name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH); _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);
} }
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) : ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :
_metaspace(NULL), _metaspace(NULL),
_metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
Monitor::_safepoint_check_never)), Monitor::_safepoint_check_never)),
_unloading(false), _is_anonymous(is_anonymous), _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous),
_modified_oops(true), _accumulated_modified_oops(false), _modified_oops(true), _accumulated_modified_oops(false),
// An anonymous class loader data doesn't have anything to keep // An unsafe anonymous class loader data doesn't have anything to keep
// it from being unloaded during parsing of the anonymous class. // it from being unloaded during parsing of the unsafe anonymous class.
// The null-class-loader should always be kept alive. // The null-class-loader should always be kept alive.
_keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0), _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0),
_claimed(0), _claimed(0),
_handles(), _handles(),
_klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL), _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL),
@ -164,14 +164,14 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous) :
_class_loader_klass = h_class_loader->klass(); _class_loader_klass = h_class_loader->klass();
} }
if (!is_anonymous) { if (!is_unsafe_anonymous) {
// The holder is initialized later for anonymous classes, and before calling anything // The holder is initialized later for unsafe anonymous classes, and before calling anything
// that call class_loader(). // that call class_loader().
initialize_holder(h_class_loader); initialize_holder(h_class_loader);
// A ClassLoaderData created solely for an anonymous class should never have a // A ClassLoaderData created solely for an unsafe anonymous class should never have a
// ModuleEntryTable or PackageEntryTable created for it. The defining package // ModuleEntryTable or PackageEntryTable created for it. The defining package
// and module for an anonymous class will be found in its host class. // and module for an unsafe anonymous class will be found in its host class.
_packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size);
if (h_class_loader.is_null()) { if (h_class_loader.is_null()) {
// Create unnamed module for boot loader // Create unnamed module for boot loader
@ -287,20 +287,20 @@ bool ClassLoaderData::claim() {
return (int) Atomic::cmpxchg(1, &_claimed, 0) == 0; return (int) Atomic::cmpxchg(1, &_claimed, 0) == 0;
} }
// Anonymous classes have their own ClassLoaderData that is marked to keep alive // 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. // 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 anonymous class' name or // 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 anonymous class while // 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. // it is being defined, therefore _keep_alive is not volatile or atomic.
void ClassLoaderData::inc_keep_alive() { void ClassLoaderData::inc_keep_alive() {
if (is_anonymous()) { if (is_unsafe_anonymous()) {
assert(_keep_alive >= 0, "Invalid keep alive increment count"); assert(_keep_alive >= 0, "Invalid keep alive increment count");
_keep_alive++; _keep_alive++;
} }
} }
void ClassLoaderData::dec_keep_alive() { void ClassLoaderData::dec_keep_alive() {
if (is_anonymous()) { if (is_unsafe_anonymous()) {
assert(_keep_alive > 0, "Invalid keep alive decrement count"); assert(_keep_alive > 0, "Invalid keep alive decrement count");
_keep_alive--; _keep_alive--;
} }
@ -402,20 +402,20 @@ void ClassLoaderData::record_dependency(const Klass* k) {
// Do not need to record dependency if the dependency is to a class whose // 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 // 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 // is one of the three builtin class loaders and the dependency is not
// anonymous.) // unsafe anonymous.)
if (to_cld->is_permanent_class_loader_data()) { if (to_cld->is_permanent_class_loader_data()) {
return; return;
} }
oop to; oop to;
if (to_cld->is_anonymous()) { if (to_cld->is_unsafe_anonymous()) {
// Just return if an anonymous class is attempting to record a dependency // Just return if an unsafe anonymous class is attempting to record a dependency
// to itself. (Note that every anonymous class has its own unique class // to itself. (Note that every unsafe anonymous class has its own unique class
// loader data.) // loader data.)
if (to_cld == from_cld) { if (to_cld == from_cld) {
return; return;
} }
// Anonymous class dependencies are through the mirror. // Unsafe anonymous class dependencies are through the mirror.
to = k->java_mirror(); to = k->java_mirror();
} else { } else {
to = to_cld->class_loader(); to = to_cld->class_loader();
@ -640,7 +640,7 @@ const int _boot_loader_dictionary_size = 1009;
const int _default_loader_dictionary_size = 107; const int _default_loader_dictionary_size = 107;
Dictionary* ClassLoaderData::create_dictionary() { Dictionary* ClassLoaderData::create_dictionary() {
assert(!is_anonymous(), "anonymous class loader data do not have a dictionary"); assert(!is_unsafe_anonymous(), "unsafe anonymous class loader data do not have a dictionary");
int size; int size;
bool resizable = false; bool resizable = false;
if (_the_null_class_loader_data == NULL) { if (_the_null_class_loader_data == NULL) {
@ -677,7 +677,7 @@ oop ClassLoaderData::holder_phantom() const {
// Unloading support // Unloading support
bool ClassLoaderData::is_alive() const { bool ClassLoaderData::is_alive() const {
bool alive = keep_alive() // null class loader and incomplete anonymous klasses. bool alive = keep_alive() // null class loader and incomplete unsafe anonymous klasses.
|| (_holder.peek() != NULL); // and not cleaned by the GC weak handle processing. || (_holder.peek() != NULL); // and not cleaned by the GC weak handle processing.
return alive; return alive;
@ -767,13 +767,13 @@ ClassLoaderData::~ClassLoaderData() {
// Returns true if this class loader data is for the app class loader // 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 // or a user defined system class loader. (Note that the class loader
// data may be anonymous.) // data may be unsafe anonymous.)
bool ClassLoaderData::is_system_class_loader_data() const { bool ClassLoaderData::is_system_class_loader_data() const {
return SystemDictionary::is_system_class_loader(class_loader()); return SystemDictionary::is_system_class_loader(class_loader());
} }
// Returns true if this class loader data is for the platform class loader. // Returns true if this class loader data is for the platform class loader.
// (Note that the class loader data may be anonymous.) // (Note that the class loader data may be unsafe anonymous.)
bool ClassLoaderData::is_platform_class_loader_data() const { bool ClassLoaderData::is_platform_class_loader_data() const {
return SystemDictionary::is_platform_class_loader(class_loader()); return SystemDictionary::is_platform_class_loader(class_loader());
} }
@ -781,7 +781,7 @@ bool ClassLoaderData::is_platform_class_loader_data() const {
// Returns true if the class loader for this class loader data is one of // Returns true if the class loader for this class loader data is one of
// the 3 builtin (boot application/system or platform) class loaders, // the 3 builtin (boot application/system or platform) class loaders,
// including a user-defined system class loader. Note that if the class // including a user-defined system class loader. Note that if the class
// loader data is for an anonymous class then it may get freed by a GC // 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. // even if its class loader is one of these loaders.
bool ClassLoaderData::is_builtin_class_loader_data() const { bool ClassLoaderData::is_builtin_class_loader_data() const {
return (is_boot_class_loader_data() || return (is_boot_class_loader_data() ||
@ -790,10 +790,10 @@ bool ClassLoaderData::is_builtin_class_loader_data() const {
} }
// Returns true if this class loader data is a class loader data // Returns true if this class loader data is a class loader data
// that is not ever freed by a GC. It must be one of the builtin // that is not ever freed by a GC. It must be the CLD for one of the builtin
// class loaders and not anonymous. // class loaders and not the CLD for an unsafe anonymous class.
bool ClassLoaderData::is_permanent_class_loader_data() const { bool ClassLoaderData::is_permanent_class_loader_data() const {
return is_builtin_class_loader_data() && !is_anonymous(); return is_builtin_class_loader_data() && !is_unsafe_anonymous();
} }
ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() { ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() {
@ -810,8 +810,8 @@ ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() {
if (this == the_null_class_loader_data()) { if (this == the_null_class_loader_data()) {
assert (class_loader() == NULL, "Must be"); assert (class_loader() == NULL, "Must be");
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType);
} else if (is_anonymous()) { } else if (is_unsafe_anonymous()) {
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::UnsafeAnonymousMetaspaceType);
} else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
} else { } else {
@ -962,8 +962,8 @@ void ClassLoaderData::free_deallocate_list_C_heap_structures() {
} }
} }
// These anonymous class loaders are to contain classes used for JSR292 // These CLDs are to contain unsafe anonymous classes used for JSR292
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(Handle loader) { ClassLoaderData* ClassLoaderData::unsafe_anonymous_class_loader_data(Handle loader) {
// Add a new class loader data to the graph. // Add a new class loader data to the graph.
return ClassLoaderDataGraph::add(loader, true); return ClassLoaderDataGraph::add(loader, true);
} }
@ -1005,8 +1005,8 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
// loader data: 0xsomeaddr of 'bootstrap' // loader data: 0xsomeaddr of 'bootstrap'
out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id()); out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id());
} }
if (is_anonymous()) { if (is_unsafe_anonymous()) {
out->print(" anonymous"); out->print(" unsafe anonymous");
} }
} }
@ -1014,7 +1014,7 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
void ClassLoaderData::print_on(outputStream* out) const { void ClassLoaderData::print_on(outputStream* out) const {
out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id()); p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id());
if (is_anonymous()) out->print(" anonymous"); if (is_unsafe_anonymous()) out->print(" unsafe anonymous");
if (claimed()) out->print(" claimed"); if (claimed()) out->print(" claimed");
if (is_unloading()) out->print(" unloading"); if (is_unloading()) out->print(" unloading");
out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
@ -1032,8 +1032,8 @@ void ClassLoaderData::verify() {
assert_locked_or_safepoint(_metaspace_lock); assert_locked_or_safepoint(_metaspace_lock);
oop cl = class_loader(); oop cl = class_loader();
guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same"); guarantee(this == class_loader_data(cl) || is_unsafe_anonymous(), "Must be the same");
guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_anonymous(), "must be"); guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_unsafe_anonymous(), "must be");
// Verify the integrity of the allocated space. // Verify the integrity of the allocated space.
if (metaspace_or_null() != NULL) { if (metaspace_or_null() != NULL) {
@ -1069,14 +1069,14 @@ bool ClassLoaderDataGraph::_metaspace_oom = false;
// Add a new class loader data node to the list. Assign the newly created // 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 into the java/lang/ClassLoader object as a hidden field
ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anonymous) { ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsafe_anonymous) {
NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the NoSafepointVerifier no_safepoints; // we mustn't GC until we've installed the
// ClassLoaderData in the graph since the CLD // ClassLoaderData in the graph since the CLD
// contains oops in _handles that must be walked. // contains oops in _handles that must be walked.
ClassLoaderData* cld = new ClassLoaderData(loader, is_anonymous); ClassLoaderData* cld = new ClassLoaderData(loader, is_unsafe_anonymous);
if (!is_anonymous) { if (!is_unsafe_anonymous) {
// First, Atomically set it // First, Atomically set it
ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL); ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
if (old != NULL) { if (old != NULL) {
@ -1109,8 +1109,8 @@ ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anony
} while (true); } while (true);
} }
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) { ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymous) {
ClassLoaderData* loader_data = add_to_graph(loader, is_anonymous); ClassLoaderData* loader_data = add_to_graph(loader, is_unsafe_anonymous);
// Initialize _name and _name_and_id after the loader data is added to the // Initialize _name and _name_and_id after the loader data is added to the
// CLDG because adding the Symbol for _name and _name_and_id might safepoint. // CLDG because adding the Symbol for _name and _name_and_id might safepoint.
if (loader.not_null()) { if (loader.not_null()) {

View file

@ -92,8 +92,8 @@ class ClassLoaderDataGraph : public AllStatic {
static volatile size_t _num_instance_classes; static volatile size_t _num_instance_classes;
static volatile size_t _num_array_classes; static volatile size_t _num_array_classes;
static ClassLoaderData* add_to_graph(Handle class_loader, bool anonymous); static ClassLoaderData* add_to_graph(Handle class_loader, bool is_unsafe_anonymous);
static ClassLoaderData* add(Handle class_loader, bool anonymous); static ClassLoaderData* add(Handle class_loader, bool is_unsafe_anonymous);
public: public:
static ClassLoaderData* find_or_create(Handle class_loader); static ClassLoaderData* find_or_create(Handle class_loader);
@ -114,7 +114,7 @@ class ClassLoaderDataGraph : public AllStatic {
// Walking classes through the ClassLoaderDataGraph include array classes. It also includes // Walking classes through the ClassLoaderDataGraph include array classes. It also includes
// classes that are allocated but not loaded, classes that have errors, and scratch classes // classes that are allocated but not loaded, classes that have errors, and scratch classes
// for redefinition. These classes are removed during the next class unloading. // for redefinition. These classes are removed during the next class unloading.
// Walking the ClassLoaderDataGraph also includes anonymous classes. // Walking the ClassLoaderDataGraph also includes unsafe anonymous classes.
static void classes_do(KlassClosure* klass_closure); static void classes_do(KlassClosure* klass_closure);
static void classes_do(void f(Klass* const)); static void classes_do(void f(Klass* const));
static void methods_do(void f(Method*)); static void methods_do(void f(Method*));
@ -238,16 +238,17 @@ class ClassLoaderData : public CHeapObj<mtClass> {
// classes in the class loader are allocated. // classes in the class loader are allocated.
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup. Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
bool _unloading; // true if this class loader goes away bool _unloading; // true if this class loader goes away
bool _is_anonymous; // if this CLD is for an anonymous class bool _is_unsafe_anonymous; // CLD is dedicated to one class and that class determines the CLDs lifecycle.
// For example, an unsafe anonymous class.
// Remembered sets support for the oops in the class loader data. // Remembered sets support for the oops in the class loader data.
bool _modified_oops; // Card Table Equivalent (YC/CMS support) bool _modified_oops; // Card Table Equivalent (YC/CMS support)
bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support) bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
s2 _keep_alive; // if this CLD is kept alive. s2 _keep_alive; // if this CLD is kept alive.
// Used for anonymous classes and the boot class // Used for unsafe anonymous classes and the boot class
// loader. _keep_alive does not need to be volatile or // loader. _keep_alive does not need to be volatile or
// atomic since there is one unique CLD per anonymous class. // atomic since there is one unique CLD per unsafe anonymous class.
volatile int _claimed; // true if claimed, for example during GC traces. volatile int _claimed; // true if claimed, for example during GC traces.
// To avoid applying oop closure more than once. // To avoid applying oop closure more than once.
@ -283,7 +284,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void set_next(ClassLoaderData* next) { _next = next; } void set_next(ClassLoaderData* next) { _next = next; }
ClassLoaderData* next() const { return _next; } ClassLoaderData* next() const { return _next; }
ClassLoaderData(Handle h_class_loader, bool is_anonymous); ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous);
~ClassLoaderData(); ~ClassLoaderData();
// The CLD are not placed in the Heap, so the Card Table or // The CLD are not placed in the Heap, so the Card Table or
@ -337,7 +338,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
Mutex* metaspace_lock() const { return _metaspace_lock; } Mutex* metaspace_lock() const { return _metaspace_lock; }
bool is_anonymous() const { return _is_anonymous; } bool is_unsafe_anonymous() const { return _is_unsafe_anonymous; }
static void init_null_class_loader_data(); static void init_null_class_loader_data();
@ -346,15 +347,15 @@ class ClassLoaderData : public CHeapObj<mtClass> {
} }
// Returns true if this class loader data is for the system class loader. // Returns true if this class loader data is for the system class loader.
// (Note that the class loader data may be anonymous.) // (Note that the class loader data may be unsafe anonymous.)
bool is_system_class_loader_data() const; bool is_system_class_loader_data() const;
// Returns true if this class loader data is for the platform class loader. // Returns true if this class loader data is for the platform class loader.
// (Note that the class loader data may be anonymous.) // (Note that the class loader data may be unsafe anonymous.)
bool is_platform_class_loader_data() const; bool is_platform_class_loader_data() const;
// Returns true if this class loader data is for the boot class loader. // Returns true if this class loader data is for the boot class loader.
// (Note that the class loader data may be anonymous.) // (Note that the class loader data may be unsafe anonymous.)
inline bool is_boot_class_loader_data() const; inline bool is_boot_class_loader_data() const;
bool is_builtin_class_loader_data() const; bool is_builtin_class_loader_data() const;
@ -372,7 +373,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
return _unloading; return _unloading;
} }
// Used to refcount an anonymous class's CLD in order to // Used to refcount an unsafe anonymous class's CLD in order to
// indicate their aliveness. // indicate their aliveness.
void inc_keep_alive(); void inc_keep_alive();
void dec_keep_alive(); void dec_keep_alive();
@ -412,7 +413,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
static ClassLoaderData* class_loader_data(oop loader); static ClassLoaderData* class_loader_data(oop loader);
static ClassLoaderData* class_loader_data_or_null(oop loader); static ClassLoaderData* class_loader_data_or_null(oop loader);
static ClassLoaderData* anonymous_class_loader_data(Handle loader); static ClassLoaderData* unsafe_anonymous_class_loader_data(Handle loader);
// Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'. // Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'.
// Also works if unloading. // Also works if unloading.

View file

@ -298,7 +298,7 @@ InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS)
name, name,
loader_data, loader_data,
protection_domain, protection_domain,
NULL, // host_klass NULL, // unsafe_anonymous_host
NULL, // cp_patches NULL, // cp_patches
THREAD); THREAD);

View file

@ -128,7 +128,7 @@ public:
class LoaderTreeNode : public ResourceObj { class LoaderTreeNode : public ResourceObj {
// We walk the CLDG and, for each CLD which is non-anonymous, add // We walk the CLDG and, for each CLD which is non-unsafe_anonymous, add
// a tree node. // a tree node.
// To add a node we need its parent node; if the parent node does not yet // To add a node we need its parent node; if the parent node does not yet
// exist - because we have not yet encountered the CLD for the parent loader - // exist - because we have not yet encountered the CLD for the parent loader -
@ -219,7 +219,7 @@ class LoaderTreeNode : public ResourceObj {
if (print_classes) { if (print_classes) {
if (_classes != NULL) { if (_classes != NULL) {
for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) { for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) {
// Non-anonymous classes should live in the primary CLD of its loader // Non-unsafe anonymous classes should live in the primary CLD of its loader
assert(lci->_cld == _cld, "must be"); assert(lci->_cld == _cld, "must be");
branchtracker.print(st); branchtracker.print(st);
@ -252,12 +252,12 @@ class LoaderTreeNode : public ResourceObj {
for (LoadedClassInfo* lci = _anon_classes; lci; lci = lci->_next) { for (LoadedClassInfo* lci = _anon_classes; lci; lci = lci->_next) {
branchtracker.print(st); branchtracker.print(st);
if (lci == _anon_classes) { // first iteration if (lci == _anon_classes) { // first iteration
st->print("%*s ", indentation, "Anonymous Classes:"); st->print("%*s ", indentation, "Unsafe Anonymous Classes:");
} else { } else {
st->print("%*s ", indentation, ""); st->print("%*s ", indentation, "");
} }
st->print("%s", lci->_klass->external_name()); st->print("%s", lci->_klass->external_name());
// For anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD. // For unsafe anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD.
assert(lci->_cld != _cld, "must be"); assert(lci->_cld != _cld, "must be");
if (verbose) { if (verbose) {
st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld)); st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
@ -266,7 +266,7 @@ class LoaderTreeNode : public ResourceObj {
} }
branchtracker.print(st); branchtracker.print(st);
st->print("%*s ", indentation, ""); st->print("%*s ", indentation, "");
st->print_cr("(%u anonymous class%s)", _num_anon_classes, (_num_anon_classes == 1) ? "" : "es"); st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes, (_num_anon_classes == 1) ? "" : "es");
// Empty line // Empty line
branchtracker.print(st); branchtracker.print(st);
@ -318,14 +318,14 @@ public:
_next = info; _next = info;
} }
void add_classes(LoadedClassInfo* first_class, int num_classes, bool anonymous) { void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_unsafe_anonymous) {
LoadedClassInfo** p_list_to_add_to = anonymous ? &_anon_classes : &_classes; LoadedClassInfo** p_list_to_add_to = is_unsafe_anonymous ? &_anon_classes : &_classes;
// Search tail. // Search tail.
while ((*p_list_to_add_to) != NULL) { while ((*p_list_to_add_to) != NULL) {
p_list_to_add_to = &(*p_list_to_add_to)->_next; p_list_to_add_to = &(*p_list_to_add_to)->_next;
} }
*p_list_to_add_to = first_class; *p_list_to_add_to = first_class;
if (anonymous) { if (is_unsafe_anonymous) {
_num_anon_classes += num_classes; _num_anon_classes += num_classes;
} else { } else {
_num_classes += num_classes; _num_classes += num_classes;
@ -420,7 +420,7 @@ class LoaderInfoScanClosure : public CLDClosure {
LoadedClassCollectClosure lccc(cld); LoadedClassCollectClosure lccc(cld);
const_cast<ClassLoaderData*>(cld)->classes_do(&lccc); const_cast<ClassLoaderData*>(cld)->classes_do(&lccc);
if (lccc._num_classes > 0) { if (lccc._num_classes > 0) {
info->add_classes(lccc._list, lccc._num_classes, cld->is_anonymous()); info->add_classes(lccc._list, lccc._num_classes, cld->is_unsafe_anonymous());
} }
} }
@ -480,7 +480,7 @@ public:
assert(info != NULL, "must be"); assert(info != NULL, "must be");
// Update CLD in node, but only if this is the primary CLD for this loader. // Update CLD in node, but only if this is the primary CLD for this loader.
if (cld->is_anonymous() == false) { if (cld->is_unsafe_anonymous() == false) {
assert(info->cld() == NULL, "there should be only one primary CLD per loader"); assert(info->cld() == NULL, "there should be only one primary CLD per loader");
info->set_cld(cld); info->set_cld(cld);
} }

View file

@ -58,7 +58,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
cls = *cls_ptr; cls = *cls_ptr;
} }
if (!cld->is_anonymous()) { if (!cld->is_unsafe_anonymous()) {
cls->_cld = cld; cls->_cld = cld;
} }
@ -70,7 +70,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
ClassStatsClosure csc; ClassStatsClosure csc;
cld->classes_do(&csc); cld->classes_do(&csc);
if(cld->is_anonymous()) { if(cld->is_unsafe_anonymous()) {
cls->_anon_classes_count += csc._num_classes; cls->_anon_classes_count += csc._num_classes;
} else { } else {
cls->_classes_count = csc._num_classes; cls->_classes_count = csc._num_classes;
@ -79,7 +79,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
ClassLoaderMetaspace* ms = cld->metaspace_or_null(); ClassLoaderMetaspace* ms = cld->metaspace_or_null();
if (ms != NULL) { if (ms != NULL) {
if(cld->is_anonymous()) { if(cld->is_unsafe_anonymous()) {
cls->_anon_chunk_sz += ms->allocated_chunks_bytes(); cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
cls->_anon_block_sz += ms->allocated_blocks_bytes(); cls->_anon_block_sz += ms->allocated_blocks_bytes();
} else { } else {

View file

@ -885,7 +885,7 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool,
ConstantPool* cp = bpool->create_constant_pool(CHECK); ConstantPool* cp = bpool->create_constant_pool(CHECK);
if (cp != klass->constants()) { if (cp != klass->constants()) {
// Copy resolved anonymous class into new constant pool. // Copy resolved anonymous class into new constant pool.
if (klass->is_anonymous()) { if (klass->is_unsafe_anonymous()) {
cp->klass_at_put(klass->this_class_index(), klass); cp->klass_at_put(klass->this_class_index(), klass);
} }
klass->class_loader_data()->add_to_deallocate_list(klass->constants()); klass->class_loader_data()->add_to_deallocate_list(klass->constants());

View file

@ -3786,7 +3786,7 @@ oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle
} }
oop new_resolved_method = k->allocate_instance(CHECK_NULL); oop new_resolved_method = k->allocate_instance(CHECK_NULL);
new_resolved_method->address_field_put(_vmtarget_offset, (address)m()); new_resolved_method->address_field_put(_vmtarget_offset, (address)m());
// Add a reference to the loader (actually mirror because anonymous classes will not have // Add a reference to the loader (actually mirror because unsafe anonymous classes will not have
// distinct loaders) to ensure the metadata is kept alive. // distinct loaders) to ensure the metadata is kept alive.
// This mirror may be different than the one in clazz field. // This mirror may be different than the one in clazz field.
new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror()); new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());

View file

@ -183,7 +183,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
Symbol* name, Symbol* name,
ClassLoaderData* loader_data, ClassLoaderData* loader_data,
Handle protection_domain, Handle protection_domain,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
TRAPS) { TRAPS) {
assert(stream != NULL, "invariant"); assert(stream != NULL, "invariant");
@ -201,7 +201,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
THREAD->statistical_info().incr_define_class_count(); THREAD->statistical_info().incr_define_class_count();
// Skip this processing for VM anonymous classes // Skip this processing for VM anonymous classes
if (host_klass == NULL) { if (unsafe_anonymous_host == NULL) {
stream = check_class_file_load_hook(stream, stream = check_class_file_load_hook(stream,
name, name,
loader_data, loader_data,
@ -214,7 +214,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
name, name,
loader_data, loader_data,
protection_domain, protection_domain,
host_klass, unsafe_anonymous_host,
cp_patches, cp_patches,
ClassFileParser::BROADCAST, // publicity level ClassFileParser::BROADCAST, // publicity level
CHECK_NULL); CHECK_NULL);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -72,7 +72,7 @@ class KlassFactory : AllStatic {
Symbol* name, Symbol* name,
ClassLoaderData* loader_data, ClassLoaderData* loader_data,
Handle protection_domain, Handle protection_domain,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
TRAPS); TRAPS);
public: public:

View file

@ -110,7 +110,7 @@ public:
ClassLoaderData* loader_data() const { return _loader_data; } ClassLoaderData* loader_data() const { return _loader_data; }
void set_loader_data(ClassLoaderData* cld) { void set_loader_data(ClassLoaderData* cld) {
assert(!cld->is_anonymous(), "Unexpected anonymous class loader data"); assert(!cld->is_unsafe_anonymous(), "Unexpected unsafe anonymous class loader data");
_loader_data = cld; _loader_data = cld;
} }

View file

@ -988,18 +988,18 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
TRAPS) { TRAPS) {
EventClassLoad class_load_start_event; EventClassLoad class_load_start_event;
ClassLoaderData* loader_data; ClassLoaderData* loader_data;
if (host_klass != NULL) { if (unsafe_anonymous_host != NULL) {
// Create a new CLD for anonymous class, that uses the same class loader // Create a new CLD for an unsafe anonymous class, that uses the same class loader
// as the host_klass // as the unsafe_anonymous_host
guarantee(oopDesc::equals(host_klass->class_loader(), class_loader()), "should be the same"); guarantee(oopDesc::equals(unsafe_anonymous_host->class_loader(), class_loader()), "should be the same");
loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader); loader_data = ClassLoaderData::unsafe_anonymous_class_loader_data(class_loader);
} else { } else {
loader_data = ClassLoaderData::class_loader_data(class_loader()); loader_data = ClassLoaderData::class_loader_data(class_loader());
} }
@ -1016,12 +1016,12 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
class_name, class_name,
loader_data, loader_data,
protection_domain, protection_domain,
host_klass, unsafe_anonymous_host,
cp_patches, cp_patches,
CHECK_NULL); CHECK_NULL);
if (host_klass != NULL && k != NULL) { if (unsafe_anonymous_host != NULL && k != NULL) {
// Anonymous classes must update ClassLoaderData holder (was host_klass loader) // Unsafe anonymous classes must update ClassLoaderData holder (was unsafe_anonymous_host loader)
// so that they can be unloaded when the mirror is no longer referenced. // so that they can be unloaded when the mirror is no longer referenced.
k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror())); k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror()));
@ -1056,8 +1056,8 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
post_class_load_event(&class_load_start_event, k, loader_data); post_class_load_event(&class_load_start_event, k, loader_data);
} }
} }
assert(host_klass != NULL || NULL == cp_patches, assert(unsafe_anonymous_host != NULL || NULL == cp_patches,
"cp_patches only found with host_klass"); "cp_patches only found with unsafe_anonymous_host");
return k; return k;
} }
@ -1115,7 +1115,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
class_name, class_name,
loader_data, loader_data,
protection_domain, protection_domain,
NULL, // host_klass NULL, // unsafe_anonymous_host
NULL, // cp_patches NULL, // cp_patches
CHECK_NULL); CHECK_NULL);
} }
@ -3010,7 +3010,7 @@ class CombineDictionariesClosure : public CLDClosure {
_master_dictionary(master_dictionary) {} _master_dictionary(master_dictionary) {}
void do_cld(ClassLoaderData* cld) { void do_cld(ClassLoaderData* cld) {
ResourceMark rm; ResourceMark rm;
if (cld->is_anonymous()) { if (cld->is_unsafe_anonymous()) {
return; return;
} }
if (cld->is_system_class_loader_data() || cld->is_platform_class_loader_data()) { if (cld->is_system_class_loader_data() || cld->is_platform_class_loader_data()) {

View file

@ -298,7 +298,7 @@ public:
class_loader, class_loader,
protection_domain, protection_domain,
st, st,
NULL, // host klass NULL, // unsafe_anonymous_host
NULL, // cp_patches NULL, // cp_patches
THREAD); THREAD);
} }
@ -306,7 +306,7 @@ public:
Handle class_loader, Handle class_loader,
Handle protection_domain, Handle protection_domain,
ClassFileStream* st, ClassFileStream* st,
const InstanceKlass* host_klass, const InstanceKlass* unsafe_anonymous_host,
GrowableArray<Handle>* cp_patches, GrowableArray<Handle>* cp_patches,
TRAPS); TRAPS);

View file

@ -755,11 +755,11 @@ bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbo
Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) { Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
assert(DumpSharedSpaces, "called at dump time only"); assert(DumpSharedSpaces, "called at dump time only");
// Skip anonymous classes, which are not archived as they are not in // Skip unsafe anonymous classes, which are not archived as they are not in
// dictionary (see assert_no_anonymoys_classes_in_dictionaries() in // dictionary (see assert_no_unsafe_anonymous_classes_in_dictionaries() in
// VM_PopulateDumpSharedSpace::doit()). // VM_PopulateDumpSharedSpace::doit()).
if (k->class_loader_data()->is_anonymous()) { if (k->class_loader_data()->is_unsafe_anonymous()) {
return true; // anonymous classes are not archived, skip return true; // unsafe anonymous classes are not archived, skip
} }
SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k); SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k);

View file

@ -2823,20 +2823,20 @@ void ClassVerifier::verify_invoke_instructions(
current_class()->super()->name()))) { current_class()->super()->name()))) {
bool subtype = false; bool subtype = false;
bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
if (!current_class()->is_anonymous()) { if (!current_class()->is_unsafe_anonymous()) {
subtype = ref_class_type.is_assignable_from( subtype = ref_class_type.is_assignable_from(
current_type(), this, false, CHECK_VERIFY(this)); current_type(), this, false, CHECK_VERIFY(this));
} else { } else {
VerificationType host_klass_type = VerificationType unsafe_anonymous_host_type =
VerificationType::reference_type(current_class()->host_klass()->name()); VerificationType::reference_type(current_class()->unsafe_anonymous_host()->name());
subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this)); subtype = ref_class_type.is_assignable_from(unsafe_anonymous_host_type, this, false, CHECK_VERIFY(this));
// If invokespecial of IMR, need to recheck for same or // If invokespecial of IMR, need to recheck for same or
// direct interface relative to the host class // direct interface relative to the host class
have_imr_indirect = (have_imr_indirect && have_imr_indirect = (have_imr_indirect &&
!is_same_or_direct_interface( !is_same_or_direct_interface(
current_class()->host_klass(), current_class()->unsafe_anonymous_host(),
host_klass_type, ref_class_type)); unsafe_anonymous_host_type, ref_class_type));
} }
if (!subtype) { if (!subtype) {
verify_error(ErrorContext::bad_code(bci), verify_error(ErrorContext::bad_code(bci),
@ -2866,15 +2866,15 @@ void ClassVerifier::verify_invoke_instructions(
} else { // other methods } else { // other methods
// Ensures that target class is assignable to method class. // Ensures that target class is assignable to method class.
if (opcode == Bytecodes::_invokespecial) { if (opcode == Bytecodes::_invokespecial) {
if (!current_class()->is_anonymous()) { if (!current_class()->is_unsafe_anonymous()) {
current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
} else { } else {
// anonymous class invokespecial calls: check if the // anonymous class invokespecial calls: check if the
// objectref is a subtype of the host_klass of the current class // objectref is a subtype of the unsafe_anonymous_host of the current class
// to allow an anonymous class to reference methods in the host_klass // to allow an anonymous class to reference methods in the unsafe_anonymous_host
VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
VerificationType hosttype = VerificationType hosttype =
VerificationType::reference_type(current_class()->host_klass()->name()); VerificationType::reference_type(current_class()->unsafe_anonymous_host()->name());
bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this)); bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this));
if (!subtype) { if (!subtype) {
verify_error( ErrorContext::bad_type(current_frame->offset(), verify_error( ErrorContext::bad_type(current_frame->offset(),

View file

@ -153,14 +153,14 @@ void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager*
// Follow the klass field in the mirror. // Follow the klass field in the mirror.
Klass* klass = java_lang_Class::as_Klass(obj); Klass* klass = java_lang_Class::as_Klass(obj);
if (klass != NULL) { if (klass != NULL) {
// An anonymous class doesn't have its own class loader, so the call // An unsafe anonymous class doesn't have its own class loader,
// to follow_klass will mark and push its java mirror instead of the // so the call to follow_klass will mark and push its java mirror instead of the
// class loader. When handling the java mirror for an anonymous class // class loader. When handling the java mirror for an unsafe anonymous
// we need to make sure its class loader data is claimed, this is done // class we need to make sure its class loader data is claimed, this is done
// by calling follow_class_loader explicitly. For non-anonymous classes // by calling follow_class_loader explicitly. For non-anonymous classes the
// the call to follow_class_loader is made when the class loader itself // call to follow_class_loader is made when the class loader itself is handled.
// is handled. if (klass->is_instance_klass() &&
if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) { InstanceKlass::cast(klass)->is_unsafe_anonymous()) {
cm->follow_class_loader(klass->class_loader_data()); cm->follow_class_loader(klass->class_loader_data());
} else { } else {
cm->follow_klass(klass); cm->follow_klass(klass);

View file

@ -924,11 +924,11 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
info.call_kind() == CallInfo::vtable_call, ""); info.call_kind() == CallInfo::vtable_call, "");
} }
#endif #endif
// Get sender or sender's host_klass, and only set cpCache entry to resolved if // Get sender or sender's unsafe_anonymous_host, and only set cpCache entry to resolved if
// it is not an interface. The receiver for invokespecial calls within interface // it is not an interface. The receiver for invokespecial calls within interface
// methods must be checked for every call. // methods must be checked for every call.
InstanceKlass* sender = pool->pool_holder(); InstanceKlass* sender = pool->pool_holder();
sender = sender->has_host_klass() ? sender->host_klass() : sender; sender = sender->is_unsafe_anonymous() ? sender->unsafe_anonymous_host() : sender;
switch (info.call_kind()) { switch (info.call_kind()) {
case CallInfo::direct_call: case CallInfo::direct_call:

View file

@ -1167,9 +1167,9 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
Klass* current_klass = link_info.current_klass(); Klass* current_klass = link_info.current_klass();
if (current_klass != NULL && resolved_klass->is_interface()) { if (current_klass != NULL && resolved_klass->is_interface()) {
InstanceKlass* ck = InstanceKlass::cast(current_klass); InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_anonymous() ? InstanceKlass *klass_to_check = !ck->is_unsafe_anonymous() ?
ck : ck :
InstanceKlass::cast(ck->host_klass()); InstanceKlass::cast(ck->unsafe_anonymous_host());
// Disable verification for the dynamically-generated reflection bytecodes. // Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of( bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass()); SystemDictionary::reflect_MagicAccessorImpl_klass());
@ -1260,7 +1260,7 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
// The verifier also checks that the receiver is a subtype of the sender, if the sender is // The verifier also checks that the receiver is a subtype of the sender, if the sender is
// a class. If the sender is an interface, the check has to be performed at runtime. // a class. If the sender is an interface, the check has to be performed at runtime.
InstanceKlass* sender = InstanceKlass::cast(current_klass); InstanceKlass* sender = InstanceKlass::cast(current_klass);
sender = sender->is_anonymous() ? sender->host_klass() : sender; sender = sender->is_unsafe_anonymous() ? sender->unsafe_anonymous_host() : sender;
if (sender->is_interface() && recv.not_null()) { if (sender->is_interface() && recv.not_null()) {
Klass* receiver_klass = recv->klass(); Klass* receiver_klass = recv->klass();
if (!receiver_klass->is_subtype_of(sender)) { if (!receiver_klass->is_subtype_of(sender)) {

View file

@ -161,10 +161,10 @@ void ObjectSampleDescription::write_class_name() {
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
const InstanceKlass* ik = InstanceKlass::cast(k); const InstanceKlass* ik = InstanceKlass::cast(k);
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
return; return;
} }
assert(!ik->is_anonymous(), "invariant"); assert(!ik->is_unsafe_anonymous(), "invariant");
const Symbol* name = ik->name(); const Symbol* name = ik->name();
if (name != NULL) { if (name != NULL) {
write_text("Class Name: "); write_text("Class Name: ");

View file

@ -200,7 +200,7 @@
<Event name="MetaspaceAllocationFailure" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Allocation Failure" startTime="false" <Event name="MetaspaceAllocationFailure" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Allocation Failure" startTime="false"
stackTrace="true"> stackTrace="true">
<Field type="ClassLoader" name="classLoader" label="Class Loader" /> <Field type="ClassLoader" name="classLoader" label="Class Loader" />
<Field type="boolean" name="anonymousClassLoader" label="Anonymous Class Loader" /> <Field type="boolean" name="unsafeAnonymousClassLoader" label="Unsafe Anonymous Class Loader" />
<Field type="ulong" contentType="bytes" name="size" label="Size" /> <Field type="ulong" contentType="bytes" name="size" label="Size" />
<Field type="MetadataType" name="metadataType" label="Metadata Type" /> <Field type="MetadataType" name="metadataType" label="Metadata Type" />
<Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" /> <Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" />
@ -208,7 +208,7 @@
<Event name="MetaspaceOOM" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Out of Memory" startTime="false" stackTrace="true"> <Event name="MetaspaceOOM" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Out of Memory" startTime="false" stackTrace="true">
<Field type="ClassLoader" name="classLoader" label="Class Loader" /> <Field type="ClassLoader" name="classLoader" label="Class Loader" />
<Field type="boolean" name="anonymousClassLoader" label="Anonymous Class Loader" /> <Field type="boolean" name="unsafeAnonymousClassLoader" label="Unsafe Anonymous Class Loader" />
<Field type="ulong" contentType="bytes" name="size" label="Size" /> <Field type="ulong" contentType="bytes" name="size" label="Size" />
<Field type="MetadataType" name="metadataType" label="Metadata Type" /> <Field type="MetadataType" name="metadataType" label="Metadata Type" />
<Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" /> <Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" />
@ -682,11 +682,11 @@
<Field type="long" name="classCount" label="Classes" description="Number of loaded classes" /> <Field type="long" name="classCount" label="Classes" description="Number of loaded classes" />
<Field type="ulong" contentType="bytes" name="chunkSize" label="Total Chunk Size" description="Total size of all allocated metaspace chunks (each chunk has several blocks)" /> <Field type="ulong" contentType="bytes" name="chunkSize" label="Total Chunk Size" description="Total size of all allocated metaspace chunks (each chunk has several blocks)" />
<Field type="ulong" contentType="bytes" name="blockSize" label="Total Block Size" description="Total size of all allocated metaspace blocks (each chunk has several blocks)" /> <Field type="ulong" contentType="bytes" name="blockSize" label="Total Block Size" description="Total size of all allocated metaspace blocks (each chunk has several blocks)" />
<Field type="long" name="anonymousClassCount" label="Unsafe Anonymous Classes" description="Number of loaded classes to support invokedynamic" /> <Field type="long" name="unsafeAnonymousClassCount" label="Unsafe Anonymous Classes" description="Number of loaded classes to support invokedynamic" />
<Field type="ulong" contentType="bytes" name="anonymousChunkSize" label="Total Unsafe Anonymous Classes Chunk Size" <Field type="ulong" contentType="bytes" name="unsafeAnonymousChunkSize" label="Total Unsafe Anonymous Classes Chunk Size"
description="Total size of all allocated metaspace chunks for anonymous classes (each chunk has several blocks)" /> description="Total size of all allocated metaspace chunks for unsafe anonymous classes (each chunk has several blocks)" />
<Field type="ulong" contentType="bytes" name="anonymousBlockSize" label="Total Unsafe Anonymous Classes Block Size" <Field type="ulong" contentType="bytes" name="unsafeAnonymousBlockSize" label="Total Unsafe Anonymous Classes Block Size"
description="Total size of all allocated metaspace blocks for anonymous classes (each chunk has several blocks)" /> description="Total size of all allocated metaspace blocks for unsafe anonymous classes (each chunk has several blocks)" />
</Event> </Event>
<Event name="ThreadAllocationStatistics" category="Java Application, Statistics" label="Thread Allocation Statistics" period="everyChunk"> <Event name="ThreadAllocationStatistics" category="Java Application, Statistics" label="Thread Allocation Statistics" period="everyChunk">

View file

@ -476,9 +476,9 @@ public:
event.set_classCount(cls->_classes_count); event.set_classCount(cls->_classes_count);
event.set_chunkSize(cls->_chunk_sz); event.set_chunkSize(cls->_chunk_sz);
event.set_blockSize(cls->_block_sz); event.set_blockSize(cls->_block_sz);
event.set_anonymousClassCount(cls->_anon_classes_count); event.set_unsafeAnonymousClassCount(cls->_anon_classes_count);
event.set_anonymousChunkSize(cls->_anon_chunk_sz); event.set_unsafeAnonymousChunkSize(cls->_anon_chunk_sz);
event.set_anonymousBlockSize(cls->_anon_block_sz); event.set_unsafeAnonymousBlockSize(cls->_anon_block_sz);
event.commit(); event.commit();
return true; return true;
} }

View file

@ -77,7 +77,7 @@ static traceid package_id(KlassPtr klass) {
static traceid cld_id(CldPtr cld) { static traceid cld_id(CldPtr cld) {
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
return cld->is_anonymous() ? 0 : TRACE_ID(cld); return cld->is_unsafe_anonymous() ? 0 : TRACE_ID(cld);
} }
static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) { static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
@ -92,7 +92,7 @@ static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
} }
CldPtr cld = k->class_loader_data(); CldPtr cld = k->class_loader_data();
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
if (!cld->is_anonymous()) { if (!cld->is_unsafe_anonymous()) {
tag_leakp_artifact(cld, class_unload); tag_leakp_artifact(cld, class_unload);
} }
} }
@ -230,7 +230,7 @@ typedef JfrArtifactWriterHost<ModuleWriterImpl, TYPE_MODULE> ModuleWriter;
int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) { int write__artifact__classloader(JfrCheckpointWriter* writer, JfrArtifactSet* artifacts, const void* c) {
assert(c != NULL, "invariant"); assert(c != NULL, "invariant");
CldPtr cld = (CldPtr)c; CldPtr cld = (CldPtr)c;
assert(!cld->is_anonymous(), "invariant"); assert(!cld->is_unsafe_anonymous(), "invariant");
const traceid cld_id = TRACE_ID(cld); const traceid cld_id = TRACE_ID(cld);
// class loader type // class loader type
const Klass* class_loader_klass = cld->class_loader_klass(); const Klass* class_loader_klass = cld->class_loader_klass();
@ -301,9 +301,9 @@ int write__artifact__klass__symbol(JfrCheckpointWriter* writer, JfrArtifactSet*
assert(artifacts != NULL, "invaiant"); assert(artifacts != NULL, "invaiant");
assert(k != NULL, "invariant"); assert(k != NULL, "invariant");
const InstanceKlass* const ik = (const InstanceKlass*)k; const InstanceKlass* const ik = (const InstanceKlass*)k;
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
CStringEntryPtr entry = CStringEntryPtr entry =
artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik)); artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik));
assert(entry != NULL, "invariant"); assert(entry != NULL, "invariant");
return write__artifact__cstring__entry__(writer, entry); return write__artifact__cstring__entry__(writer, entry);
} }
@ -358,7 +358,7 @@ class KlassSymbolWriterImpl {
} }
CldPtr cld = klass->class_loader_data(); CldPtr cld = klass->class_loader_data();
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
if (!cld->is_anonymous()) { if (!cld->is_unsafe_anonymous()) {
count += class_loader_symbols(cld); count += class_loader_symbols(cld);
} }
if (_method_used_predicate(klass)) { if (_method_used_predicate(klass)) {
@ -374,9 +374,9 @@ int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) {
assert(klass != NULL, "invariant"); assert(klass != NULL, "invariant");
assert(_predicate(klass), "invariant"); assert(_predicate(klass), "invariant");
const InstanceKlass* const ik = (const InstanceKlass*)klass; const InstanceKlass* const ik = (const InstanceKlass*)klass;
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
CStringEntryPtr entry = CStringEntryPtr entry =
this->_artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik)); this->_artifacts->map_cstring(JfrSymbolId::unsafe_anonymous_klass_name_hash_code(ik));
assert(entry != NULL, "invariant"); assert(entry != NULL, "invariant");
return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0; return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0;
} }
@ -432,7 +432,7 @@ int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) {
template <template <typename> class Predicate> template <template <typename> class Predicate>
int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) { int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
assert(!cld->is_anonymous(), "invariant"); assert(!cld->is_unsafe_anonymous(), "invariant");
int count = 0; int count = 0;
// class loader type // class loader type
const Klass* class_loader_klass = cld->class_loader_klass(); const Klass* class_loader_klass = cld->class_loader_klass();
@ -696,7 +696,7 @@ class CldFieldSelector {
static TypePtr select(KlassPtr klass) { static TypePtr select(KlassPtr klass) {
assert(klass != NULL, "invariant"); assert(klass != NULL, "invariant");
CldPtr cld = klass->class_loader_data(); CldPtr cld = klass->class_loader_data();
return cld->is_anonymous() ? NULL : cld; return cld->is_unsafe_anonymous() ? NULL : cld;
} }
}; };
@ -922,7 +922,7 @@ class CLDCallback : public CLDClosure {
CLDCallback(bool class_unload) : _class_unload(class_unload) {} CLDCallback(bool class_unload) : _class_unload(class_unload) {}
void do_cld(ClassLoaderData* cld) { void do_cld(ClassLoaderData* cld) {
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
if (cld->is_anonymous()) { if (cld->is_unsafe_anonymous()) {
return; return;
} }
if (_class_unload) { if (_class_unload) {

View file

@ -59,14 +59,14 @@ JfrSymbolId::~JfrSymbolId() {
delete _cstring_table; delete _cstring_table;
} }
traceid JfrSymbolId::mark_anonymous_klass_name(const Klass* k) { traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const Klass* k) {
assert(k != NULL, "invariant"); assert(k != NULL, "invariant");
assert(k->is_instance_klass(), "invariant"); assert(k->is_instance_klass(), "invariant");
assert(is_anonymous_klass(k), "invariant"); assert(is_unsafe_anonymous_klass(k), "invariant");
uintptr_t anonymous_symbol_hash_code = 0; uintptr_t anonymous_symbol_hash_code = 0;
const char* const anonymous_symbol = const char* const anonymous_symbol =
create_anonymous_klass_symbol((const InstanceKlass*)k, anonymous_symbol_hash_code); create_unsafe_anonymous_klass_symbol((const InstanceKlass*)k, anonymous_symbol_hash_code);
if (anonymous_symbol == NULL) { if (anonymous_symbol == NULL) {
return 0; return 0;
@ -119,8 +119,8 @@ bool JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry*
traceid JfrSymbolId::mark(const Klass* k) { traceid JfrSymbolId::mark(const Klass* k) {
assert(k != NULL, "invariant"); assert(k != NULL, "invariant");
traceid symbol_id = 0; traceid symbol_id = 0;
if (is_anonymous_klass(k)) { if (is_unsafe_anonymous_klass(k)) {
symbol_id = mark_anonymous_klass_name(k); symbol_id = mark_unsafe_anonymous_klass_name(k);
} }
if (0 == symbol_id) { if (0 == symbol_id) {
const Symbol* const sym = k->name(); const Symbol* const sym = k->name();
@ -148,9 +148,9 @@ traceid JfrSymbolId::mark(const char* str, uintptr_t hash) {
return _cstring_table->id(str, hash); return _cstring_table->id(str, hash);
} }
bool JfrSymbolId::is_anonymous_klass(const Klass* k) { bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
assert(k != NULL, "invariant"); assert(k != NULL, "invariant");
return k->is_instance_klass() && ((const InstanceKlass*)k)->is_anonymous(); return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous();
} }
/* /*
@ -161,23 +161,23 @@ bool JfrSymbolId::is_anonymous_klass(const Klass* k) {
* caller needs ResourceMark * caller needs ResourceMark
*/ */
uintptr_t JfrSymbolId::anonymous_klass_name_hash_code(const InstanceKlass* ik) { uintptr_t JfrSymbolId::unsafe_anonymous_klass_name_hash_code(const InstanceKlass* ik) {
assert(ik != NULL, "invariant"); assert(ik != NULL, "invariant");
assert(ik->is_anonymous(), "invariant"); assert(ik->is_unsafe_anonymous(), "invariant");
const oop mirror = ik->java_mirror(); const oop mirror = ik->java_mirror();
assert(mirror != NULL, "invariant"); assert(mirror != NULL, "invariant");
return (uintptr_t)mirror->identity_hash(); return (uintptr_t)mirror->identity_hash();
} }
const char* JfrSymbolId::create_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode) { const char* JfrSymbolId::create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode) {
assert(ik != NULL, "invariant"); assert(ik != NULL, "invariant");
assert(ik->is_anonymous(), "invariant"); assert(ik->is_unsafe_anonymous(), "invariant");
assert(0 == hashcode, "invariant"); assert(0 == hashcode, "invariant");
char* anonymous_symbol = NULL; char* anonymous_symbol = NULL;
const oop mirror = ik->java_mirror(); const oop mirror = ik->java_mirror();
assert(mirror != NULL, "invariant"); assert(mirror != NULL, "invariant");
char hash_buf[40]; char hash_buf[40];
hashcode = anonymous_klass_name_hash_code(ik); hashcode = unsafe_anonymous_klass_name_hash_code(ik);
sprintf(hash_buf, "/" UINTX_FORMAT, hashcode); sprintf(hash_buf, "/" UINTX_FORMAT, hashcode);
const size_t hash_len = strlen(hash_buf); const size_t hash_len = strlen(hash_buf);
const size_t result_len = ik->name()->utf8_length(); const size_t result_len = ik->name()->utf8_length();
@ -223,8 +223,8 @@ void JfrArtifactSet::clear() {
// _klass_list will be cleared by a ResourceMark // _klass_list will be cleared by a ResourceMark
} }
traceid JfrArtifactSet::mark_anonymous_klass_name(const Klass* klass) { traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass) {
return _symbol_id->mark_anonymous_klass_name(klass); return _symbol_id->mark_unsafe_anonymous_klass_name(klass);
} }
traceid JfrArtifactSet::mark(const Symbol* sym, uintptr_t hash) { traceid JfrArtifactSet::mark(const Symbol* sym, uintptr_t hash) {

View file

@ -236,9 +236,9 @@ class JfrSymbolId : public JfrCHeapObj {
bool equals(const char* query, uintptr_t hash, const CStringEntry* entry); bool equals(const char* query, uintptr_t hash, const CStringEntry* entry);
public: public:
static bool is_anonymous_klass(const Klass* k); static bool is_unsafe_anonymous_klass(const Klass* k);
static const char* create_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode); static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode);
static uintptr_t anonymous_klass_name_hash_code(const InstanceKlass* ik); static uintptr_t unsafe_anonymous_klass_name_hash_code(const InstanceKlass* ik);
static uintptr_t regular_klass_name_hash_code(const Klass* k); static uintptr_t regular_klass_name_hash_code(const Klass* k);
JfrSymbolId(); JfrSymbolId();
@ -247,7 +247,7 @@ class JfrSymbolId : public JfrCHeapObj {
void initialize(); void initialize();
void clear(); void clear();
traceid mark_anonymous_klass_name(const Klass* k); traceid mark_unsafe_anonymous_klass_name(const Klass* k);
traceid mark(const Symbol* sym, uintptr_t hash); traceid mark(const Symbol* sym, uintptr_t hash);
traceid mark(const Klass* k); traceid mark(const Klass* k);
traceid mark(const Symbol* symbol); traceid mark(const Symbol* symbol);
@ -259,7 +259,7 @@ class JfrSymbolId : public JfrCHeapObj {
template <typename T> template <typename T>
void symbol(T& functor, const Klass* k) { void symbol(T& functor, const Klass* k) {
if (is_anonymous_klass(k)) { if (is_unsafe_anonymous_klass(k)) {
return; return;
} }
functor(map_symbol(regular_klass_name_hash_code(k))); functor(map_symbol(regular_klass_name_hash_code(k)));
@ -274,10 +274,10 @@ class JfrSymbolId : public JfrCHeapObj {
template <typename T> template <typename T>
void cstring(T& functor, const Klass* k) { void cstring(T& functor, const Klass* k) {
if (!is_anonymous_klass(k)) { if (!is_unsafe_anonymous_klass(k)) {
return; return;
} }
functor(map_cstring(anonymous_klass_name_hash_code((const InstanceKlass*)k))); functor(map_cstring(unsafe_anonymous_klass_name_hash_code((const InstanceKlass*)k)));
} }
template <typename T> template <typename T>
@ -327,7 +327,7 @@ class JfrArtifactSet : public JfrCHeapObj {
traceid mark(const Klass* klass); traceid mark(const Klass* klass);
traceid mark(const Symbol* symbol); traceid mark(const Symbol* symbol);
traceid mark(const char* const str, uintptr_t hash); traceid mark(const char* const str, uintptr_t hash);
traceid mark_anonymous_klass_name(const Klass* klass); traceid mark_unsafe_anonymous_klass_name(const Klass* klass);
const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const; const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const;
const JfrSymbolId::SymbolEntry* map_symbol(uintptr_t hash) const; const JfrSymbolId::SymbolEntry* map_symbol(uintptr_t hash) const;

View file

@ -120,7 +120,7 @@ void JfrTraceId::assign(const PackageEntry* package) {
void JfrTraceId::assign(const ClassLoaderData* cld) { void JfrTraceId::assign(const ClassLoaderData* cld) {
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
if (cld->is_anonymous()) { if (cld->is_unsafe_anonymous()) {
cld->set_trace_id(0); cld->set_trace_id(0);
return; return;
} }

View file

@ -96,7 +96,7 @@ inline traceid JfrTraceId::use(const PackageEntry* package, bool leakp /* false
inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) { inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) {
assert(cld != NULL, "invariant"); assert(cld != NULL, "invariant");
return cld->is_anonymous() ? 0 : set_used_and_get_shifted(cld, leakp); return cld->is_unsafe_anonymous() ? 0 : set_used_and_get_shifted(cld, leakp);
} }
inline bool JfrTraceId::in_visible_set(const Klass* klass) { inline bool JfrTraceId::in_visible_set(const Klass* klass) {

View file

@ -1436,7 +1436,7 @@ C2V_END
C2V_VMENTRY(jobject, getHostClass, (JNIEnv*, jobject, jobject jvmci_type)) C2V_VMENTRY(jobject, getHostClass, (JNIEnv*, jobject, jobject jvmci_type))
InstanceKlass* k = InstanceKlass::cast(CompilerToVM::asKlass(jvmci_type)); InstanceKlass* k = InstanceKlass::cast(CompilerToVM::asKlass(jvmci_type));
InstanceKlass* host = k->host_klass(); InstanceKlass* host = k->unsafe_anonymous_host();
JVMCIKlassHandle handle(THREAD, host); JVMCIKlassHandle handle(THREAD, host);
oop result = CompilerToVM::get_jvmci_type(handle, CHECK_NULL); oop result = CompilerToVM::get_jvmci_type(handle, CHECK_NULL);
return JNIHandles::make_local(THREAD, result); return JNIHandles::make_local(THREAD, result);

View file

@ -527,7 +527,7 @@
\ \
declare_constant(InstanceKlass::linked) \ declare_constant(InstanceKlass::linked) \
declare_constant(InstanceKlass::fully_initialized) \ declare_constant(InstanceKlass::fully_initialized) \
declare_constant(InstanceKlass::_misc_is_anonymous) \ declare_constant(InstanceKlass::_misc_is_unsafe_anonymous) \
\ \
declare_constant(JumpData::taken_off_set) \ declare_constant(JumpData::taken_off_set) \
declare_constant(JumpData::displacement_off_set) \ declare_constant(JumpData::displacement_off_set) \

View file

@ -62,7 +62,7 @@ static const char* space_type_name(Metaspace::MetaspaceType t) {
switch (t) { switch (t) {
case Metaspace::StandardMetaspaceType: s = "Standard"; break; case Metaspace::StandardMetaspaceType: s = "Standard"; break;
case Metaspace::BootMetaspaceType: s = "Boot"; break; case Metaspace::BootMetaspaceType: s = "Boot"; break;
case Metaspace::AnonymousMetaspaceType: s = "Anonymous"; break; case Metaspace::UnsafeAnonymousMetaspaceType: s = "UnsafeAnonymous"; break;
case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break; case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break;
default: ShouldNotReachHere(); default: ShouldNotReachHere();
} }

View file

@ -102,8 +102,8 @@ class Metaspace : public AllStatic {
ZeroMetaspaceType = 0, ZeroMetaspaceType = 0,
StandardMetaspaceType = ZeroMetaspaceType, StandardMetaspaceType = ZeroMetaspaceType,
BootMetaspaceType = StandardMetaspaceType + 1, BootMetaspaceType = StandardMetaspaceType + 1,
AnonymousMetaspaceType = BootMetaspaceType + 1, UnsafeAnonymousMetaspaceType = BootMetaspaceType + 1,
ReflectionMetaspaceType = AnonymousMetaspaceType + 1, ReflectionMetaspaceType = UnsafeAnonymousMetaspaceType + 1,
MetaspaceTypeCount MetaspaceTypeCount
}; };

View file

@ -102,7 +102,7 @@ void PrintCLDMetaspaceInfoClosure::do_cld(ClassLoaderData* cld) {
_out->print(" (unloading)"); _out->print(" (unloading)");
} }
_out->print(":"); _out->print(":");
if (cld->is_anonymous()) { if (cld->is_unsafe_anonymous()) {
_out->print(" <anonymous class>, loaded by"); _out->print(" <anonymous class>, loaded by");
} }
if (name != NULL) { if (name != NULL) {

View file

@ -75,14 +75,14 @@ size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const
if (is_class()) { if (is_class()) {
switch (type) { switch (type) {
case Metaspace::BootMetaspaceType: requested = Metaspace::first_class_chunk_word_size(); break; case Metaspace::BootMetaspaceType: requested = Metaspace::first_class_chunk_word_size(); break;
case Metaspace::AnonymousMetaspaceType: requested = ClassSpecializedChunk; break; case Metaspace::UnsafeAnonymousMetaspaceType: requested = ClassSpecializedChunk; break;
case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break; case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break;
default: requested = ClassSmallChunk; break; default: requested = ClassSmallChunk; break;
} }
} else { } else {
switch (type) { switch (type) {
case Metaspace::BootMetaspaceType: requested = Metaspace::first_chunk_word_size(); break; case Metaspace::BootMetaspaceType: requested = Metaspace::first_chunk_word_size(); break;
case Metaspace::AnonymousMetaspaceType: requested = SpecializedChunk; break; case Metaspace::UnsafeAnonymousMetaspaceType: requested = SpecializedChunk; break;
case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break; case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break;
default: requested = SmallChunk; break; default: requested = SmallChunk; break;
} }
@ -114,13 +114,15 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) {
// After that a medium chunk is preferred. // After that a medium chunk is preferred.
size_t chunk_word_size; size_t chunk_word_size;
// Special case for anonymous metadata space. // Special case for unsafe anonymous metadata space.
// Anonymous metadata space is usually small, with majority within 1K - 2K range and // UnsafeAnonymous metadata space is usually small since it is used for
// class loader data's whose life cycle is governed by one class such as an
// unsafe anonymous class. The majority within 1K - 2K range and
// rarely about 4K (64-bits JVM). // rarely about 4K (64-bits JVM).
// Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
// from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4) // from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4)
// reduces space waste from 60+% to around 30%. // reduces space waste from 60+% to around 30%.
if ((_space_type == Metaspace::AnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) && if ((_space_type == Metaspace::UnsafeAnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) &&
_mdtype == Metaspace::NonClassType && _mdtype == Metaspace::NonClassType &&
num_chunks_by_type(SpecializedIndex) < anon_and_delegating_metadata_specialize_chunk_limit && num_chunks_by_type(SpecializedIndex) < anon_and_delegating_metadata_specialize_chunk_limit &&
word_size + Metachunk::overhead() <= SpecializedChunk) { word_size + Metachunk::overhead() <= SpecializedChunk) {

View file

@ -579,14 +579,13 @@ static void relocate_cached_class_file() {
} }
NOT_PRODUCT( NOT_PRODUCT(
static void assert_not_anonymous_class(InstanceKlass* k) { static void assert_not_unsafe_anonymous_class(InstanceKlass* k) {
assert(!(k->is_anonymous()), "cannot archive anonymous classes"); assert(!(k->is_unsafe_anonymous()), "cannot archive unsafe anonymous classes");
} }
// Anonymous classes are not stored inside any dictionaries. They are created by // Unsafe anonymous classes are not stored inside any dictionaries.
// SystemDictionary::parse_stream() with a non-null host_klass. static void assert_no_unsafe_anonymous_classes_in_dictionaries() {
static void assert_no_anonymoys_classes_in_dictionaries() { ClassLoaderDataGraph::dictionary_classes_do(assert_not_unsafe_anonymous_class);
ClassLoaderDataGraph::dictionary_classes_do(assert_not_anonymous_class);
}) })
// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables. // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
@ -1396,9 +1395,9 @@ void VM_PopulateDumpSharedSpace::doit() {
remove_unshareable_in_classes(); remove_unshareable_in_classes();
tty->print_cr("done. "); tty->print_cr("done. ");
// We don't support archiving anonymous classes. Verify that they are not stored in // We don't support archiving unsafe anonymous classes. Verify that they are not stored in
// the any dictionaries. // any dictionaries.
NOT_PRODUCT(assert_no_anonymoys_classes_in_dictionaries()); NOT_PRODUCT(assert_no_unsafe_anonymous_classes_in_dictionaries());
SystemDictionaryShared::finalize_verification_constraints(); SystemDictionaryShared::finalize_verification_constraints();

View file

@ -62,10 +62,10 @@ void MetaspaceTracer::send_allocation_failure_event(ClassLoaderData *cld,
E event; E event;
if (event.should_commit()) { if (event.should_commit()) {
event.set_classLoader(cld); event.set_classLoader(cld);
if (cld->is_anonymous()) { if (cld->is_unsafe_anonymous()) {
event.set_anonymousClassLoader(true); event.set_unsafeAnonymousClassLoader(true);
} else { } else {
event.set_anonymousClassLoader(false); event.set_unsafeAnonymousClassLoader(false);
} }
event.set_size(word_size * BytesPerWord); event.set_size(word_size * BytesPerWord);
event.set_metadataType((u1) mdtype); event.set_metadataType((u1) mdtype);

View file

@ -221,7 +221,7 @@ void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, T
allocate_resolved_klasses(loader_data, num_klasses, THREAD); allocate_resolved_klasses(loader_data, num_klasses, THREAD);
} }
// Anonymous class support: // Unsafe anonymous class support:
void ConstantPool::klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name) { void ConstantPool::klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name) {
assert(is_within_bounds(class_index), "index out of bounds"); assert(is_within_bounds(class_index), "index out of bounds");
assert(is_within_bounds(name_index), "index out of bounds"); assert(is_within_bounds(name_index), "index out of bounds");
@ -243,7 +243,7 @@ void ConstantPool::klass_at_put(int class_index, int name_index, int resolved_kl
} }
} }
// Anonymous class support: // Unsafe anonymous class support:
void ConstantPool::klass_at_put(int class_index, Klass* k) { void ConstantPool::klass_at_put(int class_index, Klass* k) {
assert(k != NULL, "must be valid klass"); assert(k != NULL, "must be valid klass");
CPKlassSlot kslot = klass_slot_at(class_index); CPKlassSlot kslot = klass_slot_at(class_index);

View file

@ -271,7 +271,7 @@ class ConstantPool : public Metadata {
*int_at_addr(which) = name_index; *int_at_addr(which) = name_index;
} }
// Anonymous class support: // Unsafe anonymous class support:
void klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name); void klass_at_put(int class_index, int name_index, int resolved_klass_index, Klass* k, Symbol* name);
void klass_at_put(int class_index, Klass* k); void klass_at_put(int class_index, Klass* k);
@ -455,7 +455,7 @@ class ConstantPool : public Metadata {
// A "pseudo-string" is an non-string oop that has found its way into // A "pseudo-string" is an non-string oop that has found its way into
// a String entry. // a String entry.
// This can happen if the user patches a live // This can happen if the user patches a live
// object into a CONSTANT_String entry of an anonymous class. // object into a CONSTANT_String entry of an unsafe anonymous class.
// Method oops internally created for method handles may also // Method oops internally created for method handles may also
// use pseudo-strings to link themselves to related metaobjects. // use pseudo-strings to link themselves to related metaobjects.

View file

@ -341,8 +341,8 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& par
parser.itable_size(), parser.itable_size(),
nonstatic_oop_map_size(parser.total_oop_map_count()), nonstatic_oop_map_size(parser.total_oop_map_count()),
parser.is_interface(), parser.is_interface(),
parser.is_anonymous(), parser.is_unsafe_anonymous(),
should_store_fingerprint(parser.is_anonymous())); should_store_fingerprint(parser.is_unsafe_anonymous()));
const Symbol* const class_name = parser.class_name(); const Symbol* const class_name = parser.class_name();
assert(class_name != NULL, "invariant"); assert(class_name != NULL, "invariant");
@ -412,7 +412,7 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, Klass
set_vtable_length(parser.vtable_size()); set_vtable_length(parser.vtable_size());
set_kind(kind); set_kind(kind);
set_access_flags(parser.access_flags()); set_access_flags(parser.access_flags());
set_is_anonymous(parser.is_anonymous()); set_is_unsafe_anonymous(parser.is_unsafe_anonymous());
set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), set_layout_helper(Klass::instance_layout_helper(parser.layout_size(),
false)); false));
@ -2193,7 +2193,7 @@ bool InstanceKlass::supers_have_passed_fingerprint_checks() {
return true; return true;
} }
bool InstanceKlass::should_store_fingerprint(bool is_anonymous) { bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) {
#if INCLUDE_AOT #if INCLUDE_AOT
// We store the fingerprint into the InstanceKlass only in the following 2 cases: // We store the fingerprint into the InstanceKlass only in the following 2 cases:
if (CalculateClassFingerprint) { if (CalculateClassFingerprint) {
@ -2204,8 +2204,8 @@ bool InstanceKlass::should_store_fingerprint(bool is_anonymous) {
// (2) We are running -Xshare:dump to create a shared archive // (2) We are running -Xshare:dump to create a shared archive
return true; return true;
} }
if (UseAOT && is_anonymous) { if (UseAOT && is_unsafe_anonymous) {
// (3) We are using AOT code from a shared library and see an anonymous class // (3) We are using AOT code from a shared library and see an unsafe anonymous class
return true; return true;
} }
#endif #endif
@ -2507,8 +2507,8 @@ const char* InstanceKlass::signature_name() const {
int hash_len = 0; int hash_len = 0;
char hash_buf[40]; char hash_buf[40];
// If this is an anonymous class, append a hash to make the name unique // If this is an unsafe anonymous class, append a hash to make the name unique
if (is_anonymous()) { if (is_unsafe_anonymous()) {
intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0; intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash); jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
hash_len = (int)strlen(hash_buf); hash_len = (int)strlen(hash_buf);
@ -2559,15 +2559,20 @@ Symbol* InstanceKlass::package_from_name(const Symbol* name, TRAPS) {
} }
ModuleEntry* InstanceKlass::module() const { ModuleEntry* InstanceKlass::module() const {
// For an unsafe anonymous class return the host class' module
if (is_unsafe_anonymous()) {
assert(unsafe_anonymous_host() != NULL, "unsafe anonymous class must have a host class");
return unsafe_anonymous_host()->module();
}
// Class is in a named package
if (!in_unnamed_package()) { if (!in_unnamed_package()) {
return _package_entry->module(); return _package_entry->module();
} }
const Klass* host = host_klass();
if (host == NULL) { // Class is in an unnamed package, return its loader's unnamed module
return class_loader_data()->unnamed_module(); return class_loader_data()->unnamed_module();
} }
return host->class_loader_data()->unnamed_module();
}
void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) { void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
@ -2813,7 +2818,7 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA
*inner_is_member = true; *inner_is_member = true;
} }
if (NULL == outer_klass) { if (NULL == outer_klass) {
// It may be anonymous; try for that. // It may be unsafe anonymous; try for that.
int encl_method_class_idx = enclosing_method_class_index(); int encl_method_class_idx = enclosing_method_class_index();
if (encl_method_class_idx != 0) { if (encl_method_class_idx != 0) {
Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL);
@ -3161,7 +3166,7 @@ void InstanceKlass::print_on(outputStream* st) const {
class_loader_data()->print_value_on(st); class_loader_data()->print_value_on(st);
st->cr(); st->cr();
} }
st->print(BULLET"host class: "); Metadata::print_value_on_maybe_null(st, host_klass()); st->cr(); st->print(BULLET"unsafe anonymous host class: "); Metadata::print_value_on_maybe_null(st, unsafe_anonymous_host()); st->cr();
if (source_file_name() != NULL) { if (source_file_name() != NULL) {
st->print(BULLET"source file: "); st->print(BULLET"source file: ");
source_file_name()->print_value_on(st); source_file_name()->print_value_on(st);
@ -3612,9 +3617,9 @@ void InstanceKlass::verify_on(outputStream* st) {
if (constants() != NULL) { if (constants() != NULL) {
guarantee(constants()->is_constantPool(), "should be constant pool"); guarantee(constants()->is_constantPool(), "should be constant pool");
} }
const Klass* host = host_klass(); const Klass* anonymous_host = unsafe_anonymous_host();
if (host != NULL) { if (anonymous_host != NULL) {
guarantee(host->is_klass(), "should be klass"); guarantee(anonymous_host->is_klass(), "should be klass");
} }
} }

View file

@ -54,7 +54,7 @@
// The embedded nonstatic oop-map blocks are short pairs (offset, length) // The embedded nonstatic oop-map blocks are short pairs (offset, length)
// indicating where oops are located in instances of this klass. // indicating where oops are located in instances of this klass.
// [EMBEDDED implementor of the interface] only exist for interface // [EMBEDDED implementor of the interface] only exist for interface
// [EMBEDDED host klass ] only exist for an anonymous class (JSR 292 enabled) // [EMBEDDED unsafe_anonymous_host klass] only exist for an unsafe anonymous class (JSR 292 enabled)
// [EMBEDDED fingerprint ] only if should_store_fingerprint()==true // [EMBEDDED fingerprint ] only if should_store_fingerprint()==true
@ -226,7 +226,7 @@ class InstanceKlass: public Klass {
_misc_rewritten = 1 << 2, // methods rewritten. _misc_rewritten = 1 << 2, // methods rewritten.
_misc_has_nonstatic_fields = 1 << 3, // for sizing with UseCompressedOops _misc_has_nonstatic_fields = 1 << 3, // for sizing with UseCompressedOops
_misc_should_verify_class = 1 << 4, // allow caching of preverification _misc_should_verify_class = 1 << 4, // allow caching of preverification
_misc_is_anonymous = 1 << 5, // has embedded _host_klass field _misc_is_unsafe_anonymous = 1 << 5, // has embedded _unsafe_anonymous_host field
_misc_is_contended = 1 << 6, // marked with contended annotation _misc_is_contended = 1 << 6, // marked with contended annotation
_misc_has_nonstatic_concrete_methods = 1 << 7, // class/superclass/implemented interfaces has non-static, concrete methods _misc_has_nonstatic_concrete_methods = 1 << 7, // class/superclass/implemented interfaces has non-static, concrete methods
_misc_declares_nonstatic_concrete_methods = 1 << 8, // directly declares non-static, concrete methods _misc_declares_nonstatic_concrete_methods = 1 << 8, // directly declares non-static, concrete methods
@ -315,11 +315,11 @@ class InstanceKlass: public Klass {
// NULL: no implementor. // NULL: no implementor.
// A Klass* that's not itself: one implementor. // A Klass* that's not itself: one implementor.
// Itself: more than one implementors. // Itself: more than one implementors.
// embedded host klass follows here // embedded unsafe_anonymous_host klass follows here
// The embedded host klass only exists in an anonymous class for // The embedded host klass only exists in an unsafe anonymous class for
// dynamic language support (JSR 292 enabled). The host class grants // dynamic language support (JSR 292 enabled). The host class grants
// its access privileges to this class also. The host class is either // its access privileges to this class also. The host class is either
// named, or a previously loaded anonymous class. A non-anonymous class // named, or a previously loaded unsafe anonymous class. A non-anonymous class
// or an anonymous class loaded through normal classloading does not // or an anonymous class loaded through normal classloading does not
// have this embedded field. // have this embedded field.
// //
@ -650,43 +650,40 @@ public:
objArrayOop signers() const; objArrayOop signers() const;
// host class // host class
InstanceKlass* host_klass() const { InstanceKlass* unsafe_anonymous_host() const {
InstanceKlass** hk = adr_host_klass(); InstanceKlass** hk = adr_unsafe_anonymous_host();
if (hk == NULL) { if (hk == NULL) {
assert(!is_anonymous(), "Anonymous classes have host klasses"); assert(!is_unsafe_anonymous(), "Unsafe anonymous classes have host klasses");
return NULL; return NULL;
} else { } else {
assert(*hk != NULL, "host klass should always be set if the address is not null"); assert(*hk != NULL, "host klass should always be set if the address is not null");
assert(is_anonymous(), "Only anonymous classes have host klasses"); assert(is_unsafe_anonymous(), "Only unsafe anonymous classes have host klasses");
return *hk; return *hk;
} }
} }
void set_host_klass(const InstanceKlass* host) { void set_unsafe_anonymous_host(const InstanceKlass* host) {
assert(is_anonymous(), "not anonymous"); assert(is_unsafe_anonymous(), "not unsafe anonymous");
const InstanceKlass** addr = (const InstanceKlass **)adr_host_klass(); const InstanceKlass** addr = (const InstanceKlass **)adr_unsafe_anonymous_host();
assert(addr != NULL, "no reversed space"); assert(addr != NULL, "no reversed space");
if (addr != NULL) { if (addr != NULL) {
*addr = host; *addr = host;
} }
} }
bool has_host_klass() const { bool is_unsafe_anonymous() const {
return adr_host_klass() != NULL; return (_misc_flags & _misc_is_unsafe_anonymous) != 0;
} }
bool is_anonymous() const { void set_is_unsafe_anonymous(bool value) {
return (_misc_flags & _misc_is_anonymous) != 0;
}
void set_is_anonymous(bool value) {
if (value) { if (value) {
_misc_flags |= _misc_is_anonymous; _misc_flags |= _misc_is_unsafe_anonymous;
} else { } else {
_misc_flags &= ~_misc_is_anonymous; _misc_flags &= ~_misc_is_unsafe_anonymous;
} }
} }
// Oop that keeps the metadata for this class from being unloaded // Oop that keeps the metadata for this class from being unloaded
// in places where the metadata is stored in other places, like nmethods // in places where the metadata is stored in other places, like nmethods
oop klass_holder() const { oop klass_holder() const {
return is_anonymous() ? java_mirror() : class_loader(); return (is_unsafe_anonymous()) ? java_mirror() : class_loader();
} }
bool is_contended() const { bool is_contended() const {
@ -780,8 +777,8 @@ public:
} }
bool supers_have_passed_fingerprint_checks(); bool supers_have_passed_fingerprint_checks();
static bool should_store_fingerprint(bool is_anonymous); static bool should_store_fingerprint(bool is_unsafe_anonymous);
bool should_store_fingerprint() const { return should_store_fingerprint(is_anonymous()); } bool should_store_fingerprint() const { return should_store_fingerprint(is_unsafe_anonymous()); }
bool has_stored_fingerprint() const; bool has_stored_fingerprint() const;
uint64_t get_stored_fingerprint() const; uint64_t get_stored_fingerprint() const;
void store_fingerprint(uint64_t fingerprint); void store_fingerprint(uint64_t fingerprint);
@ -1063,20 +1060,20 @@ public:
static int size(int vtable_length, int itable_length, static int size(int vtable_length, int itable_length,
int nonstatic_oop_map_size, int nonstatic_oop_map_size,
bool is_interface, bool is_anonymous, bool has_stored_fingerprint) { bool is_interface, bool is_unsafe_anonymous, bool has_stored_fingerprint) {
return align_metadata_size(header_size() + return align_metadata_size(header_size() +
vtable_length + vtable_length +
itable_length + itable_length +
nonstatic_oop_map_size + nonstatic_oop_map_size +
(is_interface ? (int)sizeof(Klass*)/wordSize : 0) + (is_interface ? (int)sizeof(Klass*)/wordSize : 0) +
(is_anonymous ? (int)sizeof(Klass*)/wordSize : 0) + (is_unsafe_anonymous ? (int)sizeof(Klass*)/wordSize : 0) +
(has_stored_fingerprint ? (int)sizeof(uint64_t*)/wordSize : 0)); (has_stored_fingerprint ? (int)sizeof(uint64_t*)/wordSize : 0));
} }
int size() const { return size(vtable_length(), int size() const { return size(vtable_length(),
itable_length(), itable_length(),
nonstatic_oop_map_size(), nonstatic_oop_map_size(),
is_interface(), is_interface(),
is_anonymous(), is_unsafe_anonymous(),
has_stored_fingerprint()); has_stored_fingerprint());
} }
#if INCLUDE_SERVICES #if INCLUDE_SERVICES
@ -1107,8 +1104,8 @@ public:
} }
}; };
InstanceKlass** adr_host_klass() const { InstanceKlass** adr_unsafe_anonymous_host() const {
if (is_anonymous()) { if (is_unsafe_anonymous()) {
InstanceKlass** adr_impl = (InstanceKlass **)adr_implementor(); InstanceKlass** adr_impl = (InstanceKlass **)adr_implementor();
if (adr_impl != NULL) { if (adr_impl != NULL) {
return adr_impl + 1; return adr_impl + 1;
@ -1122,7 +1119,7 @@ public:
address adr_fingerprint() const { address adr_fingerprint() const {
if (has_stored_fingerprint()) { if (has_stored_fingerprint()) {
InstanceKlass** adr_host = adr_host_klass(); InstanceKlass** adr_host = adr_unsafe_anonymous_host();
if (adr_host != NULL) { if (adr_host != NULL) {
return (address)(adr_host + 1); return (address)(adr_host + 1);
} }

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,9 +51,10 @@ void InstanceMirrorKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
Klass* klass = java_lang_Class::as_Klass(obj); Klass* klass = java_lang_Class::as_Klass(obj);
// We'll get NULL for primitive mirrors. // We'll get NULL for primitive mirrors.
if (klass != NULL) { if (klass != NULL) {
if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) { if (klass->is_instance_klass() &&
// An anonymous class doesn't have its own class loader, so when handling InstanceKlass::cast(klass)->is_unsafe_anonymous()) {
// the java mirror for an anonymous class we need to make sure its class // An unsafe anonymous class doesn't have its own class loader, so
// when handling the java mirror for the class we need to make sure its class
// loader data is claimed, this is done by calling do_cld explicitly. // loader data is claimed, this is done by calling do_cld explicitly.
// For non-anonymous classes the call to do_cld is made when the class // For non-anonymous classes the call to do_cld is made when the class
// loader itself is handled. // loader itself is handled.

View file

@ -612,7 +612,7 @@ oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
const char* Klass::external_name() const { const char* Klass::external_name() const {
if (is_instance_klass()) { if (is_instance_klass()) {
const InstanceKlass* ik = static_cast<const InstanceKlass*>(this); const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
if (ik->is_anonymous()) { if (ik->is_unsafe_anonymous()) {
char addr_buf[20]; char addr_buf[20];
jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik)); jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
size_t addr_len = strlen(addr_buf); size_t addr_len = strlen(addr_buf);

View file

@ -654,7 +654,7 @@ protected:
virtual void metaspace_pointers_do(MetaspaceClosure* iter); virtual void metaspace_pointers_do(MetaspaceClosure* iter);
virtual MetaspaceObj::Type type() const { return ClassType; } virtual MetaspaceObj::Type type() const { return ClassType; }
// Iff the class loader (or mirror for anonymous classes) is alive the // Iff the class loader (or mirror for unsafe anonymous classes) is alive the
// Klass is considered alive. Has already been marked as unloading. // Klass is considered alive. Has already been marked as unloading.
bool is_loader_alive() const { return !class_loader_data()->is_unloading(); } bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }

View file

@ -510,7 +510,7 @@ void Parse::do_call() {
if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) { if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) {
ciInstanceKlass* calling_klass = method()->holder(); ciInstanceKlass* calling_klass = method()->holder();
ciInstanceKlass* sender_klass = ciInstanceKlass* sender_klass =
calling_klass->is_anonymous() ? calling_klass->host_klass() : calling_klass->is_unsafe_anonymous() ? calling_klass->unsafe_anonymous_host() :
calling_klass; calling_klass;
if (sender_klass->is_interface()) { if (sender_klass->is_interface()) {
receiver_constraint = sender_klass; receiver_constraint = sender_klass;

View file

@ -136,7 +136,7 @@ bool VM_RedefineClasses::doit_prologue() {
} }
oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
// classes for primitives and arrays and vm anonymous classes cannot be redefined // classes for primitives and arrays and vm unsafe anonymous classes cannot be redefined
// check here so following code can assume these classes are InstanceKlass // check here so following code can assume these classes are InstanceKlass
if (!is_modifiable_class(mirror)) { if (!is_modifiable_class(mirror)) {
_res = JVMTI_ERROR_UNMODIFIABLE_CLASS; _res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
@ -278,8 +278,8 @@ bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
return false; return false;
} }
// Cannot redefine or retransform an anonymous class. // Cannot redefine or retransform an unsafe anonymous class.
if (InstanceKlass::cast(k)->is_anonymous()) { if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
return false; return false;
} }
return true; return true;
@ -2650,7 +2650,7 @@ bool VM_RedefineClasses::skip_type_annotation_target(
case 0x10: case 0x10:
// kind: type in extends clause of class or interface declaration // kind: type in extends clause of class or interface declaration
// (including the direct superclass of an anonymous class declaration), // (including the direct superclass of an unsafe anonymous class declaration),
// or in implements clause of interface declaration // or in implements clause of interface declaration
// location: ClassFile // location: ClassFile

View file

@ -776,8 +776,8 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
// Make sure it's the real host class, not another anonymous class. // Make sure it's the real host class, not another anonymous class.
while (host_klass != NULL && host_klass->is_instance_klass() && while (host_klass != NULL && host_klass->is_instance_klass() &&
InstanceKlass::cast(host_klass)->is_anonymous()) { InstanceKlass::cast(host_klass)->is_unsafe_anonymous()) {
host_klass = InstanceKlass::cast(host_klass)->host_klass(); host_klass = InstanceKlass::cast(host_klass)->unsafe_anonymous_host();
} }
// Primitive types have NULL Klass* fields in their java.lang.Class instances. // Primitive types have NULL Klass* fields in their java.lang.Class instances.

View file

@ -424,18 +424,18 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
return result; return result;
} }
static bool under_host_klass(const InstanceKlass* ik, const InstanceKlass* host_klass) { static bool under_unsafe_anonymous_host(const InstanceKlass* ik, const InstanceKlass* unsafe_anonymous_host) {
DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
for (;;) { for (;;) {
const InstanceKlass* hc = ik->host_klass(); const InstanceKlass* hc = ik->unsafe_anonymous_host();
if (hc == NULL) return false; if (hc == NULL) return false;
if (hc == host_klass) return true; if (hc == unsafe_anonymous_host) return true;
ik = hc; ik = hc;
// There's no way to make a host class loop short of patching memory. // There's no way to make a host class loop short of patching memory.
// Therefore there cannot be a loop here unless there's another bug. // Therefore there cannot be a loop here unless there's another bug.
// Still, let's check for it. // Still, let's check for it.
assert(--inf_loop_check > 0, "no host_klass loop"); assert(--inf_loop_check > 0, "no unsafe_anonymous_host loop");
} }
} }
@ -446,10 +446,10 @@ static bool can_relax_access_check_for(const Klass* accessor,
const InstanceKlass* accessor_ik = InstanceKlass::cast(accessor); const InstanceKlass* accessor_ik = InstanceKlass::cast(accessor);
const InstanceKlass* accessee_ik = InstanceKlass::cast(accessee); const InstanceKlass* accessee_ik = InstanceKlass::cast(accessee);
// If either is on the other's host_klass chain, access is OK, // If either is on the other's unsafe_anonymous_host chain, access is OK,
// because one is inside the other. // because one is inside the other.
if (under_host_klass(accessor_ik, accessee_ik) || if (under_unsafe_anonymous_host(accessor_ik, accessee_ik) ||
under_host_klass(accessee_ik, accessor_ik)) under_unsafe_anonymous_host(accessee_ik, accessor_ik))
return true; return true;
if ((RelaxAccessControlCheck && if ((RelaxAccessControlCheck &&
@ -676,13 +676,13 @@ bool Reflection::verify_member_access(const Klass* current_class,
} }
const Klass* host_class = current_class; const Klass* host_class = current_class;
if (host_class->is_instance_klass() && if (current_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()) { InstanceKlass::cast(current_class)->is_unsafe_anonymous()) {
host_class = InstanceKlass::cast(host_class)->host_klass(); host_class = InstanceKlass::cast(current_class)->unsafe_anonymous_host();
assert(host_class != NULL, "Anonymous class has null host class"); assert(host_class != NULL, "Unsafe anonymous class has null host class");
assert(!(host_class->is_instance_klass() && assert(!(host_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()), InstanceKlass::cast(host_class)->is_unsafe_anonymous()),
"host_class should not be anonymous"); "unsafe_anonymous_host should not be unsafe anonymous itself");
} }
if (host_class == member_class) { if (host_class == member_class) {
return true; return true;
@ -710,7 +710,7 @@ bool Reflection::verify_member_access(const Klass* current_class,
} }
// private access between different classes needs a nestmate check, but // private access between different classes needs a nestmate check, but
// not for anonymous classes - so check host_class // not for unsafe anonymous classes - so check host_class
if (access.is_private() && host_class == current_class) { if (access.is_private() && host_class == current_class) {
if (current_class->is_instance_klass() && member_class->is_instance_klass() ) { if (current_class->is_instance_klass() && member_class->is_instance_klass() ) {
InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class)); InstanceKlass* cur_ik = const_cast<InstanceKlass*>(InstanceKlass::cast(current_class));
@ -742,7 +742,7 @@ bool Reflection::is_same_class_package(const Klass* class1, const Klass* class2)
// Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not,
// throw an incompatible class change exception // throw an incompatible class change exception
// If inner_is_member, require the inner to be a member of the outer. // If inner_is_member, require the inner to be a member of the outer.
// If !inner_is_member, require the inner to be anonymous (a non-member). // If !inner_is_member, require the inner to be unsafe anonymous (a non-member).
// Caller is responsible for figuring out in advance which case must be true. // Caller is responsible for figuring out in advance which case must be true.
void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner, void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner,
bool inner_is_member, TRAPS) { bool inner_is_member, TRAPS) {

View file

@ -516,7 +516,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
nonstatic_field(ClassLoaderData, _class_loader, OopHandle) \ nonstatic_field(ClassLoaderData, _class_loader, OopHandle) \
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \ nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
volatile_nonstatic_field(ClassLoaderData, _klasses, Klass*) \ volatile_nonstatic_field(ClassLoaderData, _klasses, Klass*) \
nonstatic_field(ClassLoaderData, _is_anonymous, bool) \ nonstatic_field(ClassLoaderData, _is_unsafe_anonymous, bool) \
volatile_nonstatic_field(ClassLoaderData, _dictionary, Dictionary*) \ volatile_nonstatic_field(ClassLoaderData, _dictionary, Dictionary*) \
\ \
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \ static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
@ -2267,7 +2267,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
declare_constant(InstanceKlass::_misc_rewritten) \ declare_constant(InstanceKlass::_misc_rewritten) \
declare_constant(InstanceKlass::_misc_has_nonstatic_fields) \ declare_constant(InstanceKlass::_misc_has_nonstatic_fields) \
declare_constant(InstanceKlass::_misc_should_verify_class) \ declare_constant(InstanceKlass::_misc_should_verify_class) \
declare_constant(InstanceKlass::_misc_is_anonymous) \ declare_constant(InstanceKlass::_misc_is_unsafe_anonymous) \
declare_constant(InstanceKlass::_misc_is_contended) \ declare_constant(InstanceKlass::_misc_is_contended) \
declare_constant(InstanceKlass::_misc_has_nonstatic_concrete_methods) \ declare_constant(InstanceKlass::_misc_has_nonstatic_concrete_methods) \
declare_constant(InstanceKlass::_misc_declares_nonstatic_concrete_methods)\ declare_constant(InstanceKlass::_misc_declares_nonstatic_concrete_methods)\

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,7 +74,7 @@ final class AOTCompiledClass {
this.dependentMethods = new ArrayList<>(); this.dependentMethods = new ArrayList<>();
this.classId = classId; this.classId = classId;
this.type = type; this.type = type;
this.metadataName = type.isAnonymous() ? "anon<" + classId + ">" : type.getName(); this.metadataName = type.isUnsafeAnonymous() ? "anon<" + classId + ">" : type.getName();
this.gotIndex = binaryContainer.addTwoSlotKlassSymbol(metadataName); this.gotIndex = binaryContainer.addTwoSlotKlassSymbol(metadataName);
this.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods. this.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods.
this.dependentMethodsOffset = -1; this.dependentMethodsOffset = -1;

View file

@ -45,14 +45,14 @@ public class ClassLoaderData extends VMObject {
classLoaderField = type.getAddressField("_class_loader"); classLoaderField = type.getAddressField("_class_loader");
nextField = type.getAddressField("_next"); nextField = type.getAddressField("_next");
klassesField = new MetadataField(type.getAddressField("_klasses"), 0); klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
isAnonymousField = new CIntField(type.getCIntegerField("_is_anonymous"), 0); isUnsafeAnonymousField = new CIntField(type.getCIntegerField("_is_unsafe_anonymous"), 0);
dictionaryField = type.getAddressField("_dictionary"); dictionaryField = type.getAddressField("_dictionary");
} }
private static AddressField classLoaderField; private static AddressField classLoaderField;
private static AddressField nextField; private static AddressField nextField;
private static MetadataField klassesField; private static MetadataField klassesField;
private static CIntField isAnonymousField; private static CIntField isUnsafeAnonymousField;
private static AddressField dictionaryField; private static AddressField dictionaryField;
public ClassLoaderData(Address addr) { public ClassLoaderData(Address addr) {
@ -81,8 +81,8 @@ public class ClassLoaderData extends VMObject {
return null; return null;
} }
public boolean getIsAnonymous() { public boolean getisUnsafeAnonymous() {
return isAnonymousField.getValue(this) != 0; return isUnsafeAnonymousField.getValue(this) != 0;
} }
public ClassLoaderData next() { public ClassLoaderData next() {

View file

@ -69,7 +69,7 @@ public class InstanceKlass extends Klass {
private static int MISC_REWRITTEN; private static int MISC_REWRITTEN;
private static int MISC_HAS_NONSTATIC_FIELDS; private static int MISC_HAS_NONSTATIC_FIELDS;
private static int MISC_SHOULD_VERIFY_CLASS; private static int MISC_SHOULD_VERIFY_CLASS;
private static int MISC_IS_ANONYMOUS; private static int MISC_IS_UNSAFE_ANONYMOUS;
private static int MISC_IS_CONTENDED; private static int MISC_IS_CONTENDED;
private static int MISC_HAS_NONSTATIC_CONCRETE_METHODS; private static int MISC_HAS_NONSTATIC_CONCRETE_METHODS;
private static int MISC_DECLARES_NONSTATIC_CONCRETE_METHODS; private static int MISC_DECLARES_NONSTATIC_CONCRETE_METHODS;
@ -133,7 +133,7 @@ public class InstanceKlass extends Klass {
MISC_REWRITTEN = db.lookupIntConstant("InstanceKlass::_misc_rewritten").intValue(); MISC_REWRITTEN = db.lookupIntConstant("InstanceKlass::_misc_rewritten").intValue();
MISC_HAS_NONSTATIC_FIELDS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_fields").intValue(); MISC_HAS_NONSTATIC_FIELDS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_fields").intValue();
MISC_SHOULD_VERIFY_CLASS = db.lookupIntConstant("InstanceKlass::_misc_should_verify_class").intValue(); MISC_SHOULD_VERIFY_CLASS = db.lookupIntConstant("InstanceKlass::_misc_should_verify_class").intValue();
MISC_IS_ANONYMOUS = db.lookupIntConstant("InstanceKlass::_misc_is_anonymous").intValue(); MISC_IS_UNSAFE_ANONYMOUS = db.lookupIntConstant("InstanceKlass::_misc_is_unsafe_anonymous").intValue();
MISC_IS_CONTENDED = db.lookupIntConstant("InstanceKlass::_misc_is_contended").intValue(); MISC_IS_CONTENDED = db.lookupIntConstant("InstanceKlass::_misc_is_contended").intValue();
MISC_HAS_NONSTATIC_CONCRETE_METHODS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_concrete_methods").intValue(); MISC_HAS_NONSTATIC_CONCRETE_METHODS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_concrete_methods").intValue();
MISC_DECLARES_NONSTATIC_CONCRETE_METHODS = db.lookupIntConstant("InstanceKlass::_misc_declares_nonstatic_concrete_methods").intValue(); MISC_DECLARES_NONSTATIC_CONCRETE_METHODS = db.lookupIntConstant("InstanceKlass::_misc_declares_nonstatic_concrete_methods").intValue();
@ -281,7 +281,7 @@ public class InstanceKlass extends Klass {
if (isInterface()) { if (isInterface()) {
size += wordLength; size += wordLength;
} }
if (isAnonymous()) { if (isUnsafeAnonymous()) {
size += wordLength; size += wordLength;
} }
if (hasStoredFingerprint()) { if (hasStoredFingerprint()) {
@ -294,8 +294,8 @@ public class InstanceKlass extends Klass {
return (int) miscFlags.getValue(this); return (int) miscFlags.getValue(this);
} }
public boolean isAnonymous() { public boolean isUnsafeAnonymous() {
return (getMiscFlags() & MISC_IS_ANONYMOUS) != 0; return (getMiscFlags() & MISC_IS_UNSAFE_ANONYMOUS) != 0;
} }
public static boolean shouldStoreFingerprint() { public static boolean shouldStoreFingerprint() {

View file

@ -522,7 +522,7 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceWrapper
return lookupType(cpi, opcode); return lookupType(cpi, opcode);
case String: case String:
/* /*
* Normally, we would expect a String here, but anonymous classes can have * Normally, we would expect a String here, but unsafe anonymous classes can have
* "pseudo strings" (arbitrary live objects) patched into a String entry. Such * "pseudo strings" (arbitrary live objects) patched into a String entry. Such
* entries do not have a symbol in the constant pool slot. * entries do not have a symbol in the constant pool slot.
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -110,6 +110,6 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
@Override @Override
ResolvedJavaMethod getClassInitializer(); ResolvedJavaMethod getClassInitializer();
boolean isAnonymous(); boolean isUnsafeAnonymous();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -985,8 +985,8 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
} }
@Override @Override
public boolean isAnonymous() { public boolean isUnsafeAnonymous() {
return (getMiscFlags() & config().instanceKlassMiscIsAnonymous) != 0; return (getMiscFlags() & config().instanceKlassMiscIsUnsafeAnonymous) != 0;
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -100,7 +100,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class); final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class);
final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class); final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class);
final int instanceKlassMiscIsAnonymous = getConstant("InstanceKlass::_misc_is_anonymous", Integer.class); final int instanceKlassMiscIsUnsafeAnonymous = getConstant("InstanceKlass::_misc_is_unsafe_anonymous", Integer.class);
final int arrayU1LengthOffset = getFieldOffset("Array<int>::_length", Integer.class, "int"); final int arrayU1LengthOffset = getFieldOffset("Array<int>::_length", Integer.class, "int");
final int arrayU1DataOffset = getFieldOffset("Array<u1>::_data", Integer.class); final int arrayU1DataOffset = getFieldOffset("Array<u1>::_data", Integer.class);

View file

@ -102,9 +102,9 @@ protected:
_spaces[i].lock = new Mutex(Monitor::native, "gtest-MetaspaceAllocationTest-lock", false, Monitor::_safepoint_check_never); _spaces[i].lock = new Mutex(Monitor::native, "gtest-MetaspaceAllocationTest-lock", false, Monitor::_safepoint_check_never);
ASSERT_TRUE(_spaces[i].lock != NULL); ASSERT_TRUE(_spaces[i].lock != NULL);
} }
// Let every ~10th space be an anonymous one to test different allocation patterns. // Let every ~10th space be an unsafe anonymous one to test different allocation patterns.
const Metaspace::MetaspaceType msType = (os::random() % 100 < 10) ? const Metaspace::MetaspaceType msType = (os::random() % 100 < 10) ?
Metaspace::AnonymousMetaspaceType : Metaspace::StandardMetaspaceType; Metaspace::UnsafeAnonymousMetaspaceType : Metaspace::StandardMetaspaceType;
{ {
// Pull lock during space creation, since this is what happens in the VM too // Pull lock during space creation, since this is what happens in the VM too
// (see ClassLoaderData::metaspace_non_null(), which we mimick here). // (see ClassLoaderData::metaspace_non_null(), which we mimick here).

View file

@ -114,7 +114,7 @@ public class TestIntConstant {
{"CollectedHeap::G1 4", {"CollectedHeap::G1 4",
"RUNNABLE 2", "RUNNABLE 2",
"Deoptimization::Reason_class_check 4", "Deoptimization::Reason_class_check 4",
"InstanceKlass::_misc_is_anonymous 32", "InstanceKlass::_misc_is_unsafe_anonymous 32",
"Generation::ParNew 1", "Generation::ParNew 1",
"_thread_uninitialized 0"}; "_thread_uninitialized 0"};
String[] tempConstantString = {"intConstant _temp_constant 45"}; String[] tempConstantString = {"intConstant _temp_constant 45"};

View file

@ -76,9 +76,9 @@ public class TestClassLoaderStatsEvent {
Events.assertField(event, "classCount").equal(1L); Events.assertField(event, "classCount").equal(1L);
Events.assertField(event, "chunkSize").above(1L); Events.assertField(event, "chunkSize").above(1L);
Events.assertField(event, "blockSize").above(1L); Events.assertField(event, "blockSize").above(1L);
Events.assertField(event, "anonymousClassCount").equal(1L); Events.assertField(event, "unsafeAnonymousClassCount").equal(1L);
Events.assertField(event, "anonymousChunkSize").above(1L); Events.assertField(event, "unsafeAnonymousChunkSize").above(1L);
Events.assertField(event, "anonymousBlockSize").above(1L); Events.assertField(event, "unsafeAnonymousBlockSize").above(1L);
isAnyFound = true; isAnyFound = true;
} }
} }