mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8247666: Support Lambda proxy classes in static CDS archive
Reviewed-by: iklam, mchung
This commit is contained in:
parent
e2e11d3449
commit
74ac77e2b1
38 changed files with 1960 additions and 130 deletions
|
@ -31,11 +31,13 @@
|
|||
#include "classfile/classLoaderExt.hpp"
|
||||
#include "classfile/dictionary.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#include "classfile/verificationType.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "interpreter/bootstrapInfo.hpp"
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
@ -98,6 +100,7 @@ public:
|
|||
};
|
||||
|
||||
InstanceKlass* _klass;
|
||||
InstanceKlass* _nest_host;
|
||||
bool _failed_verification;
|
||||
bool _is_archived_lambda_proxy;
|
||||
int _id;
|
||||
|
@ -109,6 +112,7 @@ public:
|
|||
|
||||
DumpTimeSharedClassInfo() {
|
||||
_klass = NULL;
|
||||
_nest_host = NULL;
|
||||
_failed_verification = false;
|
||||
_is_archived_lambda_proxy = false;
|
||||
_id = -1;
|
||||
|
@ -146,6 +150,7 @@ public:
|
|||
|
||||
void metaspace_pointers_do(MetaspaceClosure* it) {
|
||||
it->push(&_klass);
|
||||
it->push(&_nest_host);
|
||||
if (_verifier_constraints != NULL) {
|
||||
for (int i = 0; i < _verifier_constraints->length(); i++) {
|
||||
DTVerifierConstraint* cons = _verifier_constraints->adr_at(i);
|
||||
|
@ -177,6 +182,14 @@ public:
|
|||
bool failed_verification() {
|
||||
return _failed_verification;
|
||||
}
|
||||
|
||||
void set_nest_host(InstanceKlass* nest_host) {
|
||||
_nest_host = nest_host;
|
||||
}
|
||||
|
||||
InstanceKlass* nest_host() {
|
||||
return _nest_host;
|
||||
}
|
||||
};
|
||||
|
||||
inline unsigned DumpTimeSharedClassTable_hash(InstanceKlass* const& k) {
|
||||
|
@ -257,7 +270,9 @@ public:
|
|||
class LambdaProxyClassKey {
|
||||
template <typename T> static void original_to_target(T& field) {
|
||||
if (field != NULL) {
|
||||
field = DynamicArchive::original_to_target(field);
|
||||
if (DynamicDumpSharedSpaces) {
|
||||
field = DynamicArchive::original_to_target(field);
|
||||
}
|
||||
ArchivePtrMarker::mark_pointer(&field);
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +298,15 @@ public:
|
|||
_member_method(member_method),
|
||||
_instantiated_method_type(instantiated_method_type) {}
|
||||
|
||||
void metaspace_pointers_do(MetaspaceClosure* it) {
|
||||
it->push(&_caller_ik);
|
||||
it->push(&_invoked_name);
|
||||
it->push(&_invoked_type);
|
||||
it->push(&_method_type);
|
||||
it->push(&_member_method);
|
||||
it->push(&_instantiated_method_type);
|
||||
}
|
||||
|
||||
void original_to_target() {
|
||||
original_to_target(_caller_ik);
|
||||
original_to_target(_instantiated_method_type);
|
||||
|
@ -309,12 +333,20 @@ public:
|
|||
SystemDictionaryShared::hash_for_shared_dictionary(_instantiated_method_type);
|
||||
}
|
||||
|
||||
static unsigned int dumptime_hash(Symbol* sym) {
|
||||
if (sym == NULL) {
|
||||
// _invoked_name maybe NULL
|
||||
return 0;
|
||||
}
|
||||
return java_lang_String::hash_code((const jbyte*)sym->bytes(), sym->utf8_length());
|
||||
}
|
||||
|
||||
unsigned int dumptime_hash() const {
|
||||
return primitive_hash<InstanceKlass*>(_caller_ik) +
|
||||
primitive_hash<Symbol*>(_invoked_name) +
|
||||
primitive_hash<Symbol*>(_invoked_type) +
|
||||
primitive_hash<Symbol*>(_method_type) +
|
||||
primitive_hash<Symbol*>(_instantiated_method_type);
|
||||
return dumptime_hash(_caller_ik->name()) +
|
||||
dumptime_hash(_invoked_name) +
|
||||
dumptime_hash(_invoked_type) +
|
||||
dumptime_hash(_method_type) +
|
||||
dumptime_hash(_instantiated_method_type);
|
||||
}
|
||||
|
||||
static inline unsigned int DUMPTIME_HASH(LambdaProxyClassKey const& key) {
|
||||
|
@ -339,14 +371,20 @@ public:
|
|||
assert(_proxy_klasses != NULL, "sanity");
|
||||
_proxy_klasses->append(proxy_klass);
|
||||
}
|
||||
|
||||
void metaspace_pointers_do(MetaspaceClosure* it) {
|
||||
for (int i=0; i<_proxy_klasses->length(); i++) {
|
||||
it->push(_proxy_klasses->adr_at(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class RunTimeLambdaProxyClassInfo {
|
||||
LambdaProxyClassKey _key;
|
||||
InstanceKlass* _proxy_klass_head;
|
||||
public:
|
||||
RunTimeLambdaProxyClassInfo(LambdaProxyClassKey key, InstanceKlass* proxy_klass) :
|
||||
_key(key), _proxy_klass_head(proxy_klass) {}
|
||||
RunTimeLambdaProxyClassInfo(LambdaProxyClassKey key, InstanceKlass* proxy_klass_head) :
|
||||
_key(key), _proxy_klass_head(proxy_klass_head) {}
|
||||
|
||||
InstanceKlass* proxy_klass_head() const { return _proxy_klass_head; }
|
||||
|
||||
|
@ -358,13 +396,18 @@ public:
|
|||
void init(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
|
||||
_key = key;
|
||||
_key.original_to_target();
|
||||
_proxy_klass_head = DynamicArchive::original_to_target(info._proxy_klasses->at(0));
|
||||
_proxy_klass_head = DynamicDumpSharedSpaces ?
|
||||
DynamicArchive::original_to_target(info._proxy_klasses->at(0)) :
|
||||
info._proxy_klasses->at(0);
|
||||
ArchivePtrMarker::mark_pointer(&_proxy_klass_head);
|
||||
}
|
||||
|
||||
unsigned int hash() const {
|
||||
return _key.hash();
|
||||
}
|
||||
LambdaProxyClassKey key() const {
|
||||
return _key;
|
||||
}
|
||||
};
|
||||
|
||||
class LambdaProxyClassDictionary : public OffsetCompactHashtable<
|
||||
|
@ -374,6 +417,8 @@ class LambdaProxyClassDictionary : public OffsetCompactHashtable<
|
|||
|
||||
LambdaProxyClassDictionary _lambda_proxy_class_dictionary;
|
||||
|
||||
LambdaProxyClassDictionary _dynamic_lambda_proxy_class_dictionary;
|
||||
|
||||
class DumpTimeLambdaProxyClassDictionary
|
||||
: public ResourceHashtable<LambdaProxyClassKey,
|
||||
DumpTimeLambdaProxyClassInfo,
|
||||
|
@ -585,15 +630,15 @@ public:
|
|||
ld_constraints[i]._loader_type2 = info._loader_constraints->at(i)._loader_type2;
|
||||
}
|
||||
}
|
||||
if (DynamicDumpSharedSpaces) {
|
||||
if (_klass->is_hidden()) {
|
||||
Thread* THREAD = Thread::current();
|
||||
InstanceKlass* n_h = _klass->nest_host(THREAD);
|
||||
|
||||
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 = DynamicArchive::original_to_target(info._klass);
|
||||
set_nest_host(n_h);
|
||||
}
|
||||
_klass = DynamicDumpSharedSpaces ? DynamicArchive::original_to_target(info._klass) : info._klass;
|
||||
ArchivePtrMarker::mark_pointer(&_klass);
|
||||
}
|
||||
|
||||
|
@ -1389,7 +1434,7 @@ void SystemDictionaryShared::validate_before_archiving(InstanceKlass* k) {
|
|||
class ExcludeDumpTimeSharedClasses : StackObj {
|
||||
public:
|
||||
bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
|
||||
if (SystemDictionaryShared::should_be_excluded(k)) {
|
||||
if (SystemDictionaryShared::should_be_excluded(k) || info.is_excluded()) {
|
||||
info.set_excluded();
|
||||
}
|
||||
return true; // keep on iterating
|
||||
|
@ -1449,10 +1494,26 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class IterateDumpTimeLambdaProxyClassDictionary : StackObj {
|
||||
MetaspaceClosure *_it;
|
||||
public:
|
||||
IterateDumpTimeLambdaProxyClassDictionary(MetaspaceClosure* it) : _it(it) {}
|
||||
|
||||
bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
|
||||
info.metaspace_pointers_do(_it);
|
||||
key.metaspace_pointers_do(_it);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void SystemDictionaryShared::dumptime_classes_do(class MetaspaceClosure* it) {
|
||||
assert_locked_or_safepoint(DumpTimeTable_lock);
|
||||
IterateDumpTimeSharedClassTable iter(it);
|
||||
_dumptime_table->iterate(&iter);
|
||||
if (_dumptime_lambda_proxy_class_dictionary != NULL) {
|
||||
IterateDumpTimeLambdaProxyClassDictionary iter_lambda(it);
|
||||
_dumptime_lambda_proxy_class_dictionary->iterate(&iter_lambda);
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbol* name,
|
||||
|
@ -1523,7 +1584,8 @@ void SystemDictionaryShared::add_lambda_proxy_class(InstanceKlass* caller_ik,
|
|||
Symbol* invoked_type,
|
||||
Symbol* method_type,
|
||||
Method* member_method,
|
||||
Symbol* instantiated_method_type) {
|
||||
Symbol* instantiated_method_type,
|
||||
TRAPS) {
|
||||
|
||||
assert(caller_ik->class_loader() == lambda_ik->class_loader(), "mismatched class loader");
|
||||
assert(caller_ik->class_loader_data() == lambda_ik->class_loader_data(), "mismatched class loader data");
|
||||
|
@ -1533,12 +1595,14 @@ void SystemDictionaryShared::add_lambda_proxy_class(InstanceKlass* caller_ik,
|
|||
|
||||
lambda_ik->assign_class_loader_type();
|
||||
lambda_ik->set_shared_classpath_index(caller_ik->shared_classpath_index());
|
||||
InstanceKlass* nest_host = caller_ik->nest_host(THREAD);
|
||||
|
||||
DumpTimeSharedClassInfo* info = _dumptime_table->get(lambda_ik);
|
||||
if (info != NULL && !lambda_ik->is_non_strong_hidden() && is_builtin(lambda_ik) && is_builtin(caller_ik)) {
|
||||
// Set _is_archived_lambda_proxy in DumpTimeSharedClassInfo so that the lambda_ik
|
||||
// won't be excluded during dumping of shared archive. See ExcludeDumpTimeSharedClasses.
|
||||
info->_is_archived_lambda_proxy = true;
|
||||
info->set_nest_host(nest_host);
|
||||
|
||||
LambdaProxyClassKey key(caller_ik,
|
||||
invoked_name,
|
||||
|
@ -1560,6 +1624,10 @@ InstanceKlass* SystemDictionaryShared::get_shared_lambda_proxy_class(InstanceKla
|
|||
LambdaProxyClassKey key(caller_ik, invoked_name, invoked_type,
|
||||
method_type, member_method, instantiated_method_type);
|
||||
const RunTimeLambdaProxyClassInfo* info = _lambda_proxy_class_dictionary.lookup(&key, key.hash(), 0);
|
||||
if (info == NULL) {
|
||||
// Try lookup from the dynamic lambda proxy class dictionary.
|
||||
info = _dynamic_lambda_proxy_class_dictionary.lookup(&key, key.hash(), 0);
|
||||
}
|
||||
InstanceKlass* proxy_klass = NULL;
|
||||
if (info != NULL) {
|
||||
InstanceKlass* curr_klass = info->proxy_klass_head();
|
||||
|
@ -1577,7 +1645,7 @@ InstanceKlass* SystemDictionaryShared::get_shared_lambda_proxy_class(InstanceKla
|
|||
proxy_klass->clear_lambda_proxy_is_available();
|
||||
if (log_is_enabled(Debug, cds)) {
|
||||
ResourceMark rm;
|
||||
log_debug(cds)("Loaded lambda proxy: %s", proxy_klass->external_name());
|
||||
log_debug(cds)("Loaded lambda proxy: %s ", proxy_klass->external_name());
|
||||
}
|
||||
} else {
|
||||
if (log_is_enabled(Debug, cds)) {
|
||||
|
@ -1612,6 +1680,10 @@ InstanceKlass* SystemDictionaryShared::prepare_shared_lambda_proxy_class(Instanc
|
|||
InstanceKlass* loaded_lambda =
|
||||
SystemDictionary::load_shared_lambda_proxy_class(lambda_ik, class_loader, protection_domain, pkg_entry, CHECK_NULL);
|
||||
|
||||
if (loaded_lambda == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ensures the nest host is the same as the lambda proxy's
|
||||
// nest host recorded at dump time.
|
||||
InstanceKlass* nest_host = caller_ik->nest_host(THREAD);
|
||||
|
@ -1846,6 +1918,49 @@ bool SystemDictionaryShared::check_linking_constraints(InstanceKlass* klass, TRA
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SystemDictionaryShared::is_supported_invokedynamic(BootstrapInfo* bsi) {
|
||||
if (bsi->arg_values() == NULL || !bsi->arg_values()->is_objArray()) {
|
||||
DEBUG_ONLY(
|
||||
tty->print_cr("bsi check failed");
|
||||
tty->print_cr(" bsi->arg_values().not_null() %d", bsi->arg_values().not_null());
|
||||
if (bsi->arg_values().not_null()) {
|
||||
tty->print_cr(" bsi->arg_values()->is_objArray() %d", bsi->arg_values()->is_objArray());
|
||||
bsi->print();
|
||||
}
|
||||
)
|
||||
return false;
|
||||
}
|
||||
|
||||
Handle bsm = bsi->bsm();
|
||||
if (bsm.is_null() || !java_lang_invoke_DirectMethodHandle::is_instance(bsm())) {
|
||||
DEBUG_ONLY(
|
||||
tty->print_cr("bsm check failed");
|
||||
tty->print_cr(" bsm.is_null() %d", bsm.is_null());
|
||||
tty->print_cr(" java_lang_invoke_DirectMethodHandle::is_instance(bsm()) %d",
|
||||
java_lang_invoke_DirectMethodHandle::is_instance(bsm()));
|
||||
)
|
||||
return false;
|
||||
}
|
||||
|
||||
oop mn = java_lang_invoke_DirectMethodHandle::member(bsm());
|
||||
Method* method = java_lang_invoke_MemberName::vmtarget(mn);
|
||||
if (method->klass_name()->equals("java/lang/invoke/LambdaMetafactory") &&
|
||||
method->name()->equals("metafactory") &&
|
||||
method->signature()->equals("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;")) {
|
||||
return true;
|
||||
} else {
|
||||
DEBUG_ONLY(
|
||||
ResourceMark rm;
|
||||
tty->print_cr("method check failed");
|
||||
tty->print_cr(" klass_name() %s", method->klass_name()->as_C_string());
|
||||
tty->print_cr(" name() %s", method->name()->as_C_string());
|
||||
tty->print_cr(" signature() %s", method->signature()->as_C_string());
|
||||
)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class EstimateSizeForArchive : StackObj {
|
||||
size_t _shared_class_info_size;
|
||||
int _num_builtin_klasses;
|
||||
|
@ -1894,9 +2009,15 @@ public:
|
|||
CopyLambdaProxyClassInfoToArchive(CompactHashtableWriter* writer)
|
||||
: _writer(writer) {}
|
||||
bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
|
||||
if (SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) {
|
||||
return true;
|
||||
}
|
||||
// In static dump, info._proxy_klasses->at(0) is already relocated to point to the archived class
|
||||
// (not the original class).
|
||||
//
|
||||
// The following check has been moved to SystemDictionaryShared::check_excluded_classes(), which
|
||||
// happens before the classes are copied.
|
||||
//
|
||||
// if (SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) {
|
||||
// return true;
|
||||
//}
|
||||
ResourceMark rm;
|
||||
log_info(cds,dynamic)("Archiving hidden %s", info._proxy_klasses->at(0)->external_name());
|
||||
size_t byte_size = sizeof(RunTimeLambdaProxyClassInfo);
|
||||
|
@ -1904,7 +2025,9 @@ public:
|
|||
(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 = MetaspaceShared::object_delta_u4(DynamicArchive::buffer_to_target(runtime_info));
|
||||
u4 delta = DynamicDumpSharedSpaces ?
|
||||
MetaspaceShared::object_delta_u4((void*)DynamicArchive::buffer_to_target(runtime_info)) :
|
||||
MetaspaceShared::object_delta_u4((void*)runtime_info);
|
||||
_writer->add(hash, delta);
|
||||
return true;
|
||||
}
|
||||
|
@ -1914,16 +2037,13 @@ class AdjustLambdaProxyClassInfo : StackObj {
|
|||
public:
|
||||
AdjustLambdaProxyClassInfo() {}
|
||||
bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
|
||||
if (SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) {
|
||||
return true;
|
||||
}
|
||||
int len = info._proxy_klasses->length();
|
||||
if (len > 1) {
|
||||
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 = DynamicArchive::original_to_buffer(ok0);
|
||||
InstanceKlass* bk1 = DynamicArchive::original_to_buffer(ok1);
|
||||
InstanceKlass* bk0 = DynamicDumpSharedSpaces ? DynamicArchive::original_to_buffer(ok0) : ok0;
|
||||
InstanceKlass* bk1 = DynamicDumpSharedSpaces ? DynamicArchive::original_to_buffer(ok1) : 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);
|
||||
|
@ -1931,7 +2051,11 @@ public:
|
|||
ArchivePtrMarker::mark_pointer(bk0->next_link_addr());
|
||||
}
|
||||
}
|
||||
DynamicArchive::original_to_buffer(info._proxy_klasses->at(0))->set_lambda_proxy_is_available();
|
||||
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();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -2022,13 +2146,21 @@ void SystemDictionaryShared::adjust_lambda_proxy_class_dictionary() {
|
|||
|
||||
void SystemDictionaryShared::serialize_dictionary_headers(SerializeClosure* soc,
|
||||
bool is_static_archive) {
|
||||
FileMapInfo *dynamic_mapinfo = FileMapInfo::dynamic_info();
|
||||
if (is_static_archive) {
|
||||
_builtin_dictionary.serialize_header(soc);
|
||||
_unregistered_dictionary.serialize_header(soc);
|
||||
if (dynamic_mapinfo == NULL || DynamicDumpSharedSpaces || (dynamic_mapinfo != NULL && UseSharedSpaces)) {
|
||||
_lambda_proxy_class_dictionary.serialize_header(soc);
|
||||
}
|
||||
} else {
|
||||
_dynamic_builtin_dictionary.serialize_header(soc);
|
||||
_dynamic_unregistered_dictionary.serialize_header(soc);
|
||||
_lambda_proxy_class_dictionary.serialize_header(soc);
|
||||
if (DynamicDumpSharedSpaces) {
|
||||
_lambda_proxy_class_dictionary.serialize_header(soc);
|
||||
} else {
|
||||
_dynamic_lambda_proxy_class_dictionary.serialize_header(soc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2106,20 +2238,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void SystemDictionaryShared::print_on(const char* prefix,
|
||||
RunTimeSharedDictionary* builtin_dictionary,
|
||||
RunTimeSharedDictionary* unregistered_dictionary,
|
||||
LambdaProxyClassDictionary* lambda_dictionary,
|
||||
outputStream* st) {
|
||||
st->print_cr("%sShared Dictionary", prefix);
|
||||
SharedDictionaryPrinter p(st);
|
||||
builtin_dictionary->iterate(&p);
|
||||
unregistered_dictionary->iterate(&p);
|
||||
if (!lambda_dictionary->empty()) {
|
||||
st->print_cr("%sShared Lambda Dictionary", prefix);
|
||||
SharedLambdaDictionaryPrinter ldp(st);
|
||||
lambda_dictionary->iterate(&ldp);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemDictionaryShared::print_on(outputStream* st) {
|
||||
if (UseSharedSpaces) {
|
||||
st->print_cr("Shared Dictionary");
|
||||
SharedDictionaryPrinter p(st);
|
||||
_builtin_dictionary.iterate(&p);
|
||||
_unregistered_dictionary.iterate(&p);
|
||||
print_on("", &_builtin_dictionary, &_unregistered_dictionary, &_lambda_proxy_class_dictionary, st);
|
||||
if (DynamicArchive::is_mapped()) {
|
||||
_dynamic_builtin_dictionary.iterate(&p);
|
||||
_unregistered_dictionary.iterate(&p);
|
||||
if (!_lambda_proxy_class_dictionary.empty()) {
|
||||
st->print_cr("Shared Lambda Dictionary");
|
||||
SharedLambdaDictionaryPrinter ldp(st);
|
||||
_lambda_proxy_class_dictionary.iterate(&ldp);
|
||||
}
|
||||
print_on("", &_dynamic_builtin_dictionary, &_dynamic_unregistered_dictionary,
|
||||
&_dynamic_lambda_proxy_class_dictionary, st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2128,10 +2268,11 @@ void SystemDictionaryShared::print_table_statistics(outputStream* st) {
|
|||
if (UseSharedSpaces) {
|
||||
_builtin_dictionary.print_table_statistics(st, "Builtin Shared Dictionary");
|
||||
_unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary");
|
||||
_lambda_proxy_class_dictionary.print_table_statistics(st, "Lambda Shared Dictionary");
|
||||
if (DynamicArchive::is_mapped()) {
|
||||
_dynamic_builtin_dictionary.print_table_statistics(st, "Dynamic Builtin Shared Dictionary");
|
||||
_dynamic_unregistered_dictionary.print_table_statistics(st, "Unregistered Shared Dictionary");
|
||||
_lambda_proxy_class_dictionary.print_table_statistics(st, "Lambda Shared Dictionary");
|
||||
_dynamic_lambda_proxy_class_dictionary.print_table_statistics(st, "Dynamic Lambda Shared Dictionary");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2150,6 +2291,7 @@ bool SystemDictionaryShared::empty_dumptime_table() {
|
|||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
class ArchivedMirrorPatcher {
|
||||
protected:
|
||||
static void update(Klass* k) {
|
||||
if (k->has_raw_archived_mirror()) {
|
||||
oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
|
||||
|
@ -2174,11 +2316,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class ArchivedLambdaMirrorPatcher : public ArchivedMirrorPatcher {
|
||||
public:
|
||||
void do_value(const RunTimeLambdaProxyClassInfo* info) {
|
||||
InstanceKlass* ik = info->proxy_klass_head();
|
||||
while (ik != NULL) {
|
||||
update(ik);
|
||||
Klass* k = ik->next_link();
|
||||
ik = (k != NULL) ? InstanceKlass::cast(k) : NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void SystemDictionaryShared::update_archived_mirror_native_pointers_for(RunTimeSharedDictionary* dict) {
|
||||
ArchivedMirrorPatcher patcher;
|
||||
dict->iterate(&patcher);
|
||||
}
|
||||
|
||||
void SystemDictionaryShared::update_archived_mirror_native_pointers_for(LambdaProxyClassDictionary* dict) {
|
||||
ArchivedLambdaMirrorPatcher patcher;
|
||||
dict->iterate(&patcher);
|
||||
}
|
||||
|
||||
void SystemDictionaryShared::update_archived_mirror_native_pointers() {
|
||||
if (!HeapShared::open_archive_heap_region_mapped()) {
|
||||
return;
|
||||
|
@ -2188,6 +2347,7 @@ void SystemDictionaryShared::update_archived_mirror_native_pointers() {
|
|||
}
|
||||
update_archived_mirror_native_pointers_for(&_builtin_dictionary);
|
||||
update_archived_mirror_native_pointers_for(&_unregistered_dictionary);
|
||||
update_archived_mirror_native_pointers_for(&_lambda_proxy_class_dictionary);
|
||||
|
||||
for (int t = T_BOOLEAN; t <= T_LONG; t++) {
|
||||
Klass* k = Universe::typeArrayKlassObj((BasicType)t);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue