8250989: Consolidate buffer allocation code for CDS static/dynamic dumping

Reviewed-by: ccheung, coleenp
This commit is contained in:
Ioi Lam 2021-02-07 07:10:38 +00:00
parent 0e18634b6a
commit c5ff454481
42 changed files with 701 additions and 918 deletions

View file

@ -44,6 +44,7 @@
#include "logging/logStream.hpp"
#include "memory/allocation.hpp"
#include "memory/archiveUtils.hpp"
#include "memory/archiveBuilder.hpp"
#include "memory/dynamicArchive.hpp"
#include "memory/filemap.hpp"
#include "memory/heapShared.hpp"
@ -279,15 +280,6 @@ public:
};
class LambdaProxyClassKey {
template <typename T> static void original_to_target(T& field) {
if (field != NULL) {
if (DynamicDumpSharedSpaces) {
field = DynamicArchive::original_to_target(field);
}
ArchivePtrMarker::mark_pointer(&field);
}
}
InstanceKlass* _caller_ik;
Symbol* _invoked_name;
Symbol* _invoked_type;
@ -318,13 +310,13 @@ public:
it->push(&_instantiated_method_type);
}
void original_to_target() {
original_to_target(_caller_ik);
original_to_target(_instantiated_method_type);
original_to_target(_invoked_name);
original_to_target(_invoked_type);
original_to_target(_member_method);
original_to_target(_method_type);
void mark_pointers() {
ArchivePtrMarker::mark_pointer(&_caller_ik);
ArchivePtrMarker::mark_pointer(&_instantiated_method_type);
ArchivePtrMarker::mark_pointer(&_invoked_name);
ArchivePtrMarker::mark_pointer(&_invoked_type);
ArchivePtrMarker::mark_pointer(&_member_method);
ArchivePtrMarker::mark_pointer(&_method_type);
}
bool equals(LambdaProxyClassKey const& other) const {
@ -337,11 +329,11 @@ public:
}
unsigned int hash() const {
return SystemDictionaryShared::hash_for_shared_dictionary(_caller_ik) +
SystemDictionaryShared::hash_for_shared_dictionary(_invoked_name) +
SystemDictionaryShared::hash_for_shared_dictionary(_invoked_type) +
SystemDictionaryShared::hash_for_shared_dictionary(_method_type) +
SystemDictionaryShared::hash_for_shared_dictionary(_instantiated_method_type);
return SystemDictionaryShared::hash_for_shared_dictionary((address)_caller_ik) +
SystemDictionaryShared::hash_for_shared_dictionary((address)_invoked_name) +
SystemDictionaryShared::hash_for_shared_dictionary((address)_invoked_type) +
SystemDictionaryShared::hash_for_shared_dictionary((address)_method_type) +
SystemDictionaryShared::hash_for_shared_dictionary((address)_instantiated_method_type);
}
static unsigned int dumptime_hash(Symbol* sym) {
@ -406,10 +398,8 @@ public:
}
void init(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
_key = key;
_key.original_to_target();
_proxy_klass_head = DynamicDumpSharedSpaces ?
DynamicArchive::original_to_target(info._proxy_klasses->at(0)) :
info._proxy_klasses->at(0);
_key.mark_pointers();
_proxy_klass_head = info._proxy_klasses->at(0);
ArchivePtrMarker::mark_pointer(&_proxy_klass_head);
}
@ -604,14 +594,9 @@ public:
return loader_constraints() + i;
}
static u4 object_delta_u4(Symbol* sym) {
if (DynamicDumpSharedSpaces) {
sym = DynamicArchive::original_to_target(sym);
}
return MetaspaceShared::object_delta_u4(sym);
}
void init(DumpTimeSharedClassInfo& info) {
ArchiveBuilder* builder = ArchiveBuilder::current();
assert(builder->is_in_buffer_space(info._klass), "must be");
_klass = info._klass;
if (!SystemDictionaryShared::is_builtin(_klass)) {
CrcInfo* c = crc();
@ -625,8 +610,8 @@ public:
RTVerifierConstraint* vf_constraints = verifier_constraints();
char* flags = verifier_constraint_flags();
for (i = 0; i < _num_verifier_constraints; i++) {
vf_constraints[i]._name = object_delta_u4(info._verifier_constraints->at(i)._name);
vf_constraints[i]._from_name = object_delta_u4(info._verifier_constraints->at(i)._from_name);
vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i)._name);
vf_constraints[i]._from_name = builder->any_to_offset_u4(info._verifier_constraints->at(i)._from_name);
}
for (i = 0; i < _num_verifier_constraints; i++) {
flags[i] = info._verifier_constraint_flags->at(i);
@ -636,7 +621,7 @@ public:
if (_num_loader_constraints > 0) {
RTLoaderConstraint* ld_constraints = loader_constraints();
for (i = 0; i < _num_loader_constraints; i++) {
ld_constraints[i]._name = object_delta_u4(info._loader_constraints->at(i)._name);
ld_constraints[i]._name = builder->any_to_offset_u4(info._loader_constraints->at(i)._name);
ld_constraints[i]._loader_type1 = info._loader_constraints->at(i)._loader_type1;
ld_constraints[i]._loader_type2 = info._loader_constraints->at(i)._loader_type2;
}
@ -644,12 +629,8 @@ public:
if (_klass->is_hidden()) {
InstanceKlass* n_h = info.nest_host();
if (DynamicDumpSharedSpaces) {
n_h = DynamicArchive::original_to_target(n_h);
}
set_nest_host(n_h);
}
_klass = DynamicDumpSharedSpaces ? DynamicArchive::original_to_target(info._klass) : info._klass;
ArchivePtrMarker::mark_pointer(&_klass);
}
@ -682,13 +663,9 @@ public:
return *info_pointer_addr(klass);
}
static void set_for(InstanceKlass* klass, RunTimeSharedClassInfo* record) {
if (DynamicDumpSharedSpaces) {
klass = DynamicArchive::original_to_buffer(klass);
*info_pointer_addr(klass) = DynamicArchive::buffer_to_target(record);
} else {
*info_pointer_addr(klass) = record;
}
assert(ArchiveBuilder::current()->is_in_buffer_space(klass), "must be");
assert(ArchiveBuilder::current()->is_in_buffer_space(record), "must be");
*info_pointer_addr(klass) = record;
ArchivePtrMarker::mark_pointer(info_pointer_addr(klass));
}
@ -2026,11 +2003,27 @@ size_t SystemDictionaryShared::estimate_size_for_archive() {
return total_size;
}
unsigned int SystemDictionaryShared::hash_for_shared_dictionary(address ptr) {
if (ArchiveBuilder::is_active()) {
uintx offset = ArchiveBuilder::current()->any_to_offset(ptr);
unsigned int hash = primitive_hash<uintx>(offset);
DEBUG_ONLY({
if (MetaspaceObj::is_shared((const MetaspaceObj*)ptr)) {
assert(hash == SystemDictionaryShared::hash_for_shared_dictionary_quick(ptr), "must be");
}
});
return hash;
} else {
return SystemDictionaryShared::hash_for_shared_dictionary_quick(ptr);
}
}
class CopyLambdaProxyClassInfoToArchive : StackObj {
CompactHashtableWriter* _writer;
ArchiveBuilder* _builder;
public:
CopyLambdaProxyClassInfoToArchive(CompactHashtableWriter* writer)
: _writer(writer) {}
: _writer(writer), _builder(ArchiveBuilder::current()) {}
bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
// In static dump, info._proxy_klasses->at(0) is already relocated to point to the archived class
// (not the original class).
@ -2047,10 +2040,8 @@ public:
RunTimeLambdaProxyClassInfo* runtime_info =
(RunTimeLambdaProxyClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size);
runtime_info->init(key, info);
unsigned int hash = runtime_info->hash(); // Fields in runtime_info->_key already point to target space.
u4 delta = DynamicDumpSharedSpaces ?
MetaspaceShared::object_delta_u4((void*)DynamicArchive::buffer_to_target(runtime_info)) :
MetaspaceShared::object_delta_u4((void*)runtime_info);
unsigned int hash = runtime_info->hash();
u4 delta = _builder->any_to_offset_u4((void*)runtime_info);
_writer->add(hash, delta);
return true;
}
@ -2065,8 +2056,10 @@ public:
for (int i = 0; i < len-1; i++) {
InstanceKlass* ok0 = info._proxy_klasses->at(i+0); // this is original klass
InstanceKlass* ok1 = info._proxy_klasses->at(i+1); // this is original klass
InstanceKlass* bk0 = DynamicDumpSharedSpaces ? DynamicArchive::original_to_buffer(ok0) : ok0;
InstanceKlass* bk1 = DynamicDumpSharedSpaces ? DynamicArchive::original_to_buffer(ok1) : ok1;
assert(ArchiveBuilder::current()->is_in_buffer_space(ok0), "must be");
assert(ArchiveBuilder::current()->is_in_buffer_space(ok1), "must be");
InstanceKlass* bk0 = ok0;
InstanceKlass* bk1 = ok1;
assert(bk0->next_link() == 0, "must be called after Klass::remove_unshareable_info()");
assert(bk1->next_link() == 0, "must be called after Klass::remove_unshareable_info()");
bk0->set_next_link(bk1);
@ -2074,11 +2067,8 @@ public:
ArchivePtrMarker::mark_pointer(bk0->next_link_addr());
}
}
if (DynamicDumpSharedSpaces) {
DynamicArchive::original_to_buffer(info._proxy_klasses->at(0))->set_lambda_proxy_is_available();
} else {
info._proxy_klasses->at(0)->set_lambda_proxy_is_available();
}
info._proxy_klasses->at(0)->set_lambda_proxy_is_available();
return true;
}
};
@ -2086,10 +2076,11 @@ public:
class CopySharedClassInfoToArchive : StackObj {
CompactHashtableWriter* _writer;
bool _is_builtin;
ArchiveBuilder *_builder;
public:
CopySharedClassInfoToArchive(CompactHashtableWriter* writer,
bool is_builtin)
: _writer(writer), _is_builtin(is_builtin) {}
: _writer(writer), _is_builtin(is_builtin), _builder(ArchiveBuilder::current()) {}
bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
if (!info.is_excluded() && info.is_builtin() == _is_builtin) {
@ -2100,16 +2091,8 @@ public:
unsigned int hash;
Symbol* name = info._klass->name();
if (DynamicDumpSharedSpaces) {
name = DynamicArchive::original_to_target(name);
}
hash = SystemDictionaryShared::hash_for_shared_dictionary(name);
u4 delta;
if (DynamicDumpSharedSpaces) {
delta = MetaspaceShared::object_delta_u4(DynamicArchive::buffer_to_target(record));
} else {
delta = MetaspaceShared::object_delta_u4(record);
}
hash = SystemDictionaryShared::hash_for_shared_dictionary((address)name);
u4 delta = _builder->buffer_to_offset_u4((address)record);
if (_is_builtin && info._klass->is_hidden()) {
// skip
} else {
@ -2200,7 +2183,7 @@ SystemDictionaryShared::find_record(RunTimeSharedDictionary* static_dict, RunTim
return NULL;
}
unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary(name);
unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary_quick(name);
const RunTimeSharedClassInfo* record = NULL;
if (!MetaspaceShared::is_shared_dynamic(name)) {
// The names of all shared classes in the static dict must also be in the