Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8245646: [lworld] LW3 Reduce impact of IdentityObject on metaspace #57

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -5057,6 +5057,11 @@ static Array<InstanceKlass*>* compute_transitive_interfaces(const InstanceKlass*
// length will be less than the max_transitive_size if duplicates were removed
const int length = result->length();
assert(length <= max_transitive_size, "just checking");

if (length == 1 && result->at(0) == SystemDictionary::IdentityObject_klass()) {
return Universe::the_single_IdentityObject_klass_array();
}

Array<InstanceKlass*>* const new_result =
MetadataFactory::new_array<InstanceKlass*>(loader_data, length, CHECK_NULL);
for (int i = 0; i < length; i++) {
@@ -6396,6 +6401,10 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
// it's official
set_klass(ik);

if (ik->name() == vmSymbols::java_lang_IdentityObject()) {
Universe::initialize_the_single_IdentityObject_klass_array(ik, CHECK);
}

debug_only(ik->verify();)
}

@@ -7047,6 +7056,8 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
int itfs_len = _temp_local_interfaces->length();
if (itfs_len == 0) {
_local_interfaces = Universe::the_empty_instance_klass_array();
} else if (itfs_len == 1 && _temp_local_interfaces->at(0) == SystemDictionary::IdentityObject_klass()) {
_local_interfaces = Universe::the_single_IdentityObject_klass_array();
} else {
_local_interfaces = MetadataFactory::new_array<InstanceKlass*>(_loader_data, itfs_len, NULL, CHECK);
for (int i = 0; i < itfs_len; i++) {
@@ -139,6 +139,7 @@ Array<int>* Universe::_the_empty_int_array = NULL;
Array<u2>* Universe::_the_empty_short_array = NULL;
Array<Klass*>* Universe::_the_empty_klass_array = NULL;
Array<InstanceKlass*>* Universe::_the_empty_instance_klass_array = NULL;
Array<InstanceKlass*>* Universe::_the_single_IdentityObject_klass_array = NULL;
Array<Method*>* Universe::_the_empty_method_array = NULL;

// These variables are guarded by FullGCALot_lock.
@@ -224,6 +225,7 @@ void Universe::metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_the_empty_instance_klass_array);
it->push(&_the_empty_method_array);
it->push(&_the_array_interfaces_array);
it->push(&_the_single_IdentityObject_klass_array);

_finalizer_register_cache->metaspace_pointers_do(it);
_loader_addClass_cache->metaspace_pointers_do(it);
@@ -262,6 +264,7 @@ void Universe::serialize(SerializeClosure* f) {
f->do_ptr((void**)&_the_empty_method_array);
f->do_ptr((void**)&_the_empty_klass_array);
f->do_ptr((void**)&_the_empty_instance_klass_array);
f->do_ptr((void**)&_the_single_IdentityObject_klass_array);
_finalizer_register_cache->serialize(f);
_loader_addClass_cache->serialize(f);
_throw_illegal_access_error_cache->serialize(f);
@@ -343,6 +346,8 @@ void Universe::genesis(TRAPS) {
assert(_the_array_interfaces_array->at(2) ==
SystemDictionary::IdentityObject_klass(), "u3");

assert(_the_single_IdentityObject_klass_array->at(0) ==
SystemDictionary::IdentityObject_klass(), "u3");
} else
#endif
{
@@ -471,6 +476,14 @@ void Universe::initialize_basic_type_mirrors(TRAPS) {
//_mirrors[T_ARRAY] = _object_klass->java_mirror();
}

void Universe::initialize_the_single_IdentityObject_klass_array(InstanceKlass* ik, TRAPS) {
assert(_the_single_IdentityObject_klass_array == NULL, "Must not be initialized twice");
assert(ik->name() == vmSymbols::java_lang_IdentityObject(), "Must be");
Array<InstanceKlass*>* array = MetadataFactory::new_array<InstanceKlass*>(ik->class_loader_data(), 1, NULL, CHECK);
array->at_put(0, ik);
_the_single_IdentityObject_klass_array = array;
}

void Universe::fixup_mirrors(TRAPS) {
// Bootstrap problem: all classes gets a mirror (java.lang.Class instance) assigned eagerly,
// but we cannot do that for classes created before java.lang.Class is loaded. Here we simply
@@ -136,6 +136,7 @@ class Universe: AllStatic {
static Array<u2>* _the_empty_short_array; // Canonicalized short array
static Array<Klass*>* _the_empty_klass_array; // Canonicalized klass array
static Array<InstanceKlass*>* _the_empty_instance_klass_array; // Canonicalized instance klass array
static Array<InstanceKlass*>* _the_single_IdentityObject_klass_array;
static Array<Method*>* _the_empty_method_array; // Canonicalized method array

static Array<Klass*>* _the_array_interfaces_array;
@@ -312,6 +313,12 @@ class Universe: AllStatic {
static Array<Method*>* the_empty_method_array() { return _the_empty_method_array; }
static Array<Klass*>* the_empty_klass_array() { return _the_empty_klass_array; }
static Array<InstanceKlass*>* the_empty_instance_klass_array() { return _the_empty_instance_klass_array; }
static Array<InstanceKlass*>* the_single_IdentityObject_klass_array() {
assert(_the_single_IdentityObject_klass_array != NULL, "Must be initialized before use");
assert(_the_single_IdentityObject_klass_array->length() == 1, "Sanity check");
return _the_single_IdentityObject_klass_array;
}
static void initialize_the_single_IdentityObject_klass_array(InstanceKlass* ik, TRAPS);

// OutOfMemoryError support. Returns an error with the required message. The returned error
// may or may not have a backtrace. If error has a backtrace then the stack trace is already
@@ -537,14 +537,16 @@ void InstanceKlass::deallocate_interfaces(ClassLoaderData* loader_data,
// check that the interfaces don't come from super class
Array<InstanceKlass*>* sti = (super_klass == NULL) ? NULL :
InstanceKlass::cast(super_klass)->transitive_interfaces();
if (ti != sti && ti != NULL && !ti->is_shared()) {
if (ti != sti && ti != NULL && !ti->is_shared() &&
ti != Universe::the_single_IdentityObject_klass_array()) {
MetadataFactory::free_array<InstanceKlass*>(loader_data, ti);
}
}

// local interfaces can be empty
if (local_interfaces != Universe::the_empty_instance_klass_array() &&
local_interfaces != NULL && !local_interfaces->is_shared()) {
local_interfaces != NULL && !local_interfaces->is_shared() &&
local_interfaces != Universe::the_single_IdentityObject_klass_array()) {
MetadataFactory::free_array<InstanceKlass*>(loader_data, local_interfaces);
}
}