Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8250989: Consolidate buffer allocation code for CDS static/dynamic du…
…mping

Reviewed-by: ccheung, coleenp
  • Loading branch information
iklam committed Feb 7, 2021
1 parent 0e18634 commit c5ff454
Show file tree
Hide file tree
Showing 42 changed files with 701 additions and 918 deletions.
11 changes: 3 additions & 8 deletions src/hotspot/share/classfile/compactHashtable.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
Expand Down Expand Up @@ -198,13 +198,8 @@ void SimpleCompactHashtable::init(address base_address, u4 entry_count, u4 bucke
_bucket_count = bucket_count;
_entry_count = entry_count;
_base_address = base_address;
if (DynamicDumpSharedSpaces) {
_buckets = DynamicArchive::buffer_to_target(buckets);
_entries = DynamicArchive::buffer_to_target(entries);
} else {
_buckets = buckets;
_entries = entries;
}
_buckets = buckets;
_entries = entries;
}

size_t SimpleCompactHashtable::calculate_header_size() {
Expand Down
35 changes: 22 additions & 13 deletions src/hotspot/share/classfile/javaClasses.cpp
Expand Up @@ -41,6 +41,7 @@
#include "interpreter/linkResolver.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/archiveBuilder.hpp"
#include "memory/heapShared.inline.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/oopFactory.hpp"
Expand Down Expand Up @@ -855,7 +856,9 @@ static void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) {
break;
case T_OBJECT:
{
assert(fd->signature() == vmSymbols::string_signature(),
// Can't use vmSymbols::string_signature() as fd->signature() may have been relocated
// during DumpSharedSpaces
assert(fd->signature()->equals("Ljava/lang/String;"),
"just checking");
if (DumpSharedSpaces && HeapShared::is_archived_object(mirror())) {
// Archive the String field and update the pointer.
Expand Down Expand Up @@ -1122,6 +1125,21 @@ class ResetMirrorField: public FieldClosure {
}
};

static void set_klass_field_in_archived_mirror(oop mirror_obj, int offset, Klass* k) {
assert(java_lang_Class::is_instance(mirror_obj), "must be");
// this is the copy of k in the output buffer
Klass* copy = ArchiveBuilder::get_relocated_klass(k);

// This is the address of k, if the archive is loaded at the requested location
Klass* def = ArchiveBuilder::current()->to_requested(copy);

log_debug(cds, heap, mirror)(
"Relocate mirror metadata field at %d from " PTR_FORMAT " ==> " PTR_FORMAT,
offset, p2i(k), p2i(def));

mirror_obj->metadata_field_put(offset, def);
}

void java_lang_Class::archive_basic_type_mirrors(TRAPS) {
assert(HeapShared::is_heap_object_archiving_allowed(),
"HeapShared::is_heap_object_archiving_allowed() must be true");
Expand All @@ -1136,8 +1154,7 @@ void java_lang_Class::archive_basic_type_mirrors(TRAPS) {
Klass *ak = (Klass*)(archived_m->metadata_field(_array_klass_offset));
assert(ak != NULL || t == T_VOID, "should not be NULL");
if (ak != NULL) {
Klass *reloc_ak = MetaspaceShared::get_relocated_klass(ak, true);
archived_m->metadata_field_put(_array_klass_offset, reloc_ak);
set_klass_field_in_archived_mirror(archived_m, _array_klass_offset, ak);
}

// Clear the fields. Just to be safe
Expand Down Expand Up @@ -1259,21 +1276,13 @@ oop java_lang_Class::process_archived_mirror(Klass* k, oop mirror,
// The archived mirror's field at _klass_offset is still pointing to the original
// klass. Updated the field in the archived mirror to point to the relocated
// klass in the archive.
Klass *reloc_k = MetaspaceShared::get_relocated_klass(as_Klass(mirror), true);
log_debug(cds, heap, mirror)(
"Relocate mirror metadata field at _klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
p2i(as_Klass(mirror)), p2i(reloc_k));
archived_mirror->metadata_field_put(_klass_offset, reloc_k);
set_klass_field_in_archived_mirror(archived_mirror, _klass_offset, as_Klass(mirror));

// The field at _array_klass_offset is pointing to the original one dimension
// higher array klass if exists. Relocate the pointer.
Klass *arr = array_klass_acquire(mirror);
if (arr != NULL) {
Klass *reloc_arr = MetaspaceShared::get_relocated_klass(arr, true);
log_debug(cds, heap, mirror)(
"Relocate mirror metadata field at _array_klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
p2i(arr), p2i(reloc_arr));
archived_mirror->metadata_field_put(_array_klass_offset, reloc_arr);
set_klass_field_in_archived_mirror(archived_mirror, _array_klass_offset, arr);
}
return archived_mirror;
}
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/classfile/stringTable.cpp
Expand Up @@ -719,6 +719,7 @@ oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) {

oop StringTable::create_archived_string(oop s, Thread* THREAD) {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
assert(java_lang_String::is_instance(s), "sanity");
assert(!HeapShared::is_archived_object(s), "sanity");

oop new_s = NULL;
Expand Down
15 changes: 2 additions & 13 deletions src/hotspot/share/classfile/symbolTable.cpp
Expand Up @@ -584,17 +584,15 @@ void SymbolTable::dump(outputStream* st, bool verbose) {
#if INCLUDE_CDS
void SymbolTable::copy_shared_symbol_table(GrowableArray<Symbol*>* symbols,
CompactHashtableWriter* writer) {
ArchiveBuilder* builder = ArchiveBuilder::current();
int len = symbols->length();
for (int i = 0; i < len; i++) {
Symbol* sym = ArchiveBuilder::get_relocated_symbol(symbols->at(i));
unsigned int fixed_hash = hash_shared_symbol((const char*)sym->bytes(), sym->utf8_length());
assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false),
"must not rehash during dumping");
sym->set_permanent();
if (DynamicDumpSharedSpaces) {
sym = DynamicArchive::buffer_to_target(sym);
}
writer->add(fixed_hash, MetaspaceShared::object_delta_u4(sym));
writer->add(fixed_hash, builder->buffer_to_offset_u4((address)sym));
}
}

Expand All @@ -609,15 +607,6 @@ void SymbolTable::write_to_archive(GrowableArray<Symbol*>* symbols) {
if (!DynamicDumpSharedSpaces) {
_shared_table.reset();
writer.dump(&_shared_table, "symbol");

// Verify the written shared table is correct -- at this point,
// vmSymbols has already been relocated to point to the archived
// version of the Symbols.
Symbol* sym = vmSymbols::java_lang_Object();
const char* name = (const char*)sym->bytes();
int len = sym->utf8_length();
unsigned int hash = hash_symbol(name, len, _alt_hash);
assert(sym == _shared_table.lookup(name, hash, len), "sanity");
} else {
_dynamic_shared_table.reset();
writer.dump(&_dynamic_shared_table, "symbol");
Expand Down
123 changes: 53 additions & 70 deletions src/hotspot/share/classfile/systemDictionaryShared.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -279,15 +280,6 @@ class DumpTimeSharedClassTable: public ResourceHashtable<
};

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;
Expand Down Expand Up @@ -318,13 +310,13 @@ class LambdaProxyClassKey {
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 {
Expand All @@ -337,11 +329,11 @@ class LambdaProxyClassKey {
}

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) {
Expand Down Expand Up @@ -406,10 +398,8 @@ class RunTimeLambdaProxyClassInfo {
}
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);
}

Expand Down Expand Up @@ -604,14 +594,9 @@ class RunTimeSharedClassInfo {
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();
Expand All @@ -625,8 +610,8 @@ class RunTimeSharedClassInfo {
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);
Expand All @@ -636,20 +621,16 @@ class RunTimeSharedClassInfo {
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;
}
}

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);
}

Expand Down Expand Up @@ -682,13 +663,9 @@ class RunTimeSharedClassInfo {
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));
}

Expand Down Expand Up @@ -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).
Expand All @@ -2047,10 +2040,8 @@ class CopyLambdaProxyClassInfoToArchive : StackObj {
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;
}
Expand All @@ -2065,31 +2056,31 @@ class AdjustLambdaProxyClassInfo : StackObj {
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);
bk1->set_lambda_proxy_is_available();
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;
}
};

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) {
Expand All @@ -2100,16 +2091,8 @@ class CopySharedClassInfoToArchive : StackObj {

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 {
Expand Down Expand Up @@ -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
Expand Down

1 comment on commit c5ff454

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.