mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8297914: Remove java_lang_Class::process_archived_mirror()
Reviewed-by: ccheung
This commit is contained in:
parent
4be94e4350
commit
7bcd5f418c
10 changed files with 269 additions and 281 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2023, 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
|
||||
|
@ -55,6 +55,7 @@
|
|||
#include "runtime/fieldDescriptor.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepointVerifiers.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
@ -135,8 +136,11 @@ static ArchivableStaticFieldInfo fmg_open_archive_subgraph_entry_fields[] = {
|
|||
{NULL, NULL},
|
||||
};
|
||||
|
||||
KlassSubGraphInfo* HeapShared::_default_subgraph_info;
|
||||
GrowableArrayCHeap<oop, mtClassShared>* HeapShared::_pending_roots = NULL;
|
||||
OopHandle HeapShared::_roots;
|
||||
OopHandle HeapShared::_scratch_basic_type_mirrors[T_VOID+1];
|
||||
KlassToOopHandleTable* HeapShared::_scratch_java_mirror_table = NULL;
|
||||
|
||||
#ifdef ASSERT
|
||||
bool HeapShared::is_archived_object_during_dumptime(oop p) {
|
||||
|
@ -343,21 +347,108 @@ oop HeapShared::archive_object(oop obj) {
|
|||
return archived_oop;
|
||||
}
|
||||
|
||||
void HeapShared::archive_klass_objects() {
|
||||
class KlassToOopHandleTable: public ResourceHashtable<Klass*, OopHandle,
|
||||
36137, // prime number
|
||||
AnyObj::C_HEAP,
|
||||
mtClassShared> {
|
||||
public:
|
||||
oop get_oop(Klass* k) {
|
||||
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
|
||||
OopHandle* handle = get(k);
|
||||
if (handle != NULL) {
|
||||
return handle->resolve();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
void set_oop(Klass* k, oop o) {
|
||||
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
|
||||
OopHandle handle(Universe::vm_global(), o);
|
||||
bool is_new = put(k, handle);
|
||||
assert(is_new, "cannot set twice");
|
||||
}
|
||||
void remove_oop(Klass* k) {
|
||||
MutexLocker ml(ScratchObjects_lock, Mutex::_no_safepoint_check_flag);
|
||||
OopHandle* handle = get(k);
|
||||
if (handle != NULL) {
|
||||
handle->release(Universe::vm_global());
|
||||
remove(k);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void HeapShared::init_scratch_objects(TRAPS) {
|
||||
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
|
||||
BasicType bt = (BasicType)i;
|
||||
if (!is_reference_type(bt)) {
|
||||
oop m = java_lang_Class::create_basic_type_mirror(type2name(bt), bt, CHECK);
|
||||
_scratch_basic_type_mirrors[i] = OopHandle(Universe::vm_global(), m);
|
||||
}
|
||||
}
|
||||
_scratch_java_mirror_table = new (mtClass)KlassToOopHandleTable();
|
||||
}
|
||||
|
||||
oop HeapShared::scratch_java_mirror(BasicType t) {
|
||||
assert((uint)t < T_VOID+1, "range check");
|
||||
assert(!is_reference_type(t), "sanity");
|
||||
return _scratch_basic_type_mirrors[t].resolve();
|
||||
}
|
||||
|
||||
oop HeapShared::scratch_java_mirror(Klass* k) {
|
||||
return _scratch_java_mirror_table->get_oop(k);
|
||||
}
|
||||
|
||||
void HeapShared::set_scratch_java_mirror(Klass* k, oop mirror) {
|
||||
_scratch_java_mirror_table->set_oop(k, mirror);
|
||||
}
|
||||
|
||||
void HeapShared::remove_scratch_objects(Klass* k) {
|
||||
_scratch_java_mirror_table->remove_oop(k);
|
||||
}
|
||||
|
||||
void HeapShared::archive_java_mirrors() {
|
||||
init_seen_objects_table();
|
||||
|
||||
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
|
||||
BasicType bt = (BasicType)i;
|
||||
if (!is_reference_type(bt)) {
|
||||
oop m = _scratch_basic_type_mirrors[i].resolve();
|
||||
assert(m != NULL, "sanity");
|
||||
oop archived_m = archive_reachable_objects_from(1, _default_subgraph_info, m, /*is_closed_archive=*/ false);
|
||||
assert(archived_m != NULL, "sanity");
|
||||
|
||||
log_trace(cds, heap, mirror)(
|
||||
"Archived %s mirror object from " PTR_FORMAT " ==> " PTR_FORMAT,
|
||||
type2name(bt), p2i(m), p2i(archived_m));
|
||||
|
||||
Universe::set_archived_basic_type_mirror_index(bt, append_root(archived_m));
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArray<Klass*>* klasses = ArchiveBuilder::current()->klasses();
|
||||
assert(klasses != NULL, "sanity");
|
||||
for (int i = 0; i < klasses->length(); i++) {
|
||||
Klass* k = ArchiveBuilder::get_buffered_klass(klasses->at(i));
|
||||
Klass* orig_k = klasses->at(i);
|
||||
oop m = scratch_java_mirror(orig_k);
|
||||
if (m != NULL) {
|
||||
Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k);
|
||||
oop archived_m = archive_reachable_objects_from(1, _default_subgraph_info, m, /*is_closed_archive=*/ false);
|
||||
guarantee(archived_m != NULL, "scratch mirrors should not point to any unachivable objects");
|
||||
buffered_k->set_archived_java_mirror(append_root(archived_m));
|
||||
ResourceMark rm;
|
||||
log_trace(cds, heap, mirror)(
|
||||
"Archived %s mirror object from " PTR_FORMAT " ==> " PTR_FORMAT,
|
||||
buffered_k->external_name(), p2i(m), p2i(archived_m));
|
||||
|
||||
// archive mirror object
|
||||
java_lang_Class::archive_mirror(k);
|
||||
|
||||
// archive the resolved_referenes array
|
||||
if (k->is_instance_klass()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
ik->constants()->archive_resolved_references();
|
||||
// archive the resolved_referenes array
|
||||
if (buffered_k->is_instance_klass()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(buffered_k);
|
||||
ik->constants()->archive_resolved_references();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete_seen_objects_table();
|
||||
}
|
||||
|
||||
void HeapShared::mark_native_pointers(oop orig_obj, oop archived_obj) {
|
||||
|
@ -501,6 +592,8 @@ void HeapShared::archive_objects(GrowableArray<MemRegion>* closed_regions,
|
|||
{
|
||||
NoSafepointVerifier nsv;
|
||||
|
||||
_default_subgraph_info = init_subgraph_info(vmClasses::Object_klass(), false);
|
||||
|
||||
// Cache for recording where the archived objects are copied to
|
||||
create_archived_object_cache(log_is_enabled(Info, cds, map));
|
||||
|
||||
|
@ -516,6 +609,7 @@ void HeapShared::archive_objects(GrowableArray<MemRegion>* closed_regions,
|
|||
copy_open_objects(open_regions);
|
||||
|
||||
CDSHeapVerifier::verify();
|
||||
check_default_subgraph_classes();
|
||||
}
|
||||
|
||||
G1HeapVerifier::verify_archive_regions();
|
||||
|
@ -542,9 +636,7 @@ void HeapShared::copy_open_objects(GrowableArray<MemRegion>* open_regions) {
|
|||
|
||||
G1CollectedHeap::heap()->begin_archive_alloc_range(true /* open */);
|
||||
|
||||
java_lang_Class::archive_basic_type_mirrors();
|
||||
|
||||
archive_klass_objects();
|
||||
archive_java_mirrors();
|
||||
|
||||
archive_object_subgraphs(open_archive_subgraph_entry_fields,
|
||||
false /* is_closed_archive */,
|
||||
|
@ -1134,9 +1226,11 @@ class WalkOopAndArchiveClosure: public BasicOopIterateClosure {
|
|||
log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size " SIZE_FORMAT " %s", _level,
|
||||
_orig_referencing_obj->klass()->external_name(), field_delta,
|
||||
p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name());
|
||||
LogTarget(Trace, cds, heap) log;
|
||||
LogStream out(log);
|
||||
obj->print_on(&out);
|
||||
if (log_is_enabled(Trace, cds, heap)) {
|
||||
LogTarget(Trace, cds, heap) log;
|
||||
LogStream out(log);
|
||||
obj->print_on(&out);
|
||||
}
|
||||
}
|
||||
|
||||
oop archived = HeapShared::archive_reachable_objects_from(
|
||||
|
@ -1213,7 +1307,7 @@ oop HeapShared::archive_reachable_objects_from(int level,
|
|||
//
|
||||
// If you get an error here, you probably made a change in the JDK library that has added a Class
|
||||
// object that is referenced (directly or indirectly) by static fields.
|
||||
if (java_lang_Class::is_instance(orig_obj)) {
|
||||
if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _default_subgraph_info) {
|
||||
log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level);
|
||||
os::_exit(1);
|
||||
}
|
||||
|
@ -1431,6 +1525,31 @@ void HeapShared::verify_reachable_objects_from(oop obj, bool is_archived) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// The "default subgraph" contains special objects (see heapShared.hpp) that
|
||||
// can be accessed before we load any Java classes (including java/lang/Class).
|
||||
// Make sure that these are only instances of the very few specific types
|
||||
// that we can handle.
|
||||
void HeapShared::check_default_subgraph_classes() {
|
||||
GrowableArray<Klass*>* klasses = _default_subgraph_info->subgraph_object_klasses();
|
||||
int num = klasses->length();
|
||||
for (int i = 0; i < num; i++) {
|
||||
Klass* subgraph_k = klasses->at(i);
|
||||
if (log_is_enabled(Info, cds, heap)) {
|
||||
ResourceMark rm;
|
||||
log_info(cds, heap)(
|
||||
"Archived object klass (default subgraph %d) => %s",
|
||||
i, subgraph_k->external_name());
|
||||
}
|
||||
|
||||
guarantee(subgraph_k->name()->equals("java/lang/Class") ||
|
||||
subgraph_k->name()->equals("java/lang/String") ||
|
||||
subgraph_k->name()->equals("[Ljava/lang/Object;") ||
|
||||
subgraph_k->name()->equals("[C") ||
|
||||
subgraph_k->name()->equals("[B"),
|
||||
"default subgraph can have only these objects");
|
||||
}
|
||||
}
|
||||
|
||||
HeapShared::SeenObjectsTable* HeapShared::_seen_objects_table = NULL;
|
||||
int HeapShared::_num_new_walked_objs;
|
||||
int HeapShared::_num_new_archived_objs;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue