mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
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:
parent
6ccb60937c
commit
75ed173e15
64 changed files with 359 additions and 354 deletions
|
@ -1006,7 +1006,7 @@ bool AOTCodeHeap::reconcile_dynamic_klass(AOTCompiledMethod *caller, InstanceKla
|
|||
|
||||
InstanceKlass* dyno = InstanceKlass::cast(dyno_klass);
|
||||
|
||||
if (!dyno->is_anonymous()) {
|
||||
if (!dyno->is_unsafe_anonymous()) {
|
||||
if (_klasses_got[dyno_data->_got_index] != dyno) {
|
||||
// compile-time class different from runtime class, fail and deoptimize
|
||||
sweep_dependent_methods(holder_data);
|
||||
|
|
|
@ -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)
|
||||
|
||||
void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) {
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
// don't even bother
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) {
|
|||
}
|
||||
|
||||
uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) {
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
// don't even bother
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1844,7 +1844,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
|||
// invoke-special-super
|
||||
if (bc_raw == Bytecodes::_invokespecial && !target->is_object_initializer()) {
|
||||
ciInstanceKlass* sender_klass =
|
||||
calling_klass->is_anonymous() ? calling_klass->host_klass() :
|
||||
calling_klass->is_unsafe_anonymous() ? calling_klass->unsafe_anonymous_host() :
|
||||
calling_klass;
|
||||
if (sender_klass->is_interface()) {
|
||||
int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);
|
||||
|
|
|
@ -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.
|
||||
if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke"))
|
||||
return true;
|
||||
// Trust VM anonymous classes. They are private API (sun.misc.Unsafe) and can't be serialized,
|
||||
// so there is no hacking of finals going on with them.
|
||||
if (holder->is_anonymous())
|
||||
// Trust VM unsafe anonymous classes. They are private API (jdk.internal.misc.Unsafe)
|
||||
// and can't be serialized, so there is no hacking of finals going on with them.
|
||||
if (holder->is_unsafe_anonymous())
|
||||
return true;
|
||||
// Trust final fields in all boxed classes
|
||||
if (holder->is_box_klass())
|
||||
|
|
|
@ -62,7 +62,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) :
|
|||
_nonstatic_field_size = ik->nonstatic_field_size();
|
||||
_has_nonstatic_fields = ik->has_nonstatic_fields();
|
||||
_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:
|
||||
_has_injected_fields = -1;
|
||||
_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
|
||||
// alive covers the cases where there are weak roots without performance cost.
|
||||
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
|
||||
// VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
|
||||
// It is enough to record a ciObject, since cached elements are never removed
|
||||
// VM unsafe anonymous classes alive (loader == NULL). Klass holder should
|
||||
// be used instead. It is enough to record a ciObject, since cached elements are never removed
|
||||
// during ciObjectFactory lifetime. ciObjectFactory itself is created for
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name,
|
|||
_has_nonstatic_fields = false;
|
||||
_nonstatic_fields = NULL;
|
||||
_has_injected_fields = -1;
|
||||
_is_anonymous = false;
|
||||
_is_unsafe_anonymous = false;
|
||||
_loader = loader;
|
||||
_protection_domain = protection_domain;
|
||||
_is_shared = false;
|
||||
|
@ -615,12 +615,12 @@ ciInstanceKlass* ciInstanceKlass::implementor() {
|
|||
return impl;
|
||||
}
|
||||
|
||||
ciInstanceKlass* ciInstanceKlass::host_klass() {
|
||||
ciInstanceKlass* ciInstanceKlass::unsafe_anonymous_host() {
|
||||
assert(is_loaded(), "must be loaded");
|
||||
if (is_anonymous()) {
|
||||
if (is_unsafe_anonymous()) {
|
||||
VM_ENTRY_MARK
|
||||
Klass* host_klass = get_instanceKlass()->host_klass();
|
||||
return CURRENT_ENV->get_instance_klass(host_klass);
|
||||
Klass* unsafe_anonymous_host = get_instanceKlass()->unsafe_anonymous_host();
|
||||
return CURRENT_ENV->get_instance_klass(unsafe_anonymous_host);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -53,7 +53,7 @@ private:
|
|||
bool _has_subklass;
|
||||
bool _has_nonstatic_fields;
|
||||
bool _has_nonstatic_concrete_methods;
|
||||
bool _is_anonymous;
|
||||
bool _is_unsafe_anonymous;
|
||||
|
||||
ciFlags _flags;
|
||||
jint _nonstatic_field_size;
|
||||
|
@ -179,8 +179,8 @@ public:
|
|||
return _has_nonstatic_concrete_methods;
|
||||
}
|
||||
|
||||
bool is_anonymous() {
|
||||
return _is_anonymous;
|
||||
bool is_unsafe_anonymous() {
|
||||
return _is_unsafe_anonymous;
|
||||
}
|
||||
|
||||
ciInstanceKlass* get_canonical_holder(int offset);
|
||||
|
@ -260,7 +260,7 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ciInstanceKlass* host_klass();
|
||||
ciInstanceKlass* unsafe_anonymous_host();
|
||||
|
||||
bool can_be_instantiated() {
|
||||
assert(is_loaded(), "must be loaded");
|
||||
|
|
|
@ -2091,7 +2091,7 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
|
|||
// Privileged code can use all annotations. Other code silently drops some.
|
||||
const bool privileged = loader_data->is_the_null_class_loader_data() ||
|
||||
loader_data->is_platform_class_loader_data() ||
|
||||
loader_data->is_anonymous();
|
||||
loader_data->is_unsafe_anonymous();
|
||||
switch (sid) {
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): {
|
||||
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);
|
||||
|
||||
if (is_anonymous()) {
|
||||
if (is_unsafe_anonymous()) {
|
||||
// _this_class_index is a CONSTANT_Class entry that refers to this
|
||||
// anonymous class itself. If this class needs to refer to its own methods or
|
||||
// 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_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods);
|
||||
|
||||
if (_host_klass != NULL) {
|
||||
assert (ik->is_anonymous(), "should be the same");
|
||||
ik->set_host_klass(_host_klass);
|
||||
if (_unsafe_anonymous_host != NULL) {
|
||||
assert (ik->is_unsafe_anonymous(), "should be the same");
|
||||
ik->set_unsafe_anonymous_host(_unsafe_anonymous_host);
|
||||
}
|
||||
|
||||
// Set PackageEntry for this_klass
|
||||
|
@ -5760,15 +5760,15 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
|
|||
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
|
||||
// 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);
|
||||
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 =
|
||||
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) {
|
||||
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 /.
|
||||
strncpy(new_anon_name, host_pkg_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...").
|
||||
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
|
||||
// host's package. If the classes are in different packages then throw an IAE
|
||||
// exception.
|
||||
void ClassFileParser::fix_anonymous_class_name(TRAPS) {
|
||||
assert(_host_klass != NULL, "Expected an anonymous class");
|
||||
void ClassFileParser::fix_unsafe_anonymous_class_name(TRAPS) {
|
||||
assert(_unsafe_anonymous_host != NULL, "Expected an unsafe anonymous class");
|
||||
|
||||
const jbyte* anon_last_slash = UTF8::strrchr(_class_name->base(),
|
||||
_class_name->utf8_length(), '/');
|
||||
if (anon_last_slash == NULL) { // Unnamed package
|
||||
prepend_host_package_name(_host_klass, CHECK);
|
||||
prepend_host_package_name(_unsafe_anonymous_host, CHECK);
|
||||
} 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);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
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,
|
||||
ClassLoaderData* loader_data,
|
||||
Handle protection_domain,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
Publicity pub_level,
|
||||
TRAPS) :
|
||||
_stream(stream),
|
||||
_requested_name(name),
|
||||
_loader_data(loader_data),
|
||||
_host_klass(host_klass),
|
||||
_unsafe_anonymous_host(unsafe_anonymous_host),
|
||||
_cp_patches(cp_patches),
|
||||
_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
|
||||
// package. Otherwise, throw IAE if it is in a different package than
|
||||
// its host class.
|
||||
if (_host_klass != NULL) {
|
||||
fix_anonymous_class_name(CHECK);
|
||||
if (_unsafe_anonymous_host != NULL) {
|
||||
fix_unsafe_anonymous_class_name(CHECK);
|
||||
}
|
||||
|
||||
// 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");
|
||||
DumpLoadedClassList = NULL;
|
||||
} 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.
|
||||
// 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();
|
||||
ResourceMark rm(THREAD);
|
||||
bool skip = false;
|
||||
|
|
|
@ -82,7 +82,7 @@ class ClassFileParser {
|
|||
const Symbol* _requested_name;
|
||||
Symbol* _class_name;
|
||||
mutable ClassLoaderData* _loader_data;
|
||||
const InstanceKlass* _host_klass;
|
||||
const InstanceKlass* _unsafe_anonymous_host;
|
||||
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
|
||||
int _num_patched_klasses;
|
||||
int _max_num_patched_klasses;
|
||||
|
@ -173,8 +173,8 @@ class ClassFileParser {
|
|||
ConstantPool* cp,
|
||||
TRAPS);
|
||||
|
||||
void prepend_host_package_name(const InstanceKlass* host_klass, TRAPS);
|
||||
void fix_anonymous_class_name(TRAPS);
|
||||
void prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS);
|
||||
void fix_unsafe_anonymous_class_name(TRAPS);
|
||||
|
||||
void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS);
|
||||
void set_klass(InstanceKlass* instance);
|
||||
|
@ -501,7 +501,7 @@ class ClassFileParser {
|
|||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
Handle protection_domain,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
Publicity pub_level,
|
||||
TRAPS);
|
||||
|
@ -524,10 +524,10 @@ class ClassFileParser {
|
|||
u2 this_class_index() const { return _this_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(); }
|
||||
|
||||
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; }
|
||||
ClassLoaderData* loader_data() const { return _loader_data; }
|
||||
const Symbol* class_name() const { return _class_name; }
|
||||
|
|
|
@ -1400,7 +1400,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
|
|||
name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
NULL, // host_klass
|
||||
NULL, // unsafe_anonymous_host
|
||||
NULL, // cp_patches
|
||||
THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
|
@ -1443,8 +1443,8 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
|
|||
assert(DumpSharedSpaces, "sanity");
|
||||
assert(stream != NULL, "sanity");
|
||||
|
||||
if (ik->is_anonymous()) {
|
||||
// We do not archive anonymous classes.
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
// We do not archive unsafe anonymous classes.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,16 +141,16 @@ void ClassLoaderData::initialize_name(Handle class_loader) {
|
|||
_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_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
|
||||
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),
|
||||
// An anonymous class loader data doesn't have anything to keep
|
||||
// it from being unloaded during parsing of the anonymous class.
|
||||
// An unsafe anonymous class loader data doesn't have anything to keep
|
||||
// it from being unloaded during parsing of the unsafe anonymous class.
|
||||
// The null-class-loader should always be kept alive.
|
||||
_keep_alive((is_anonymous || h_class_loader.is_null()) ? 1 : 0),
|
||||
_keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0),
|
||||
_claimed(0),
|
||||
_handles(),
|
||||
_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();
|
||||
}
|
||||
|
||||
if (!is_anonymous) {
|
||||
// The holder is initialized later for anonymous classes, and before calling anything
|
||||
if (!is_unsafe_anonymous) {
|
||||
// The holder is initialized later for unsafe anonymous classes, and before calling anything
|
||||
// that call class_loader().
|
||||
initialize_holder(h_class_loader);
|
||||
|
||||
// A ClassLoaderData created solely for an 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
|
||||
// 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);
|
||||
if (h_class_loader.is_null()) {
|
||||
// Create unnamed module for boot loader
|
||||
|
@ -287,20 +287,20 @@ bool ClassLoaderData::claim() {
|
|||
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.
|
||||
// Due to the uniqueness that no other class shares the anonymous class' name or
|
||||
// ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while
|
||||
// Due to the uniqueness that no other class shares the unsafe anonymous class' name or
|
||||
// ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while
|
||||
// it is being defined, therefore _keep_alive is not volatile or atomic.
|
||||
void ClassLoaderData::inc_keep_alive() {
|
||||
if (is_anonymous()) {
|
||||
if (is_unsafe_anonymous()) {
|
||||
assert(_keep_alive >= 0, "Invalid keep alive increment count");
|
||||
_keep_alive++;
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::dec_keep_alive() {
|
||||
if (is_anonymous()) {
|
||||
if (is_unsafe_anonymous()) {
|
||||
assert(_keep_alive > 0, "Invalid keep alive decrement count");
|
||||
_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
|
||||
// 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
|
||||
// anonymous.)
|
||||
// unsafe anonymous.)
|
||||
if (to_cld->is_permanent_class_loader_data()) {
|
||||
return;
|
||||
}
|
||||
|
||||
oop to;
|
||||
if (to_cld->is_anonymous()) {
|
||||
// Just return if an anonymous class is attempting to record a dependency
|
||||
// to itself. (Note that every anonymous class has its own unique class
|
||||
if (to_cld->is_unsafe_anonymous()) {
|
||||
// Just return if an unsafe anonymous class is attempting to record a dependency
|
||||
// to itself. (Note that every unsafe anonymous class has its own unique class
|
||||
// loader data.)
|
||||
if (to_cld == from_cld) {
|
||||
return;
|
||||
}
|
||||
// Anonymous class dependencies are through the mirror.
|
||||
// Unsafe anonymous class dependencies are through the mirror.
|
||||
to = k->java_mirror();
|
||||
} else {
|
||||
to = to_cld->class_loader();
|
||||
|
@ -640,7 +640,7 @@ const int _boot_loader_dictionary_size = 1009;
|
|||
const int _default_loader_dictionary_size = 107;
|
||||
|
||||
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;
|
||||
bool resizable = false;
|
||||
if (_the_null_class_loader_data == NULL) {
|
||||
|
@ -677,7 +677,7 @@ oop ClassLoaderData::holder_phantom() const {
|
|||
|
||||
// Unloading support
|
||||
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.
|
||||
|
||||
return alive;
|
||||
|
@ -767,13 +767,13 @@ ClassLoaderData::~ClassLoaderData() {
|
|||
|
||||
// Returns true if this class loader data is for the app class loader
|
||||
// or a user defined system class loader. (Note that the class loader
|
||||
// data may be anonymous.)
|
||||
// data may be unsafe anonymous.)
|
||||
bool ClassLoaderData::is_system_class_loader_data() const {
|
||||
return SystemDictionary::is_system_class_loader(class_loader());
|
||||
}
|
||||
|
||||
// Returns true if this class loader data is for the platform class loader.
|
||||
// (Note that the class loader data may be anonymous.)
|
||||
// (Note that the class loader data may be unsafe anonymous.)
|
||||
bool ClassLoaderData::is_platform_class_loader_data() const {
|
||||
return SystemDictionary::is_platform_class_loader(class_loader());
|
||||
}
|
||||
|
@ -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
|
||||
// the 3 builtin (boot application/system or platform) class loaders,
|
||||
// including a user-defined system class loader. Note that if the class
|
||||
// loader data is for an 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.
|
||||
bool ClassLoaderData::is_builtin_class_loader_data() const {
|
||||
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
|
||||
// that is not ever freed by a GC. It must be one of the builtin
|
||||
// class loaders and not anonymous.
|
||||
// that is not ever freed by a GC. It must be the CLD for one of the builtin
|
||||
// class loaders and not the CLD for an unsafe anonymous class.
|
||||
bool ClassLoaderData::is_permanent_class_loader_data() const {
|
||||
return is_builtin_class_loader_data() && !is_anonymous();
|
||||
return is_builtin_class_loader_data() && !is_unsafe_anonymous();
|
||||
}
|
||||
|
||||
ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() {
|
||||
|
@ -810,8 +810,8 @@ ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() {
|
|||
if (this == the_null_class_loader_data()) {
|
||||
assert (class_loader() == NULL, "Must be");
|
||||
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType);
|
||||
} else if (is_anonymous()) {
|
||||
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType);
|
||||
} else if (is_unsafe_anonymous()) {
|
||||
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::UnsafeAnonymousMetaspaceType);
|
||||
} else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) {
|
||||
metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType);
|
||||
} else {
|
||||
|
@ -962,8 +962,8 @@ void ClassLoaderData::free_deallocate_list_C_heap_structures() {
|
|||
}
|
||||
}
|
||||
|
||||
// These anonymous class loaders are to contain classes used for JSR292
|
||||
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(Handle loader) {
|
||||
// These CLDs are to contain unsafe anonymous classes used for JSR292
|
||||
ClassLoaderData* ClassLoaderData::unsafe_anonymous_class_loader_data(Handle loader) {
|
||||
// Add a new class loader data to the graph.
|
||||
return ClassLoaderDataGraph::add(loader, true);
|
||||
}
|
||||
|
@ -1005,8 +1005,8 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
|
|||
// loader data: 0xsomeaddr of 'bootstrap'
|
||||
out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id());
|
||||
}
|
||||
if (is_anonymous()) {
|
||||
out->print(" anonymous");
|
||||
if (is_unsafe_anonymous()) {
|
||||
out->print(" unsafe anonymous");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
|
|||
void ClassLoaderData::print_on(outputStream* out) const {
|
||||
out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {",
|
||||
p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id());
|
||||
if (is_anonymous()) out->print(" anonymous");
|
||||
if (is_unsafe_anonymous()) out->print(" unsafe anonymous");
|
||||
if (claimed()) out->print(" claimed");
|
||||
if (is_unloading()) out->print(" unloading");
|
||||
out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
|
||||
|
@ -1032,8 +1032,8 @@ void ClassLoaderData::verify() {
|
|||
assert_locked_or_safepoint(_metaspace_lock);
|
||||
oop cl = class_loader();
|
||||
|
||||
guarantee(this == class_loader_data(cl) || is_anonymous(), "Must be the same");
|
||||
guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_anonymous(), "must be");
|
||||
guarantee(this == class_loader_data(cl) || is_unsafe_anonymous(), "Must be the same");
|
||||
guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_unsafe_anonymous(), "must be");
|
||||
|
||||
// Verify the integrity of the allocated space.
|
||||
if (metaspace_or_null() != NULL) {
|
||||
|
@ -1069,14 +1069,14 @@ bool ClassLoaderDataGraph::_metaspace_oom = false;
|
|||
|
||||
// Add a new class loader data node to the list. Assign the newly created
|
||||
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
|
||||
ClassLoaderData* ClassLoaderDataGraph::add_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
|
||||
// ClassLoaderData in the graph since the CLD
|
||||
// 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
|
||||
ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
|
||||
if (old != NULL) {
|
||||
|
@ -1109,8 +1109,8 @@ ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_anony
|
|||
} while (true);
|
||||
}
|
||||
|
||||
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous) {
|
||||
ClassLoaderData* loader_data = add_to_graph(loader, is_anonymous);
|
||||
ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_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
|
||||
// CLDG because adding the Symbol for _name and _name_and_id might safepoint.
|
||||
if (loader.not_null()) {
|
||||
|
|
|
@ -92,8 +92,8 @@ class ClassLoaderDataGraph : public AllStatic {
|
|||
static volatile size_t _num_instance_classes;
|
||||
static volatile size_t _num_array_classes;
|
||||
|
||||
static ClassLoaderData* add_to_graph(Handle class_loader, bool anonymous);
|
||||
static ClassLoaderData* add(Handle class_loader, bool anonymous);
|
||||
static ClassLoaderData* add_to_graph(Handle class_loader, bool is_unsafe_anonymous);
|
||||
static ClassLoaderData* add(Handle class_loader, bool is_unsafe_anonymous);
|
||||
|
||||
public:
|
||||
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
|
||||
// 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.
|
||||
// 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(void f(Klass* const));
|
||||
static void methods_do(void f(Method*));
|
||||
|
@ -238,16 +238,17 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
// classes in the class loader are allocated.
|
||||
Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup.
|
||||
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.
|
||||
bool _modified_oops; // Card Table Equivalent (YC/CMS support)
|
||||
bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support)
|
||||
|
||||
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
|
||||
// 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.
|
||||
// To avoid applying oop closure more than once.
|
||||
|
@ -283,7 +284,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
void set_next(ClassLoaderData* next) { _next = next; }
|
||||
ClassLoaderData* next() const { return _next; }
|
||||
|
||||
ClassLoaderData(Handle h_class_loader, bool is_anonymous);
|
||||
ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous);
|
||||
~ClassLoaderData();
|
||||
|
||||
// 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; }
|
||||
|
||||
bool is_anonymous() const { return _is_anonymous; }
|
||||
bool is_unsafe_anonymous() const { return _is_unsafe_anonymous; }
|
||||
|
||||
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.
|
||||
// (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;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
|
||||
bool is_builtin_class_loader_data() const;
|
||||
|
@ -372,7 +373,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||
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.
|
||||
void inc_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_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'.
|
||||
// Also works if unloading.
|
||||
|
|
|
@ -298,7 +298,7 @@ InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS)
|
|||
name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
NULL, // host_klass
|
||||
NULL, // unsafe_anonymous_host
|
||||
NULL, // cp_patches
|
||||
THREAD);
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ public:
|
|||
|
||||
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.
|
||||
// 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 -
|
||||
|
@ -219,7 +219,7 @@ class LoaderTreeNode : public ResourceObj {
|
|||
if (print_classes) {
|
||||
if (_classes != NULL) {
|
||||
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");
|
||||
|
||||
branchtracker.print(st);
|
||||
|
@ -252,12 +252,12 @@ class LoaderTreeNode : public ResourceObj {
|
|||
for (LoadedClassInfo* lci = _anon_classes; lci; lci = lci->_next) {
|
||||
branchtracker.print(st);
|
||||
if (lci == _anon_classes) { // first iteration
|
||||
st->print("%*s ", indentation, "Anonymous Classes:");
|
||||
st->print("%*s ", indentation, "Unsafe Anonymous Classes:");
|
||||
} else {
|
||||
st->print("%*s ", indentation, "");
|
||||
}
|
||||
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");
|
||||
if (verbose) {
|
||||
st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld));
|
||||
|
@ -266,7 +266,7 @@ class LoaderTreeNode : public ResourceObj {
|
|||
}
|
||||
branchtracker.print(st);
|
||||
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
|
||||
branchtracker.print(st);
|
||||
|
@ -318,14 +318,14 @@ public:
|
|||
_next = info;
|
||||
}
|
||||
|
||||
void add_classes(LoadedClassInfo* first_class, int num_classes, bool anonymous) {
|
||||
LoadedClassInfo** p_list_to_add_to = anonymous ? &_anon_classes : &_classes;
|
||||
void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_unsafe_anonymous) {
|
||||
LoadedClassInfo** p_list_to_add_to = is_unsafe_anonymous ? &_anon_classes : &_classes;
|
||||
// Search tail.
|
||||
while ((*p_list_to_add_to) != NULL) {
|
||||
p_list_to_add_to = &(*p_list_to_add_to)->_next;
|
||||
}
|
||||
*p_list_to_add_to = first_class;
|
||||
if (anonymous) {
|
||||
if (is_unsafe_anonymous) {
|
||||
_num_anon_classes += num_classes;
|
||||
} else {
|
||||
_num_classes += num_classes;
|
||||
|
@ -420,7 +420,7 @@ class LoaderInfoScanClosure : public CLDClosure {
|
|||
LoadedClassCollectClosure lccc(cld);
|
||||
const_cast<ClassLoaderData*>(cld)->classes_do(&lccc);
|
||||
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");
|
||||
|
||||
// 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");
|
||||
info->set_cld(cld);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
|
|||
cls = *cls_ptr;
|
||||
}
|
||||
|
||||
if (!cld->is_anonymous()) {
|
||||
if (!cld->is_unsafe_anonymous()) {
|
||||
cls->_cld = cld;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
|
|||
|
||||
ClassStatsClosure csc;
|
||||
cld->classes_do(&csc);
|
||||
if(cld->is_anonymous()) {
|
||||
if(cld->is_unsafe_anonymous()) {
|
||||
cls->_anon_classes_count += csc._num_classes;
|
||||
} else {
|
||||
cls->_classes_count = csc._num_classes;
|
||||
|
@ -79,7 +79,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
|
|||
|
||||
ClassLoaderMetaspace* ms = cld->metaspace_or_null();
|
||||
if (ms != NULL) {
|
||||
if(cld->is_anonymous()) {
|
||||
if(cld->is_unsafe_anonymous()) {
|
||||
cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
|
||||
cls->_anon_block_sz += ms->allocated_blocks_bytes();
|
||||
} else {
|
||||
|
|
|
@ -885,7 +885,7 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool,
|
|||
ConstantPool* cp = bpool->create_constant_pool(CHECK);
|
||||
if (cp != klass->constants()) {
|
||||
// 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);
|
||||
}
|
||||
klass->class_loader_data()->add_to_deallocate_list(klass->constants());
|
||||
|
|
|
@ -3786,7 +3786,7 @@ oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle
|
|||
}
|
||||
oop new_resolved_method = k->allocate_instance(CHECK_NULL);
|
||||
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.
|
||||
// This mirror may be different than the one in clazz field.
|
||||
new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());
|
||||
|
|
|
@ -183,7 +183,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
|||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
Handle protection_domain,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS) {
|
||||
assert(stream != NULL, "invariant");
|
||||
|
@ -201,7 +201,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
|||
THREAD->statistical_info().incr_define_class_count();
|
||||
|
||||
// Skip this processing for VM anonymous classes
|
||||
if (host_klass == NULL) {
|
||||
if (unsafe_anonymous_host == NULL) {
|
||||
stream = check_class_file_load_hook(stream,
|
||||
name,
|
||||
loader_data,
|
||||
|
@ -214,7 +214,7 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
|
|||
name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
host_klass,
|
||||
unsafe_anonymous_host,
|
||||
cp_patches,
|
||||
ClassFileParser::BROADCAST, // publicity level
|
||||
CHECK_NULL);
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -72,7 +72,7 @@ class KlassFactory : AllStatic {
|
|||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
Handle protection_domain,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS);
|
||||
public:
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
ClassLoaderData* loader_data() const { return _loader_data; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -988,18 +988,18 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
|
|||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
ClassFileStream* st,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS) {
|
||||
|
||||
EventClassLoad class_load_start_event;
|
||||
|
||||
ClassLoaderData* loader_data;
|
||||
if (host_klass != NULL) {
|
||||
// Create a new CLD for anonymous class, that uses the same class loader
|
||||
// as the host_klass
|
||||
guarantee(oopDesc::equals(host_klass->class_loader(), class_loader()), "should be the same");
|
||||
loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader);
|
||||
if (unsafe_anonymous_host != NULL) {
|
||||
// Create a new CLD for an unsafe anonymous class, that uses the same class loader
|
||||
// as the unsafe_anonymous_host
|
||||
guarantee(oopDesc::equals(unsafe_anonymous_host->class_loader(), class_loader()), "should be the same");
|
||||
loader_data = ClassLoaderData::unsafe_anonymous_class_loader_data(class_loader);
|
||||
} else {
|
||||
loader_data = ClassLoaderData::class_loader_data(class_loader());
|
||||
}
|
||||
|
@ -1016,12 +1016,12 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
|
|||
class_name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
host_klass,
|
||||
unsafe_anonymous_host,
|
||||
cp_patches,
|
||||
CHECK_NULL);
|
||||
|
||||
if (host_klass != NULL && k != NULL) {
|
||||
// Anonymous classes must update ClassLoaderData holder (was host_klass loader)
|
||||
if (unsafe_anonymous_host != NULL && k != NULL) {
|
||||
// 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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
assert(host_klass != NULL || NULL == cp_patches,
|
||||
"cp_patches only found with host_klass");
|
||||
assert(unsafe_anonymous_host != NULL || NULL == cp_patches,
|
||||
"cp_patches only found with unsafe_anonymous_host");
|
||||
|
||||
return k;
|
||||
}
|
||||
|
@ -1115,7 +1115,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
|||
class_name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
NULL, // host_klass
|
||||
NULL, // unsafe_anonymous_host
|
||||
NULL, // cp_patches
|
||||
CHECK_NULL);
|
||||
}
|
||||
|
@ -3010,7 +3010,7 @@ class CombineDictionariesClosure : public CLDClosure {
|
|||
_master_dictionary(master_dictionary) {}
|
||||
void do_cld(ClassLoaderData* cld) {
|
||||
ResourceMark rm;
|
||||
if (cld->is_anonymous()) {
|
||||
if (cld->is_unsafe_anonymous()) {
|
||||
return;
|
||||
}
|
||||
if (cld->is_system_class_loader_data() || cld->is_platform_class_loader_data()) {
|
||||
|
|
|
@ -298,7 +298,7 @@ public:
|
|||
class_loader,
|
||||
protection_domain,
|
||||
st,
|
||||
NULL, // host klass
|
||||
NULL, // unsafe_anonymous_host
|
||||
NULL, // cp_patches
|
||||
THREAD);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ public:
|
|||
Handle class_loader,
|
||||
Handle protection_domain,
|
||||
ClassFileStream* st,
|
||||
const InstanceKlass* host_klass,
|
||||
const InstanceKlass* unsafe_anonymous_host,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
assert(DumpSharedSpaces, "called at dump time only");
|
||||
|
||||
// Skip anonymous classes, which are not archived as they are not in
|
||||
// dictionary (see assert_no_anonymoys_classes_in_dictionaries() in
|
||||
// Skip unsafe anonymous classes, which are not archived as they are not in
|
||||
// dictionary (see assert_no_unsafe_anonymous_classes_in_dictionaries() in
|
||||
// VM_PopulateDumpSharedSpace::doit()).
|
||||
if (k->class_loader_data()->is_anonymous()) {
|
||||
return true; // anonymous classes are not archived, skip
|
||||
if (k->class_loader_data()->is_unsafe_anonymous()) {
|
||||
return true; // unsafe anonymous classes are not archived, skip
|
||||
}
|
||||
|
||||
SharedDictionaryEntry* entry = ((SharedDictionary*)(k->class_loader_data()->dictionary()))->find_entry_for(k);
|
||||
|
|
|
@ -2823,20 +2823,20 @@ void ClassVerifier::verify_invoke_instructions(
|
|||
current_class()->super()->name()))) {
|
||||
bool subtype = false;
|
||||
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(
|
||||
current_type(), this, false, CHECK_VERIFY(this));
|
||||
} else {
|
||||
VerificationType host_klass_type =
|
||||
VerificationType::reference_type(current_class()->host_klass()->name());
|
||||
subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
|
||||
VerificationType unsafe_anonymous_host_type =
|
||||
VerificationType::reference_type(current_class()->unsafe_anonymous_host()->name());
|
||||
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
|
||||
// direct interface relative to the host class
|
||||
have_imr_indirect = (have_imr_indirect &&
|
||||
!is_same_or_direct_interface(
|
||||
current_class()->host_klass(),
|
||||
host_klass_type, ref_class_type));
|
||||
current_class()->unsafe_anonymous_host(),
|
||||
unsafe_anonymous_host_type, ref_class_type));
|
||||
}
|
||||
if (!subtype) {
|
||||
verify_error(ErrorContext::bad_code(bci),
|
||||
|
@ -2866,15 +2866,15 @@ void ClassVerifier::verify_invoke_instructions(
|
|||
} else { // other methods
|
||||
// Ensures that target class is assignable to method class.
|
||||
if (opcode == Bytecodes::_invokespecial) {
|
||||
if (!current_class()->is_anonymous()) {
|
||||
if (!current_class()->is_unsafe_anonymous()) {
|
||||
current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
|
||||
} else {
|
||||
// anonymous class invokespecial calls: check if the
|
||||
// objectref is a subtype of the host_klass of the current class
|
||||
// to allow an anonymous class to reference methods in the host_klass
|
||||
// objectref is a subtype of the unsafe_anonymous_host of the current class
|
||||
// to allow an anonymous class to reference methods in the unsafe_anonymous_host
|
||||
VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
|
||||
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));
|
||||
if (!subtype) {
|
||||
verify_error( ErrorContext::bad_type(current_frame->offset(),
|
||||
|
|
|
@ -153,14 +153,14 @@ void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager*
|
|||
// Follow the klass field in the mirror.
|
||||
Klass* klass = java_lang_Class::as_Klass(obj);
|
||||
if (klass != NULL) {
|
||||
// An anonymous class doesn't have its own class loader, 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
|
||||
// we need to make sure its class loader data is claimed, this is done
|
||||
// by calling follow_class_loader explicitly. For non-anonymous classes
|
||||
// the call to follow_class_loader is made when the class loader itself
|
||||
// is handled.
|
||||
if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) {
|
||||
// An unsafe anonymous class doesn't have its own class loader,
|
||||
// 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 unsafe anonymous
|
||||
// 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 the
|
||||
// call to follow_class_loader is made when the class loader itself is handled.
|
||||
if (klass->is_instance_klass() &&
|
||||
InstanceKlass::cast(klass)->is_unsafe_anonymous()) {
|
||||
cm->follow_class_loader(klass->class_loader_data());
|
||||
} else {
|
||||
cm->follow_klass(klass);
|
||||
|
|
|
@ -924,11 +924,11 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
|
|||
info.call_kind() == CallInfo::vtable_call, "");
|
||||
}
|
||||
#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
|
||||
// methods must be checked for every call.
|
||||
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()) {
|
||||
case CallInfo::direct_call:
|
||||
|
|
|
@ -1167,9 +1167,9 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
|
|||
Klass* current_klass = link_info.current_klass();
|
||||
if (current_klass != NULL && resolved_klass->is_interface()) {
|
||||
InstanceKlass* ck = InstanceKlass::cast(current_klass);
|
||||
InstanceKlass *klass_to_check = !ck->is_anonymous() ?
|
||||
InstanceKlass *klass_to_check = !ck->is_unsafe_anonymous() ?
|
||||
ck :
|
||||
InstanceKlass::cast(ck->host_klass());
|
||||
InstanceKlass::cast(ck->unsafe_anonymous_host());
|
||||
// Disable verification for the dynamically-generated reflection bytecodes.
|
||||
bool is_reflect = klass_to_check->is_subclass_of(
|
||||
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
|
||||
// a class. If the sender is an interface, the check has to be performed at runtime.
|
||||
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()) {
|
||||
Klass* receiver_klass = recv->klass();
|
||||
if (!receiver_klass->is_subtype_of(sender)) {
|
||||
|
|
|
@ -161,10 +161,10 @@ void ObjectSampleDescription::write_class_name() {
|
|||
|
||||
if (k->is_instance_klass()) {
|
||||
const InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
return;
|
||||
}
|
||||
assert(!ik->is_anonymous(), "invariant");
|
||||
assert(!ik->is_unsafe_anonymous(), "invariant");
|
||||
const Symbol* name = ik->name();
|
||||
if (name != NULL) {
|
||||
write_text("Class Name: ");
|
||||
|
|
|
@ -200,7 +200,7 @@
|
|||
<Event name="MetaspaceAllocationFailure" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Allocation Failure" startTime="false"
|
||||
stackTrace="true">
|
||||
<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="MetadataType" name="metadataType" label="Metadata 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">
|
||||
<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="MetadataType" name="metadataType" label="Metadata 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="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="long" name="anonymousClassCount" 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"
|
||||
description="Total size of all allocated metaspace chunks for anonymous classes (each chunk has several blocks)" />
|
||||
<Field type="ulong" contentType="bytes" name="anonymousBlockSize" label="Total Unsafe Anonymous Classes Block Size"
|
||||
description="Total size of all allocated metaspace blocks for anonymous classes (each chunk has several blocks)" />
|
||||
<Field type="long" name="unsafeAnonymousClassCount" label="Unsafe Anonymous Classes" description="Number of loaded classes to support invokedynamic" />
|
||||
<Field type="ulong" contentType="bytes" name="unsafeAnonymousChunkSize" label="Total Unsafe Anonymous Classes Chunk Size"
|
||||
description="Total size of all allocated metaspace chunks for unsafe anonymous classes (each chunk has several blocks)" />
|
||||
<Field type="ulong" contentType="bytes" name="unsafeAnonymousBlockSize" label="Total Unsafe Anonymous Classes Block Size"
|
||||
description="Total size of all allocated metaspace blocks for unsafe anonymous classes (each chunk has several blocks)" />
|
||||
</Event>
|
||||
|
||||
<Event name="ThreadAllocationStatistics" category="Java Application, Statistics" label="Thread Allocation Statistics" period="everyChunk">
|
||||
|
|
|
@ -476,9 +476,9 @@ public:
|
|||
event.set_classCount(cls->_classes_count);
|
||||
event.set_chunkSize(cls->_chunk_sz);
|
||||
event.set_blockSize(cls->_block_sz);
|
||||
event.set_anonymousClassCount(cls->_anon_classes_count);
|
||||
event.set_anonymousChunkSize(cls->_anon_chunk_sz);
|
||||
event.set_anonymousBlockSize(cls->_anon_block_sz);
|
||||
event.set_unsafeAnonymousClassCount(cls->_anon_classes_count);
|
||||
event.set_unsafeAnonymousChunkSize(cls->_anon_chunk_sz);
|
||||
event.set_unsafeAnonymousBlockSize(cls->_anon_block_sz);
|
||||
event.commit();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ static traceid package_id(KlassPtr klass) {
|
|||
|
||||
static traceid cld_id(CldPtr cld) {
|
||||
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) {
|
||||
|
@ -92,7 +92,7 @@ static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) {
|
|||
}
|
||||
CldPtr cld = k->class_loader_data();
|
||||
assert(cld != NULL, "invariant");
|
||||
if (!cld->is_anonymous()) {
|
||||
if (!cld->is_unsafe_anonymous()) {
|
||||
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) {
|
||||
assert(c != NULL, "invariant");
|
||||
CldPtr cld = (CldPtr)c;
|
||||
assert(!cld->is_anonymous(), "invariant");
|
||||
assert(!cld->is_unsafe_anonymous(), "invariant");
|
||||
const traceid cld_id = TRACE_ID(cld);
|
||||
// class loader type
|
||||
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(k != NULL, "invariant");
|
||||
const InstanceKlass* const ik = (const InstanceKlass*)k;
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
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");
|
||||
return write__artifact__cstring__entry__(writer, entry);
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ class KlassSymbolWriterImpl {
|
|||
}
|
||||
CldPtr cld = klass->class_loader_data();
|
||||
assert(cld != NULL, "invariant");
|
||||
if (!cld->is_anonymous()) {
|
||||
if (!cld->is_unsafe_anonymous()) {
|
||||
count += class_loader_symbols(cld);
|
||||
}
|
||||
if (_method_used_predicate(klass)) {
|
||||
|
@ -374,9 +374,9 @@ int KlassSymbolWriterImpl<Predicate>::klass_symbols(KlassPtr klass) {
|
|||
assert(klass != NULL, "invariant");
|
||||
assert(_predicate(klass), "invariant");
|
||||
const InstanceKlass* const ik = (const InstanceKlass*)klass;
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
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");
|
||||
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>
|
||||
int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) {
|
||||
assert(cld != NULL, "invariant");
|
||||
assert(!cld->is_anonymous(), "invariant");
|
||||
assert(!cld->is_unsafe_anonymous(), "invariant");
|
||||
int count = 0;
|
||||
// class loader type
|
||||
const Klass* class_loader_klass = cld->class_loader_klass();
|
||||
|
@ -696,7 +696,7 @@ class CldFieldSelector {
|
|||
static TypePtr select(KlassPtr klass) {
|
||||
assert(klass != NULL, "invariant");
|
||||
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) {}
|
||||
void do_cld(ClassLoaderData* cld) {
|
||||
assert(cld != NULL, "invariant");
|
||||
if (cld->is_anonymous()) {
|
||||
if (cld->is_unsafe_anonymous()) {
|
||||
return;
|
||||
}
|
||||
if (_class_unload) {
|
||||
|
|
|
@ -59,14 +59,14 @@ JfrSymbolId::~JfrSymbolId() {
|
|||
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->is_instance_klass(), "invariant");
|
||||
assert(is_anonymous_klass(k), "invariant");
|
||||
assert(is_unsafe_anonymous_klass(k), "invariant");
|
||||
|
||||
uintptr_t anonymous_symbol_hash_code = 0;
|
||||
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) {
|
||||
return 0;
|
||||
|
@ -119,8 +119,8 @@ bool JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry*
|
|||
traceid JfrSymbolId::mark(const Klass* k) {
|
||||
assert(k != NULL, "invariant");
|
||||
traceid symbol_id = 0;
|
||||
if (is_anonymous_klass(k)) {
|
||||
symbol_id = mark_anonymous_klass_name(k);
|
||||
if (is_unsafe_anonymous_klass(k)) {
|
||||
symbol_id = mark_unsafe_anonymous_klass_name(k);
|
||||
}
|
||||
if (0 == symbol_id) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool JfrSymbolId::is_anonymous_klass(const Klass* k) {
|
||||
bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
|
||||
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
|
||||
*/
|
||||
|
||||
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->is_anonymous(), "invariant");
|
||||
assert(ik->is_unsafe_anonymous(), "invariant");
|
||||
const oop mirror = ik->java_mirror();
|
||||
assert(mirror != NULL, "invariant");
|
||||
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->is_anonymous(), "invariant");
|
||||
assert(ik->is_unsafe_anonymous(), "invariant");
|
||||
assert(0 == hashcode, "invariant");
|
||||
char* anonymous_symbol = NULL;
|
||||
const oop mirror = ik->java_mirror();
|
||||
assert(mirror != NULL, "invariant");
|
||||
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);
|
||||
const size_t hash_len = strlen(hash_buf);
|
||||
const size_t result_len = ik->name()->utf8_length();
|
||||
|
@ -223,8 +223,8 @@ void JfrArtifactSet::clear() {
|
|||
// _klass_list will be cleared by a ResourceMark
|
||||
}
|
||||
|
||||
traceid JfrArtifactSet::mark_anonymous_klass_name(const Klass* klass) {
|
||||
return _symbol_id->mark_anonymous_klass_name(klass);
|
||||
traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass) {
|
||||
return _symbol_id->mark_unsafe_anonymous_klass_name(klass);
|
||||
}
|
||||
|
||||
traceid JfrArtifactSet::mark(const Symbol* sym, uintptr_t hash) {
|
||||
|
|
|
@ -236,9 +236,9 @@ class JfrSymbolId : public JfrCHeapObj {
|
|||
bool equals(const char* query, uintptr_t hash, const CStringEntry* entry);
|
||||
|
||||
public:
|
||||
static bool is_anonymous_klass(const Klass* k);
|
||||
static const char* create_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode);
|
||||
static uintptr_t anonymous_klass_name_hash_code(const InstanceKlass* ik);
|
||||
static bool is_unsafe_anonymous_klass(const Klass* k);
|
||||
static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode);
|
||||
static uintptr_t unsafe_anonymous_klass_name_hash_code(const InstanceKlass* ik);
|
||||
static uintptr_t regular_klass_name_hash_code(const Klass* k);
|
||||
|
||||
JfrSymbolId();
|
||||
|
@ -247,7 +247,7 @@ class JfrSymbolId : public JfrCHeapObj {
|
|||
void initialize();
|
||||
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 Klass* k);
|
||||
traceid mark(const Symbol* symbol);
|
||||
|
@ -259,7 +259,7 @@ class JfrSymbolId : public JfrCHeapObj {
|
|||
|
||||
template <typename T>
|
||||
void symbol(T& functor, const Klass* k) {
|
||||
if (is_anonymous_klass(k)) {
|
||||
if (is_unsafe_anonymous_klass(k)) {
|
||||
return;
|
||||
}
|
||||
functor(map_symbol(regular_klass_name_hash_code(k)));
|
||||
|
@ -274,10 +274,10 @@ class JfrSymbolId : public JfrCHeapObj {
|
|||
|
||||
template <typename T>
|
||||
void cstring(T& functor, const Klass* k) {
|
||||
if (!is_anonymous_klass(k)) {
|
||||
if (!is_unsafe_anonymous_klass(k)) {
|
||||
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>
|
||||
|
@ -327,7 +327,7 @@ class JfrArtifactSet : public JfrCHeapObj {
|
|||
traceid mark(const Klass* klass);
|
||||
traceid mark(const Symbol* symbol);
|
||||
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(uintptr_t hash) const;
|
||||
|
|
|
@ -120,7 +120,7 @@ void JfrTraceId::assign(const PackageEntry* package) {
|
|||
|
||||
void JfrTraceId::assign(const ClassLoaderData* cld) {
|
||||
assert(cld != NULL, "invariant");
|
||||
if (cld->is_anonymous()) {
|
||||
if (cld->is_unsafe_anonymous()) {
|
||||
cld->set_trace_id(0);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ inline traceid JfrTraceId::use(const PackageEntry* package, bool leakp /* false
|
|||
|
||||
inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) {
|
||||
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) {
|
||||
|
|
|
@ -1436,7 +1436,7 @@ C2V_END
|
|||
|
||||
C2V_VMENTRY(jobject, getHostClass, (JNIEnv*, jobject, jobject 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);
|
||||
oop result = CompilerToVM::get_jvmci_type(handle, CHECK_NULL);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
|
|
|
@ -527,7 +527,7 @@
|
|||
\
|
||||
declare_constant(InstanceKlass::linked) \
|
||||
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::displacement_off_set) \
|
||||
|
|
|
@ -62,7 +62,7 @@ static const char* space_type_name(Metaspace::MetaspaceType t) {
|
|||
switch (t) {
|
||||
case Metaspace::StandardMetaspaceType: s = "Standard"; 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;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@ class Metaspace : public AllStatic {
|
|||
ZeroMetaspaceType = 0,
|
||||
StandardMetaspaceType = ZeroMetaspaceType,
|
||||
BootMetaspaceType = StandardMetaspaceType + 1,
|
||||
AnonymousMetaspaceType = BootMetaspaceType + 1,
|
||||
ReflectionMetaspaceType = AnonymousMetaspaceType + 1,
|
||||
UnsafeAnonymousMetaspaceType = BootMetaspaceType + 1,
|
||||
ReflectionMetaspaceType = UnsafeAnonymousMetaspaceType + 1,
|
||||
MetaspaceTypeCount
|
||||
};
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ void PrintCLDMetaspaceInfoClosure::do_cld(ClassLoaderData* cld) {
|
|||
_out->print(" (unloading)");
|
||||
}
|
||||
_out->print(":");
|
||||
if (cld->is_anonymous()) {
|
||||
if (cld->is_unsafe_anonymous()) {
|
||||
_out->print(" <anonymous class>, loaded by");
|
||||
}
|
||||
if (name != NULL) {
|
||||
|
|
|
@ -75,14 +75,14 @@ size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const
|
|||
if (is_class()) {
|
||||
switch (type) {
|
||||
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;
|
||||
default: requested = ClassSmallChunk; break;
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
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;
|
||||
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.
|
||||
size_t chunk_word_size;
|
||||
|
||||
// Special case for anonymous metadata space.
|
||||
// Anonymous metadata space is usually small, with majority within 1K - 2K range and
|
||||
// Special case for unsafe anonymous metadata space.
|
||||
// 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).
|
||||
// Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation
|
||||
// from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4)
|
||||
// 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 &&
|
||||
num_chunks_by_type(SpecializedIndex) < anon_and_delegating_metadata_specialize_chunk_limit &&
|
||||
word_size + Metachunk::overhead() <= SpecializedChunk) {
|
||||
|
|
|
@ -579,14 +579,13 @@ static void relocate_cached_class_file() {
|
|||
}
|
||||
|
||||
NOT_PRODUCT(
|
||||
static void assert_not_anonymous_class(InstanceKlass* k) {
|
||||
assert(!(k->is_anonymous()), "cannot archive anonymous classes");
|
||||
static void assert_not_unsafe_anonymous_class(InstanceKlass* k) {
|
||||
assert(!(k->is_unsafe_anonymous()), "cannot archive unsafe anonymous classes");
|
||||
}
|
||||
|
||||
// Anonymous classes are not stored inside any dictionaries. They are created by
|
||||
// SystemDictionary::parse_stream() with a non-null host_klass.
|
||||
static void assert_no_anonymoys_classes_in_dictionaries() {
|
||||
ClassLoaderDataGraph::dictionary_classes_do(assert_not_anonymous_class);
|
||||
// Unsafe anonymous classes are not stored inside any dictionaries.
|
||||
static void assert_no_unsafe_anonymous_classes_in_dictionaries() {
|
||||
ClassLoaderDataGraph::dictionary_classes_do(assert_not_unsafe_anonymous_class);
|
||||
})
|
||||
|
||||
// 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();
|
||||
tty->print_cr("done. ");
|
||||
|
||||
// We don't support archiving anonymous classes. Verify that they are not stored in
|
||||
// the any dictionaries.
|
||||
NOT_PRODUCT(assert_no_anonymoys_classes_in_dictionaries());
|
||||
// We don't support archiving unsafe anonymous classes. Verify that they are not stored in
|
||||
// any dictionaries.
|
||||
NOT_PRODUCT(assert_no_unsafe_anonymous_classes_in_dictionaries());
|
||||
|
||||
SystemDictionaryShared::finalize_verification_constraints();
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@ void MetaspaceTracer::send_allocation_failure_event(ClassLoaderData *cld,
|
|||
E event;
|
||||
if (event.should_commit()) {
|
||||
event.set_classLoader(cld);
|
||||
if (cld->is_anonymous()) {
|
||||
event.set_anonymousClassLoader(true);
|
||||
if (cld->is_unsafe_anonymous()) {
|
||||
event.set_unsafeAnonymousClassLoader(true);
|
||||
} else {
|
||||
event.set_anonymousClassLoader(false);
|
||||
event.set_unsafeAnonymousClassLoader(false);
|
||||
}
|
||||
event.set_size(word_size * BytesPerWord);
|
||||
event.set_metadataType((u1) mdtype);
|
||||
|
|
|
@ -221,7 +221,7 @@ void ConstantPool::initialize_unresolved_klasses(ClassLoaderData* loader_data, T
|
|||
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) {
|
||||
assert(is_within_bounds(class_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) {
|
||||
assert(k != NULL, "must be valid klass");
|
||||
CPKlassSlot kslot = klass_slot_at(class_index);
|
||||
|
|
|
@ -271,7 +271,7 @@ class ConstantPool : public Metadata {
|
|||
*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, 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 String entry.
|
||||
// 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
|
||||
// use pseudo-strings to link themselves to related metaobjects.
|
||||
|
||||
|
|
|
@ -341,8 +341,8 @@ InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& par
|
|||
parser.itable_size(),
|
||||
nonstatic_oop_map_size(parser.total_oop_map_count()),
|
||||
parser.is_interface(),
|
||||
parser.is_anonymous(),
|
||||
should_store_fingerprint(parser.is_anonymous()));
|
||||
parser.is_unsafe_anonymous(),
|
||||
should_store_fingerprint(parser.is_unsafe_anonymous()));
|
||||
|
||||
const Symbol* const class_name = parser.class_name();
|
||||
assert(class_name != NULL, "invariant");
|
||||
|
@ -412,7 +412,7 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, Klass
|
|||
set_vtable_length(parser.vtable_size());
|
||||
set_kind(kind);
|
||||
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(),
|
||||
false));
|
||||
|
||||
|
@ -2193,7 +2193,7 @@ bool InstanceKlass::supers_have_passed_fingerprint_checks() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool InstanceKlass::should_store_fingerprint(bool is_anonymous) {
|
||||
bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) {
|
||||
#if INCLUDE_AOT
|
||||
// We store the fingerprint into the InstanceKlass only in the following 2 cases:
|
||||
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
|
||||
return true;
|
||||
}
|
||||
if (UseAOT && is_anonymous) {
|
||||
// (3) We are using AOT code from a shared library and see an anonymous class
|
||||
if (UseAOT && is_unsafe_anonymous) {
|
||||
// (3) We are using AOT code from a shared library and see an unsafe anonymous class
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -2507,8 +2507,8 @@ const char* InstanceKlass::signature_name() const {
|
|||
int hash_len = 0;
|
||||
char hash_buf[40];
|
||||
|
||||
// If this is an anonymous class, append a hash to make the name unique
|
||||
if (is_anonymous()) {
|
||||
// If this is an unsafe anonymous class, append a hash to make the name unique
|
||||
if (is_unsafe_anonymous()) {
|
||||
intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
|
||||
jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
|
||||
hash_len = (int)strlen(hash_buf);
|
||||
|
@ -2559,14 +2559,19 @@ Symbol* InstanceKlass::package_from_name(const Symbol* name, TRAPS) {
|
|||
}
|
||||
|
||||
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()) {
|
||||
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 host->class_loader_data()->unnamed_module();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
if (encl_method_class_idx != 0) {
|
||||
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);
|
||||
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) {
|
||||
st->print(BULLET"source file: ");
|
||||
source_file_name()->print_value_on(st);
|
||||
|
@ -3612,9 +3617,9 @@ void InstanceKlass::verify_on(outputStream* st) {
|
|||
if (constants() != NULL) {
|
||||
guarantee(constants()->is_constantPool(), "should be constant pool");
|
||||
}
|
||||
const Klass* host = host_klass();
|
||||
if (host != NULL) {
|
||||
guarantee(host->is_klass(), "should be klass");
|
||||
const Klass* anonymous_host = unsafe_anonymous_host();
|
||||
if (anonymous_host != NULL) {
|
||||
guarantee(anonymous_host->is_klass(), "should be klass");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
// The embedded nonstatic oop-map blocks are short pairs (offset, length)
|
||||
// indicating where oops are located in instances of this klass.
|
||||
// [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
|
||||
|
||||
|
||||
|
@ -226,7 +226,7 @@ class InstanceKlass: public Klass {
|
|||
_misc_rewritten = 1 << 2, // methods rewritten.
|
||||
_misc_has_nonstatic_fields = 1 << 3, // for sizing with UseCompressedOops
|
||||
_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_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
|
||||
|
@ -315,11 +315,11 @@ class InstanceKlass: public Klass {
|
|||
// NULL: no implementor.
|
||||
// A Klass* that's not itself: one implementor.
|
||||
// Itself: more than one implementors.
|
||||
// embedded host klass follows here
|
||||
// The embedded host klass only exists in an anonymous class for
|
||||
// embedded unsafe_anonymous_host klass follows here
|
||||
// The embedded host klass only exists in an unsafe anonymous class for
|
||||
// dynamic language support (JSR 292 enabled). The host class grants
|
||||
// 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
|
||||
// have this embedded field.
|
||||
//
|
||||
|
@ -650,43 +650,40 @@ public:
|
|||
objArrayOop signers() const;
|
||||
|
||||
// host class
|
||||
InstanceKlass* host_klass() const {
|
||||
InstanceKlass** hk = adr_host_klass();
|
||||
InstanceKlass* unsafe_anonymous_host() const {
|
||||
InstanceKlass** hk = adr_unsafe_anonymous_host();
|
||||
if (hk == NULL) {
|
||||
assert(!is_anonymous(), "Anonymous classes have host klasses");
|
||||
assert(!is_unsafe_anonymous(), "Unsafe anonymous classes have host klasses");
|
||||
return NULL;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
void set_host_klass(const InstanceKlass* host) {
|
||||
assert(is_anonymous(), "not anonymous");
|
||||
const InstanceKlass** addr = (const InstanceKlass **)adr_host_klass();
|
||||
void set_unsafe_anonymous_host(const InstanceKlass* host) {
|
||||
assert(is_unsafe_anonymous(), "not unsafe anonymous");
|
||||
const InstanceKlass** addr = (const InstanceKlass **)adr_unsafe_anonymous_host();
|
||||
assert(addr != NULL, "no reversed space");
|
||||
if (addr != NULL) {
|
||||
*addr = host;
|
||||
}
|
||||
}
|
||||
bool has_host_klass() const {
|
||||
return adr_host_klass() != NULL;
|
||||
bool is_unsafe_anonymous() const {
|
||||
return (_misc_flags & _misc_is_unsafe_anonymous) != 0;
|
||||
}
|
||||
bool is_anonymous() const {
|
||||
return (_misc_flags & _misc_is_anonymous) != 0;
|
||||
}
|
||||
void set_is_anonymous(bool value) {
|
||||
void set_is_unsafe_anonymous(bool value) {
|
||||
if (value) {
|
||||
_misc_flags |= _misc_is_anonymous;
|
||||
_misc_flags |= _misc_is_unsafe_anonymous;
|
||||
} else {
|
||||
_misc_flags &= ~_misc_is_anonymous;
|
||||
_misc_flags &= ~_misc_is_unsafe_anonymous;
|
||||
}
|
||||
}
|
||||
|
||||
// Oop that keeps the metadata for this class from being unloaded
|
||||
// in places where the metadata is stored in other places, like nmethods
|
||||
oop klass_holder() const {
|
||||
return is_anonymous() ? java_mirror() : class_loader();
|
||||
return (is_unsafe_anonymous()) ? java_mirror() : class_loader();
|
||||
}
|
||||
|
||||
bool is_contended() const {
|
||||
|
@ -780,8 +777,8 @@ public:
|
|||
}
|
||||
bool supers_have_passed_fingerprint_checks();
|
||||
|
||||
static bool should_store_fingerprint(bool is_anonymous);
|
||||
bool should_store_fingerprint() const { return should_store_fingerprint(is_anonymous()); }
|
||||
static bool should_store_fingerprint(bool is_unsafe_anonymous);
|
||||
bool should_store_fingerprint() const { return should_store_fingerprint(is_unsafe_anonymous()); }
|
||||
bool has_stored_fingerprint() const;
|
||||
uint64_t get_stored_fingerprint() const;
|
||||
void store_fingerprint(uint64_t fingerprint);
|
||||
|
@ -1063,20 +1060,20 @@ public:
|
|||
|
||||
static int size(int vtable_length, int itable_length,
|
||||
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() +
|
||||
vtable_length +
|
||||
itable_length +
|
||||
nonstatic_oop_map_size +
|
||||
(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));
|
||||
}
|
||||
int size() const { return size(vtable_length(),
|
||||
itable_length(),
|
||||
nonstatic_oop_map_size(),
|
||||
is_interface(),
|
||||
is_anonymous(),
|
||||
is_unsafe_anonymous(),
|
||||
has_stored_fingerprint());
|
||||
}
|
||||
#if INCLUDE_SERVICES
|
||||
|
@ -1107,8 +1104,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
InstanceKlass** adr_host_klass() const {
|
||||
if (is_anonymous()) {
|
||||
InstanceKlass** adr_unsafe_anonymous_host() const {
|
||||
if (is_unsafe_anonymous()) {
|
||||
InstanceKlass** adr_impl = (InstanceKlass **)adr_implementor();
|
||||
if (adr_impl != NULL) {
|
||||
return adr_impl + 1;
|
||||
|
@ -1122,7 +1119,7 @@ public:
|
|||
|
||||
address adr_fingerprint() const {
|
||||
if (has_stored_fingerprint()) {
|
||||
InstanceKlass** adr_host = adr_host_klass();
|
||||
InstanceKlass** adr_host = adr_unsafe_anonymous_host();
|
||||
if (adr_host != NULL) {
|
||||
return (address)(adr_host + 1);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
// We'll get NULL for primitive mirrors.
|
||||
if (klass != NULL) {
|
||||
if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) {
|
||||
// An anonymous class doesn't have its own class loader, so when handling
|
||||
// the java mirror for an anonymous class we need to make sure its class
|
||||
if (klass->is_instance_klass() &&
|
||||
InstanceKlass::cast(klass)->is_unsafe_anonymous()) {
|
||||
// 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.
|
||||
// For non-anonymous classes the call to do_cld is made when the class
|
||||
// loader itself is handled.
|
||||
|
|
|
@ -612,7 +612,7 @@ oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
|
|||
const char* Klass::external_name() const {
|
||||
if (is_instance_klass()) {
|
||||
const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
|
||||
if (ik->is_anonymous()) {
|
||||
if (ik->is_unsafe_anonymous()) {
|
||||
char addr_buf[20];
|
||||
jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
|
||||
size_t addr_len = strlen(addr_buf);
|
||||
|
|
|
@ -654,7 +654,7 @@ protected:
|
|||
virtual void metaspace_pointers_do(MetaspaceClosure* iter);
|
||||
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.
|
||||
bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }
|
||||
|
||||
|
|
|
@ -510,7 +510,7 @@ void Parse::do_call() {
|
|||
if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) {
|
||||
ciInstanceKlass* calling_klass = method()->holder();
|
||||
ciInstanceKlass* sender_klass =
|
||||
calling_klass->is_anonymous() ? calling_klass->host_klass() :
|
||||
calling_klass->is_unsafe_anonymous() ? calling_klass->unsafe_anonymous_host() :
|
||||
calling_klass;
|
||||
if (sender_klass->is_interface()) {
|
||||
receiver_constraint = sender_klass;
|
||||
|
|
|
@ -136,7 +136,7 @@ bool VM_RedefineClasses::doit_prologue() {
|
|||
}
|
||||
|
||||
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
|
||||
if (!is_modifiable_class(mirror)) {
|
||||
_res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
|
||||
|
@ -278,8 +278,8 @@ bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Cannot redefine or retransform an anonymous class.
|
||||
if (InstanceKlass::cast(k)->is_anonymous()) {
|
||||
// Cannot redefine or retransform an unsafe anonymous class.
|
||||
if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -2650,7 +2650,7 @@ bool VM_RedefineClasses::skip_type_annotation_target(
|
|||
|
||||
case 0x10:
|
||||
// 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
|
||||
// location: ClassFile
|
||||
|
||||
|
|
|
@ -776,8 +776,8 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
|
|||
|
||||
// Make sure it's the real host class, not another anonymous class.
|
||||
while (host_klass != NULL && host_klass->is_instance_klass() &&
|
||||
InstanceKlass::cast(host_klass)->is_anonymous()) {
|
||||
host_klass = InstanceKlass::cast(host_klass)->host_klass();
|
||||
InstanceKlass::cast(host_klass)->is_unsafe_anonymous()) {
|
||||
host_klass = InstanceKlass::cast(host_klass)->unsafe_anonymous_host();
|
||||
}
|
||||
|
||||
// Primitive types have NULL Klass* fields in their java.lang.Class instances.
|
||||
|
|
|
@ -424,18 +424,18 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
|
|||
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);
|
||||
for (;;) {
|
||||
const InstanceKlass* hc = ik->host_klass();
|
||||
const InstanceKlass* hc = ik->unsafe_anonymous_host();
|
||||
if (hc == NULL) return false;
|
||||
if (hc == host_klass) return true;
|
||||
if (hc == unsafe_anonymous_host) return true;
|
||||
ik = hc;
|
||||
|
||||
// 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.
|
||||
// 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* 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.
|
||||
if (under_host_klass(accessor_ik, accessee_ik) ||
|
||||
under_host_klass(accessee_ik, accessor_ik))
|
||||
if (under_unsafe_anonymous_host(accessor_ik, accessee_ik) ||
|
||||
under_unsafe_anonymous_host(accessee_ik, accessor_ik))
|
||||
return true;
|
||||
|
||||
if ((RelaxAccessControlCheck &&
|
||||
|
@ -676,13 +676,13 @@ bool Reflection::verify_member_access(const Klass* current_class,
|
|||
}
|
||||
|
||||
const Klass* host_class = current_class;
|
||||
if (host_class->is_instance_klass() &&
|
||||
InstanceKlass::cast(host_class)->is_anonymous()) {
|
||||
host_class = InstanceKlass::cast(host_class)->host_klass();
|
||||
assert(host_class != NULL, "Anonymous class has null host class");
|
||||
if (current_class->is_instance_klass() &&
|
||||
InstanceKlass::cast(current_class)->is_unsafe_anonymous()) {
|
||||
host_class = InstanceKlass::cast(current_class)->unsafe_anonymous_host();
|
||||
assert(host_class != NULL, "Unsafe anonymous class has null host class");
|
||||
assert(!(host_class->is_instance_klass() &&
|
||||
InstanceKlass::cast(host_class)->is_anonymous()),
|
||||
"host_class should not be anonymous");
|
||||
InstanceKlass::cast(host_class)->is_unsafe_anonymous()),
|
||||
"unsafe_anonymous_host should not be unsafe anonymous itself");
|
||||
}
|
||||
if (host_class == member_class) {
|
||||
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
|
||||
// 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 (current_class->is_instance_klass() && member_class->is_instance_klass() ) {
|
||||
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,
|
||||
// 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 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.
|
||||
void Reflection::check_for_inner_class(const InstanceKlass* outer, const InstanceKlass* inner,
|
||||
bool inner_is_member, TRAPS) {
|
||||
|
|
|
@ -516,7 +516,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|||
nonstatic_field(ClassLoaderData, _class_loader, OopHandle) \
|
||||
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
|
||||
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*) \
|
||||
\
|
||||
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
|
||||
|
@ -2267,7 +2267,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|||
declare_constant(InstanceKlass::_misc_rewritten) \
|
||||
declare_constant(InstanceKlass::_misc_has_nonstatic_fields) \
|
||||
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_has_nonstatic_concrete_methods) \
|
||||
declare_constant(InstanceKlass::_misc_declares_nonstatic_concrete_methods)\
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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.classId = classId;
|
||||
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.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods.
|
||||
this.dependentMethodsOffset = -1;
|
||||
|
|
|
@ -45,14 +45,14 @@ public class ClassLoaderData extends VMObject {
|
|||
classLoaderField = type.getAddressField("_class_loader");
|
||||
nextField = type.getAddressField("_next");
|
||||
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");
|
||||
}
|
||||
|
||||
private static AddressField classLoaderField;
|
||||
private static AddressField nextField;
|
||||
private static MetadataField klassesField;
|
||||
private static CIntField isAnonymousField;
|
||||
private static CIntField isUnsafeAnonymousField;
|
||||
private static AddressField dictionaryField;
|
||||
|
||||
public ClassLoaderData(Address addr) {
|
||||
|
@ -81,8 +81,8 @@ public class ClassLoaderData extends VMObject {
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean getIsAnonymous() {
|
||||
return isAnonymousField.getValue(this) != 0;
|
||||
public boolean getisUnsafeAnonymous() {
|
||||
return isUnsafeAnonymousField.getValue(this) != 0;
|
||||
}
|
||||
|
||||
public ClassLoaderData next() {
|
||||
|
|
|
@ -69,7 +69,7 @@ public class InstanceKlass extends Klass {
|
|||
private static int MISC_REWRITTEN;
|
||||
private static int MISC_HAS_NONSTATIC_FIELDS;
|
||||
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_HAS_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_HAS_NONSTATIC_FIELDS = db.lookupIntConstant("InstanceKlass::_misc_has_nonstatic_fields").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_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();
|
||||
|
@ -281,7 +281,7 @@ public class InstanceKlass extends Klass {
|
|||
if (isInterface()) {
|
||||
size += wordLength;
|
||||
}
|
||||
if (isAnonymous()) {
|
||||
if (isUnsafeAnonymous()) {
|
||||
size += wordLength;
|
||||
}
|
||||
if (hasStoredFingerprint()) {
|
||||
|
@ -294,8 +294,8 @@ public class InstanceKlass extends Klass {
|
|||
return (int) miscFlags.getValue(this);
|
||||
}
|
||||
|
||||
public boolean isAnonymous() {
|
||||
return (getMiscFlags() & MISC_IS_ANONYMOUS) != 0;
|
||||
public boolean isUnsafeAnonymous() {
|
||||
return (getMiscFlags() & MISC_IS_UNSAFE_ANONYMOUS) != 0;
|
||||
}
|
||||
|
||||
public static boolean shouldStoreFingerprint() {
|
||||
|
|
|
@ -522,7 +522,7 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceWrapper
|
|||
return lookupType(cpi, opcode);
|
||||
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
|
||||
* entries do not have a symbol in the constant pool slot.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -110,6 +110,6 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
|
|||
@Override
|
||||
ResolvedJavaMethod getClassInitializer();
|
||||
|
||||
boolean isAnonymous();
|
||||
boolean isUnsafeAnonymous();
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -985,8 +985,8 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnonymous() {
|
||||
return (getMiscFlags() & config().instanceKlassMiscIsAnonymous) != 0;
|
||||
public boolean isUnsafeAnonymous() {
|
||||
return (getMiscFlags() & config().instanceKlassMiscIsUnsafeAnonymous) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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 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 arrayU1DataOffset = getFieldOffset("Array<u1>::_data", Integer.class);
|
||||
|
|
|
@ -102,9 +102,9 @@ protected:
|
|||
_spaces[i].lock = new Mutex(Monitor::native, "gtest-MetaspaceAllocationTest-lock", false, Monitor::_safepoint_check_never);
|
||||
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) ?
|
||||
Metaspace::AnonymousMetaspaceType : Metaspace::StandardMetaspaceType;
|
||||
Metaspace::UnsafeAnonymousMetaspaceType : Metaspace::StandardMetaspaceType;
|
||||
{
|
||||
// Pull lock during space creation, since this is what happens in the VM too
|
||||
// (see ClassLoaderData::metaspace_non_null(), which we mimick here).
|
||||
|
|
|
@ -114,7 +114,7 @@ public class TestIntConstant {
|
|||
{"CollectedHeap::G1 4",
|
||||
"RUNNABLE 2",
|
||||
"Deoptimization::Reason_class_check 4",
|
||||
"InstanceKlass::_misc_is_anonymous 32",
|
||||
"InstanceKlass::_misc_is_unsafe_anonymous 32",
|
||||
"Generation::ParNew 1",
|
||||
"_thread_uninitialized 0"};
|
||||
String[] tempConstantString = {"intConstant _temp_constant 45"};
|
||||
|
|
|
@ -76,9 +76,9 @@ public class TestClassLoaderStatsEvent {
|
|||
Events.assertField(event, "classCount").equal(1L);
|
||||
Events.assertField(event, "chunkSize").above(1L);
|
||||
Events.assertField(event, "blockSize").above(1L);
|
||||
Events.assertField(event, "anonymousClassCount").equal(1L);
|
||||
Events.assertField(event, "anonymousChunkSize").above(1L);
|
||||
Events.assertField(event, "anonymousBlockSize").above(1L);
|
||||
Events.assertField(event, "unsafeAnonymousClassCount").equal(1L);
|
||||
Events.assertField(event, "unsafeAnonymousChunkSize").above(1L);
|
||||
Events.assertField(event, "unsafeAnonymousBlockSize").above(1L);
|
||||
isAnyFound = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue