8335583: Avoid using pointers in CDS tables
Reviewed-by: iklam, ccheung
This commit is contained in:
parent
342fe42555
commit
d20ccd1aef
@ -872,6 +872,13 @@ uintx ArchiveBuilder::any_to_offset(address p) const {
|
||||
return buffer_to_offset(p);
|
||||
}
|
||||
|
||||
address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
|
||||
address requested_addr = _requested_static_archive_bottom + offset;
|
||||
address buffered_addr = requested_addr - _buffer_to_requested_delta;
|
||||
assert(is_in_buffer_space(buffered_addr), "bad offset");
|
||||
return buffered_addr;
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
narrowKlass ArchiveBuilder::get_requested_narrow_klass(Klass* k) {
|
||||
assert(CDSConfig::is_dumping_heap(), "sanity");
|
||||
|
@ -321,7 +321,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
static const uintx MAX_SHARED_DELTA = 0x7FFFFFFF;
|
||||
static const uintx MAX_SHARED_DELTA = ArchiveUtils::MAX_SHARED_DELTA;;
|
||||
|
||||
// The address p points to an object inside the output buffer. When the archive is mapped
|
||||
// at the requested address, what's the offset of this object from _requested_static_archive_bottom?
|
||||
@ -331,6 +331,9 @@ public:
|
||||
// inside the output buffer, or (b), an object in the currently mapped static archive.
|
||||
uintx any_to_offset(address p) const;
|
||||
|
||||
// The reverse of buffer_to_offset()
|
||||
address offset_to_buffered_address(u4 offset) const;
|
||||
|
||||
template <typename T>
|
||||
u4 buffer_to_offset_u4(T p) const {
|
||||
uintx offset = buffer_to_offset((address)p);
|
||||
@ -343,6 +346,11 @@ public:
|
||||
return to_offset_u4(offset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T offset_to_buffered(u4 offset) const {
|
||||
return (T)offset_to_buffered_address(offset);
|
||||
}
|
||||
|
||||
public:
|
||||
ArchiveBuilder();
|
||||
~ArchiveBuilder();
|
||||
|
@ -25,8 +25,10 @@
|
||||
#ifndef SHARE_CDS_ARCHIVEUTILS_HPP
|
||||
#define SHARE_CDS_ARCHIVEUTILS_HPP
|
||||
|
||||
#include "cds/cds_globals.hpp"
|
||||
#include "cds/serializeClosure.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/virtualspace.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
@ -247,7 +249,27 @@ public:
|
||||
|
||||
class ArchiveUtils {
|
||||
public:
|
||||
static const uintx MAX_SHARED_DELTA = 0x7FFFFFFF;
|
||||
static void log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) NOT_CDS_RETURN;
|
||||
|
||||
// offset must represent an object of type T in the mapped shared space. Return
|
||||
// a direct pointer to this object.
|
||||
template <typename T> T static from_offset(u4 offset) {
|
||||
T p = (T)(SharedBaseAddress + offset);
|
||||
assert(Metaspace::is_in_shared_metaspace(p), "must be");
|
||||
return p;
|
||||
}
|
||||
|
||||
// p must be an archived object. Get its offset from SharedBaseAddress
|
||||
template <typename T> static u4 to_offset(T p) {
|
||||
uintx pn = (uintx)p;
|
||||
uintx base = (uintx)SharedBaseAddress;
|
||||
assert(Metaspace::is_in_shared_metaspace(p), "must be");
|
||||
assert(pn > base, "sanity"); // No valid object is stored at 0 offset from SharedBaseAddress
|
||||
uintx offset = pn - base;
|
||||
assert(offset <= MAX_SHARED_DELTA, "range check");
|
||||
return static_cast<u4>(offset);
|
||||
}
|
||||
};
|
||||
|
||||
class HeapRootSegments {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2024, 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
|
||||
@ -51,7 +51,7 @@
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
|
||||
GrowableArrayCHeap<char*, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr;
|
||||
Array<Array<char>*>* LambdaFormInvokers::_static_archive_invokers = nullptr;
|
||||
Array<u4>* LambdaFormInvokers::_static_archive_invokers = nullptr;
|
||||
|
||||
#define NUM_FILTER 4
|
||||
static const char* filter[NUM_FILTER] = {"java.lang.invoke.Invokers$Holder",
|
||||
@ -216,7 +216,7 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
_static_archive_invokers = ArchiveBuilder::new_ro_array<Array<char>*>(count);
|
||||
_static_archive_invokers = ArchiveBuilder::new_ro_array<u4>(count);
|
||||
int index = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
char* str = _lambdaform_lines->at(i);
|
||||
@ -225,8 +225,7 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
|
||||
Array<char>* line = ArchiveBuilder::new_ro_array<char>((int)str_len);
|
||||
strncpy(line->adr_at(0), str, str_len);
|
||||
|
||||
_static_archive_invokers->at_put(index, line);
|
||||
ArchivePtrMarker::mark_pointer(_static_archive_invokers->adr_at(index));
|
||||
_static_archive_invokers->at_put(index, ArchiveBuilder::current()->any_to_offset_u4(line));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
@ -239,7 +238,8 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
|
||||
void LambdaFormInvokers::read_static_archive_invokers() {
|
||||
if (_static_archive_invokers != nullptr) {
|
||||
for (int i = 0; i < _static_archive_invokers->length(); i++) {
|
||||
Array<char>* line = _static_archive_invokers->at(i);
|
||||
u4 offset = _static_archive_invokers->at(i);
|
||||
Array<char>* line = ArchiveUtils::from_offset<Array<char>*>(offset);
|
||||
char* str = line->adr_at(0);
|
||||
append(str);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class LambdaFormInvokers : public AllStatic {
|
||||
private:
|
||||
static GrowableArrayCHeap<char*, mtClassShared>* _lambdaform_lines;
|
||||
// For storing LF form lines (LF_RESOLVE only) in read only table.
|
||||
static Array<Array<char>*>* _static_archive_invokers;
|
||||
static Array<u4>* _static_archive_invokers;
|
||||
static void regenerate_class(char* name, ClassFileStream& st, TRAPS);
|
||||
public:
|
||||
static void append(char* line);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, 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
|
||||
@ -34,17 +34,6 @@ DumpTimeLambdaProxyClassInfo::~DumpTimeLambdaProxyClassInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
void LambdaProxyClassKey::init_for_archive(LambdaProxyClassKey& dumptime_key) {
|
||||
ArchiveBuilder* b = ArchiveBuilder::current();
|
||||
|
||||
b->write_pointer_in_buffer(&_caller_ik, dumptime_key._caller_ik);
|
||||
b->write_pointer_in_buffer(&_instantiated_method_type, dumptime_key._instantiated_method_type);
|
||||
b->write_pointer_in_buffer(&_invoked_name, dumptime_key._invoked_name);
|
||||
b->write_pointer_in_buffer(&_invoked_type, dumptime_key._invoked_type);
|
||||
b->write_pointer_in_buffer(&_member_method, dumptime_key._member_method);
|
||||
b->write_pointer_in_buffer(&_method_type, dumptime_key._method_type);
|
||||
}
|
||||
|
||||
unsigned int LambdaProxyClassKey::hash() const {
|
||||
return SystemDictionaryShared::hash_for_shared_dictionary((address)_caller_ik) +
|
||||
SystemDictionaryShared::hash_for_shared_dictionary((address)_invoked_name) +
|
||||
@ -53,6 +42,14 @@ unsigned int LambdaProxyClassKey::hash() const {
|
||||
SystemDictionaryShared::hash_for_shared_dictionary((address)_instantiated_method_type);
|
||||
}
|
||||
|
||||
unsigned int RunTimeLambdaProxyClassKey::hash() const {
|
||||
return primitive_hash<u4>(_caller_ik) +
|
||||
primitive_hash<u4>(_invoked_name) +
|
||||
primitive_hash<u4>(_invoked_type) +
|
||||
primitive_hash<u4>(_method_type) +
|
||||
primitive_hash<u4>(_instantiated_method_type);
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void LambdaProxyClassKey::print_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
@ -65,13 +62,24 @@ void LambdaProxyClassKey::print_on(outputStream* st) const {
|
||||
st->print_cr("_method_type : %s", _method_type->as_C_string());
|
||||
}
|
||||
|
||||
void RunTimeLambdaProxyClassKey::print_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
st->print_cr("LambdaProxyClassKey : " INTPTR_FORMAT " hash: %0x08x", p2i(this), hash());
|
||||
st->print_cr("_caller_ik : %d", _caller_ik);
|
||||
st->print_cr("_instantiated_method_type : %d", _instantiated_method_type);
|
||||
st->print_cr("_invoked_name : %d", _invoked_name);
|
||||
st->print_cr("_invoked_type : %d", _invoked_type);
|
||||
st->print_cr("_member_method : %d", _member_method);
|
||||
st->print_cr("_method_type : %d", _method_type);
|
||||
}
|
||||
|
||||
void RunTimeLambdaProxyClassInfo::print_on(outputStream* st) const {
|
||||
_key.print_on(st);
|
||||
}
|
||||
#endif
|
||||
|
||||
void RunTimeLambdaProxyClassInfo::init(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
|
||||
_key.init_for_archive(key);
|
||||
_key = RunTimeLambdaProxyClassKey::init_for_dumptime(key);
|
||||
ArchiveBuilder::current()->write_pointer_in_buffer(&_proxy_klass_head,
|
||||
info._proxy_klasses->at(0));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, 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
|
||||
@ -101,9 +101,80 @@ public:
|
||||
return (k1.equals(k2));
|
||||
}
|
||||
|
||||
InstanceKlass* caller_ik() const { return _caller_ik; }
|
||||
InstanceKlass* caller_ik() const { return _caller_ik; }
|
||||
Symbol* invoked_name() const { return _invoked_name; }
|
||||
Symbol* invoked_type() const { return _invoked_type; }
|
||||
Symbol* method_type() const { return _method_type; }
|
||||
Method* member_method() const { return _member_method; }
|
||||
Symbol* instantiated_method_type() const { return _instantiated_method_type; }
|
||||
|
||||
void init_for_archive(LambdaProxyClassKey& dumptime_key);
|
||||
#ifndef PRODUCT
|
||||
void print_on(outputStream* st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class RunTimeLambdaProxyClassKey {
|
||||
u4 _caller_ik;
|
||||
u4 _invoked_name;
|
||||
u4 _invoked_type;
|
||||
u4 _method_type;
|
||||
u4 _member_method;
|
||||
u4 _instantiated_method_type;
|
||||
|
||||
RunTimeLambdaProxyClassKey(u4 caller_ik,
|
||||
u4 invoked_name,
|
||||
u4 invoked_type,
|
||||
u4 method_type,
|
||||
u4 member_method,
|
||||
u4 instantiated_method_type) :
|
||||
_caller_ik(caller_ik),
|
||||
_invoked_name(invoked_name),
|
||||
_invoked_type(invoked_type),
|
||||
_method_type(method_type),
|
||||
_member_method(member_method),
|
||||
_instantiated_method_type(instantiated_method_type) {}
|
||||
|
||||
public:
|
||||
static RunTimeLambdaProxyClassKey init_for_dumptime(LambdaProxyClassKey& key) {
|
||||
assert(ArchiveBuilder::is_active(), "sanity");
|
||||
ArchiveBuilder* b = ArchiveBuilder::current();
|
||||
|
||||
u4 caller_ik = b->any_to_offset_u4(key.caller_ik());
|
||||
u4 invoked_name = b->any_to_offset_u4(key.invoked_name());
|
||||
u4 invoked_type = b->any_to_offset_u4(key.invoked_type());
|
||||
u4 method_type = b->any_to_offset_u4(key.method_type());
|
||||
u4 member_method = b->any_to_offset_u4(key.member_method());
|
||||
u4 instantiated_method_type = b->any_to_offset_u4(key.instantiated_method_type());
|
||||
|
||||
return RunTimeLambdaProxyClassKey(caller_ik, invoked_name, invoked_type, method_type,
|
||||
member_method, instantiated_method_type);
|
||||
}
|
||||
|
||||
static RunTimeLambdaProxyClassKey init_for_runtime(InstanceKlass* caller_ik,
|
||||
Symbol* invoked_name,
|
||||
Symbol* invoked_type,
|
||||
Symbol* method_type,
|
||||
Method* member_method,
|
||||
Symbol* instantiated_method_type) {
|
||||
// All parameters must be in shared space, or else you'd get an assert in
|
||||
// ArchiveUtils::to_offset().
|
||||
return RunTimeLambdaProxyClassKey(ArchiveUtils::to_offset(caller_ik),
|
||||
ArchiveUtils::to_offset(invoked_name),
|
||||
ArchiveUtils::to_offset(invoked_type),
|
||||
ArchiveUtils::to_offset(method_type),
|
||||
ArchiveUtils::to_offset(member_method),
|
||||
ArchiveUtils::to_offset(instantiated_method_type));
|
||||
}
|
||||
|
||||
unsigned int hash() const;
|
||||
bool equals(RunTimeLambdaProxyClassKey const& other) const {
|
||||
return _caller_ik == other._caller_ik &&
|
||||
_invoked_name == other._invoked_name &&
|
||||
_invoked_type == other._invoked_type &&
|
||||
_method_type == other._method_type &&
|
||||
_member_method == other._member_method &&
|
||||
_instantiated_method_type == other._instantiated_method_type;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void print_on(outputStream* st) const;
|
||||
@ -133,17 +204,17 @@ public:
|
||||
};
|
||||
|
||||
class RunTimeLambdaProxyClassInfo {
|
||||
LambdaProxyClassKey _key;
|
||||
RunTimeLambdaProxyClassKey _key;
|
||||
InstanceKlass* _proxy_klass_head;
|
||||
public:
|
||||
RunTimeLambdaProxyClassInfo(LambdaProxyClassKey key, InstanceKlass* proxy_klass_head) :
|
||||
RunTimeLambdaProxyClassInfo(RunTimeLambdaProxyClassKey key, InstanceKlass* proxy_klass_head) :
|
||||
_key(key), _proxy_klass_head(proxy_klass_head) {}
|
||||
|
||||
InstanceKlass* proxy_klass_head() const { return _proxy_klass_head; }
|
||||
|
||||
// Used by LambdaProxyClassDictionary to implement OffsetCompactHashtable::EQUALS
|
||||
static inline bool EQUALS(
|
||||
const RunTimeLambdaProxyClassInfo* value, LambdaProxyClassKey* key, int len_unused) {
|
||||
const RunTimeLambdaProxyClassInfo* value, RunTimeLambdaProxyClassKey* key, int len_unused) {
|
||||
return (value->_key.equals(*key));
|
||||
}
|
||||
void init(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info);
|
||||
@ -151,7 +222,7 @@ public:
|
||||
unsigned int hash() const {
|
||||
return _key.hash();
|
||||
}
|
||||
LambdaProxyClassKey key() const {
|
||||
RunTimeLambdaProxyClassKey key() const {
|
||||
return _key;
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
@ -173,7 +244,7 @@ public:
|
||||
};
|
||||
|
||||
class LambdaProxyClassDictionary : public OffsetCompactHashtable<
|
||||
LambdaProxyClassKey*,
|
||||
RunTimeLambdaProxyClassKey*,
|
||||
const RunTimeLambdaProxyClassInfo*,
|
||||
RunTimeLambdaProxyClassInfo::EQUALS> {};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, 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
|
||||
@ -30,9 +30,10 @@
|
||||
|
||||
void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
|
||||
ArchiveBuilder* builder = ArchiveBuilder::current();
|
||||
builder->write_pointer_in_buffer(&_klass, info._klass);
|
||||
InstanceKlass* k = info._klass;
|
||||
_klass_offset = builder->any_to_offset_u4(k);
|
||||
|
||||
if (!SystemDictionaryShared::is_builtin(_klass)) {
|
||||
if (!SystemDictionaryShared::is_builtin(k)) {
|
||||
CrcInfo* c = crc();
|
||||
c->_clsfile_size = info._clsfile_size;
|
||||
c->_clsfile_crc32 = info._clsfile_crc32;
|
||||
@ -61,10 +62,10 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
|
||||
}
|
||||
}
|
||||
|
||||
if (_klass->is_hidden()) {
|
||||
builder->write_pointer_in_buffer(nest_host_addr(), info.nest_host());
|
||||
if (k->is_hidden()) {
|
||||
_nest_host_offset = builder->any_to_offset_u4(info.nest_host());
|
||||
}
|
||||
if (_klass->has_archived_enum_objs()) {
|
||||
if (k->has_archived_enum_objs()) {
|
||||
int num = info.num_enum_klass_static_fields();
|
||||
set_num_enum_klass_static_fields(num);
|
||||
for (int i = 0; i < num; i++) {
|
||||
@ -74,6 +75,14 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
|
||||
}
|
||||
}
|
||||
|
||||
InstanceKlass* RunTimeClassInfo::klass() const {
|
||||
if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space((address)this)) {
|
||||
return ArchiveBuilder::current()->offset_to_buffered<InstanceKlass*>(_klass_offset);
|
||||
} else {
|
||||
return ArchiveUtils::from_offset<InstanceKlass*>(_klass_offset);
|
||||
}
|
||||
}
|
||||
|
||||
size_t RunTimeClassInfo::crc_size(InstanceKlass* klass) {
|
||||
if (!SystemDictionaryShared::is_builtin(klass)) {
|
||||
return sizeof(CrcInfo);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2024, 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
|
||||
@ -52,24 +52,24 @@ public:
|
||||
struct RTVerifierConstraint {
|
||||
u4 _name;
|
||||
u4 _from_name;
|
||||
Symbol* name() { return (Symbol*)(SharedBaseAddress + _name);}
|
||||
Symbol* from_name() { return (Symbol*)(SharedBaseAddress + _from_name); }
|
||||
Symbol* name() { return ArchiveUtils::from_offset<Symbol*>(_name); }
|
||||
Symbol* from_name() { return ArchiveUtils::from_offset<Symbol*>(_from_name); }
|
||||
};
|
||||
|
||||
struct RTLoaderConstraint {
|
||||
u4 _name;
|
||||
char _loader_type1;
|
||||
char _loader_type2;
|
||||
Symbol* constraint_name() {
|
||||
return (Symbol*)(SharedBaseAddress + _name);
|
||||
}
|
||||
Symbol* constraint_name() { return ArchiveUtils::from_offset<Symbol*>(_name); }
|
||||
};
|
||||
struct RTEnumKlassStaticFields {
|
||||
int _num;
|
||||
int _root_indices[1];
|
||||
};
|
||||
|
||||
InstanceKlass* _klass;
|
||||
private:
|
||||
u4 _klass_offset;
|
||||
u4 _nest_host_offset;
|
||||
int _num_verifier_constraints;
|
||||
int _num_loader_constraints;
|
||||
|
||||
@ -80,7 +80,6 @@ public:
|
||||
// optional char _verifier_constraint_flags[_num_verifier_constraints]
|
||||
// optional RTEnumKlassStaticFields _enum_klass_static_fields;
|
||||
|
||||
private:
|
||||
static size_t header_size_size() {
|
||||
return align_up(sizeof(RunTimeClassInfo), wordSize);
|
||||
}
|
||||
@ -108,6 +107,9 @@ private:
|
||||
|
||||
static size_t crc_size(InstanceKlass* klass);
|
||||
public:
|
||||
InstanceKlass* klass() const;
|
||||
int num_verifier_constraints() const { return _num_verifier_constraints; }
|
||||
int num_loader_constraints() const { return _num_loader_constraints; }
|
||||
static size_t byte_size(InstanceKlass* klass, int num_verifier_constraints, int num_loader_constraints,
|
||||
int num_enum_klass_static_fields) {
|
||||
return header_size_size() +
|
||||
@ -125,11 +127,11 @@ private:
|
||||
}
|
||||
|
||||
size_t nest_host_offset() const {
|
||||
return crc_offset() + crc_size(_klass);
|
||||
return crc_offset() + crc_size(klass());
|
||||
}
|
||||
|
||||
size_t loader_constraints_offset() const {
|
||||
return nest_host_offset() + nest_host_size(_klass);
|
||||
return nest_host_offset() + nest_host_size(klass());
|
||||
}
|
||||
size_t verifier_constraints_offset() const {
|
||||
return loader_constraints_offset() + loader_constraints_size(_num_loader_constraints);
|
||||
@ -150,13 +152,13 @@ private:
|
||||
}
|
||||
|
||||
RTEnumKlassStaticFields* enum_klass_static_fields_addr() const {
|
||||
assert(_klass->has_archived_enum_objs(), "sanity");
|
||||
assert(klass()->has_archived_enum_objs(), "sanity");
|
||||
return (RTEnumKlassStaticFields*)(address(this) + enum_klass_static_fields_offset());
|
||||
}
|
||||
|
||||
public:
|
||||
CrcInfo* crc() const {
|
||||
assert(crc_size(_klass) > 0, "must be");
|
||||
assert(crc_size(klass()) > 0, "must be");
|
||||
return (CrcInfo*)(address(this) + crc_offset());
|
||||
}
|
||||
RTVerifierConstraint* verifier_constraints() {
|
||||
@ -173,12 +175,9 @@ public:
|
||||
return (char*)(address(this) + verifier_constraint_flags_offset());
|
||||
}
|
||||
|
||||
InstanceKlass** nest_host_addr() {
|
||||
assert(_klass->is_hidden(), "sanity");
|
||||
return (InstanceKlass**)(address(this) + nest_host_offset());
|
||||
}
|
||||
InstanceKlass* nest_host() {
|
||||
return *nest_host_addr();
|
||||
assert(!ArchiveBuilder::is_active(), "not called when dumping archive");
|
||||
return ArchiveUtils::from_offset<InstanceKlass*>(_nest_host_offset);
|
||||
}
|
||||
|
||||
RTLoaderConstraint* loader_constraints() {
|
||||
@ -248,7 +247,7 @@ public:
|
||||
// Used by RunTimeSharedDictionary to implement OffsetCompactHashtable::EQUALS
|
||||
static inline bool EQUALS(
|
||||
const RunTimeClassInfo* value, Symbol* key, int len_unused) {
|
||||
return (value->_klass->name() == key);
|
||||
return (value->klass()->name() == key);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -134,7 +134,7 @@ InstanceKlass* SystemDictionaryShared::lookup_from_stream(Symbol* class_name,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return acquire_class_for_current_thread(record->_klass, class_loader,
|
||||
return acquire_class_for_current_thread(record->klass(), class_loader,
|
||||
protection_domain, cfs,
|
||||
THREAD);
|
||||
}
|
||||
@ -789,9 +789,20 @@ InstanceKlass* SystemDictionaryShared::get_shared_lambda_proxy_class(InstanceKla
|
||||
Symbol* method_type,
|
||||
Method* member_method,
|
||||
Symbol* instantiated_method_type) {
|
||||
if (!caller_ik->is_shared() ||
|
||||
!invoked_name->is_shared() ||
|
||||
!invoked_type->is_shared() ||
|
||||
!method_type->is_shared() ||
|
||||
!member_method->is_shared() ||
|
||||
!instantiated_method_type->is_shared()) {
|
||||
// These can't be represented as u4 offset, but we wouldn't have archived a lambda proxy in this case anyway.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MutexLocker ml(CDSLambda_lock, Mutex::_no_safepoint_check_flag);
|
||||
LambdaProxyClassKey key(caller_ik, invoked_name, invoked_type,
|
||||
method_type, member_method, instantiated_method_type);
|
||||
RunTimeLambdaProxyClassKey key =
|
||||
RunTimeLambdaProxyClassKey::init_for_runtime(caller_ik, invoked_name, invoked_type,
|
||||
method_type, member_method, instantiated_method_type);
|
||||
|
||||
// Try to retrieve the lambda proxy class from static archive.
|
||||
const RunTimeLambdaProxyClassInfo* info = _static_archive.lookup_lambda_proxy_class(&key);
|
||||
@ -899,7 +910,7 @@ void SystemDictionaryShared::check_verification_constraints(InstanceKlass* klass
|
||||
assert(!CDSConfig::is_dumping_static_archive() && CDSConfig::is_using_archive(), "called at run time with CDS enabled only");
|
||||
RunTimeClassInfo* record = RunTimeClassInfo::get_for(klass);
|
||||
|
||||
int length = record->_num_verifier_constraints;
|
||||
int length = record->num_verifier_constraints();
|
||||
if (length > 0) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
RunTimeClassInfo::RTVerifierConstraint* vc = record->verifier_constraint_at(i);
|
||||
@ -1015,9 +1026,9 @@ bool SystemDictionaryShared::check_linking_constraints(Thread* current, Instance
|
||||
if (klass->is_shared_platform_class() || klass->is_shared_app_class()) {
|
||||
RunTimeClassInfo* info = RunTimeClassInfo::get_for(klass);
|
||||
assert(info != nullptr, "Sanity");
|
||||
if (info->_num_loader_constraints > 0) {
|
||||
if (info->num_loader_constraints() > 0) {
|
||||
HandleMark hm(current);
|
||||
for (int i = 0; i < info->_num_loader_constraints; i++) {
|
||||
for (int i = 0; i < info->num_loader_constraints(); i++) {
|
||||
RunTimeClassInfo::RTLoaderConstraint* lc = info->loader_constraint_at(i);
|
||||
Symbol* name = lc->constraint_name();
|
||||
Handle loader1(current, get_class_loader_by(lc->_loader_type1));
|
||||
@ -1333,14 +1344,14 @@ InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) {
|
||||
&_dynamic_archive._builtin_dictionary,
|
||||
name);
|
||||
if (record != nullptr) {
|
||||
assert(!record->_klass->is_hidden(), "hidden class cannot be looked up by name");
|
||||
assert(check_alignment(record->_klass), "Address not aligned");
|
||||
assert(!record->klass()->is_hidden(), "hidden class cannot be looked up by name");
|
||||
assert(check_alignment(record->klass()), "Address not aligned");
|
||||
// We did not save the classfile data of the generated LambdaForm invoker classes,
|
||||
// so we cannot support CLFH for such classes.
|
||||
if (record->_klass->is_generated_shared_class() && JvmtiExport::should_post_class_file_load_hook()) {
|
||||
if (record->klass()->is_generated_shared_class() && JvmtiExport::should_post_class_file_load_hook()) {
|
||||
return nullptr;
|
||||
}
|
||||
return record->_klass;
|
||||
return record->klass();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1378,10 +1389,10 @@ public:
|
||||
|
||||
void do_value(const RunTimeClassInfo* record) {
|
||||
ResourceMark rm;
|
||||
_st->print_cr("%4d: %s %s", _index++, record->_klass->external_name(),
|
||||
class_loader_name_for_shared(record->_klass));
|
||||
if (record->_klass->array_klasses() != nullptr) {
|
||||
record->_klass->array_klasses()->cds_print_value_on(_st);
|
||||
_st->print_cr("%4d: %s %s", _index++, record->klass()->external_name(),
|
||||
class_loader_name_for_shared(record->klass()));
|
||||
if (record->klass()->array_klasses() != nullptr) {
|
||||
record->klass()->array_klasses()->cds_print_value_on(_st);
|
||||
_st->cr();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2024, 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
|
||||
@ -145,7 +145,7 @@ class SystemDictionaryShared: public SystemDictionary {
|
||||
RunTimeSharedDictionary _unregistered_dictionary;
|
||||
LambdaProxyClassDictionary _lambda_proxy_class_dictionary;
|
||||
|
||||
const RunTimeLambdaProxyClassInfo* lookup_lambda_proxy_class(LambdaProxyClassKey* key) {
|
||||
const RunTimeLambdaProxyClassInfo* lookup_lambda_proxy_class(RunTimeLambdaProxyClassKey* key) {
|
||||
return _lambda_proxy_class_dictionary.lookup(key, key->hash(), 0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user