Skip to content
Permalink
Browse files
8245646: [lworld] LW3 Reduce impact of IdentityObject on metaspace
Reviewed-by: dsimms
  • Loading branch information
fparain committed May 27, 2020
1 parent 27e8b6e commit ed7a00c6f70a264a1cd3445f5496b53543f4a8bf
Showing 4 changed files with 35 additions and 2 deletions.
@@ -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);
}
}

0 comments on commit ed7a00c

Please sign in to comment.