mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8145593: Clean up metaspaceShared.cpp
Reviewed-by: jiangli
This commit is contained in:
parent
cc9cd893ac
commit
4e9dd68311
4 changed files with 113 additions and 99 deletions
|
@ -100,6 +100,7 @@ public:
|
||||||
Universe::NARROW_OOP_MODE _narrow_oop_mode; // compressed oop encoding mode
|
Universe::NARROW_OOP_MODE _narrow_oop_mode; // compressed oop encoding mode
|
||||||
int _narrow_klass_shift; // save narrow klass base and shift
|
int _narrow_klass_shift; // save narrow klass base and shift
|
||||||
address _narrow_klass_base;
|
address _narrow_klass_base;
|
||||||
|
char* _misc_data_patching_start;
|
||||||
|
|
||||||
struct space_info {
|
struct space_info {
|
||||||
int _crc; // crc checksum of the current space
|
int _crc; // crc checksum of the current space
|
||||||
|
@ -185,6 +186,8 @@ public:
|
||||||
int narrow_klass_shift() const { return _header->_narrow_klass_shift; }
|
int narrow_klass_shift() const { return _header->_narrow_klass_shift; }
|
||||||
size_t space_capacity(int i) { return _header->_space[i]._capacity; }
|
size_t space_capacity(int i) { return _header->_space[i]._capacity; }
|
||||||
struct FileMapHeader* header() { return _header; }
|
struct FileMapHeader* header() { return _header; }
|
||||||
|
char* misc_data_patching_start() { return _header->_misc_data_patching_start; }
|
||||||
|
void set_misc_data_patching_start(char* p) { _header->_misc_data_patching_start = p; }
|
||||||
|
|
||||||
static FileMapInfo* current_info() {
|
static FileMapInfo* current_info() {
|
||||||
CDS_ONLY(return _current_info;)
|
CDS_ONLY(return _current_info;)
|
||||||
|
|
|
@ -421,7 +421,7 @@ VirtualSpaceNode::VirtualSpaceNode(size_t bytes) : _top(NULL), _next(NULL), _rs(
|
||||||
// Get a mmap region anywhere if the SharedBaseAddress fails.
|
// Get a mmap region anywhere if the SharedBaseAddress fails.
|
||||||
_rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
|
_rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
|
||||||
}
|
}
|
||||||
MetaspaceShared::set_shared_rs(&_rs);
|
MetaspaceShared::initialize_shared_rs(&_rs);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,48 @@ bool MetaspaceShared::_link_classes_made_progress;
|
||||||
bool MetaspaceShared::_check_classes_made_progress;
|
bool MetaspaceShared::_check_classes_made_progress;
|
||||||
bool MetaspaceShared::_has_error_classes;
|
bool MetaspaceShared::_has_error_classes;
|
||||||
bool MetaspaceShared::_archive_loading_failed = false;
|
bool MetaspaceShared::_archive_loading_failed = false;
|
||||||
|
SharedMiscRegion MetaspaceShared::_mc;
|
||||||
|
SharedMiscRegion MetaspaceShared::_md;
|
||||||
|
|
||||||
|
void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size, SharedSpaceType space_type) {
|
||||||
|
_vs.initialize(rs, committed_byte_size);
|
||||||
|
_alloc_top = _vs.low();
|
||||||
|
_space_type = space_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOT thread-safe, but this is called during dump time in single-threaded mode.
|
||||||
|
char* SharedMiscRegion::alloc(size_t num_bytes) {
|
||||||
|
assert(DumpSharedSpaces, "dump time only");
|
||||||
|
size_t alignment = sizeof(char*);
|
||||||
|
num_bytes = align_size_up(num_bytes, alignment);
|
||||||
|
_alloc_top = (char*)align_ptr_up(_alloc_top, alignment);
|
||||||
|
if (_alloc_top + num_bytes > _vs.high()) {
|
||||||
|
report_out_of_shared_space(_space_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* p = _alloc_top;
|
||||||
|
_alloc_top += num_bytes;
|
||||||
|
|
||||||
|
memset(p, 0, num_bytes);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetaspaceShared::initialize_shared_rs(ReservedSpace* rs) {
|
||||||
|
assert(DumpSharedSpaces, "dump time only");
|
||||||
|
_shared_rs = rs;
|
||||||
|
|
||||||
|
// Split up and initialize the misc code and data spaces
|
||||||
|
size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
|
||||||
|
ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size);
|
||||||
|
ReservedSpace misc_section = _shared_rs->last_part(metadata_size);
|
||||||
|
|
||||||
|
// Now split into misc sections.
|
||||||
|
ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize);
|
||||||
|
ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize);
|
||||||
|
_md.initialize(md_rs, SharedMiscDataSize, SharedMiscData);
|
||||||
|
_mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData);
|
||||||
|
}
|
||||||
|
|
||||||
// Read/write a data stream for restoring/preserving metadata pointers and
|
// Read/write a data stream for restoring/preserving metadata pointers and
|
||||||
// miscellaneous data from/to the shared archive file.
|
// miscellaneous data from/to the shared archive file.
|
||||||
|
|
||||||
|
@ -429,64 +471,17 @@ private:
|
||||||
VirtualSpace _mc_vs;
|
VirtualSpace _mc_vs;
|
||||||
CompactHashtableWriter* _string_cht;
|
CompactHashtableWriter* _string_cht;
|
||||||
GrowableArray<MemRegion> *_string_regions;
|
GrowableArray<MemRegion> *_string_regions;
|
||||||
char* _md_alloc_low;
|
|
||||||
char* _md_alloc_top;
|
|
||||||
char* _md_alloc_max;
|
|
||||||
static VM_PopulateDumpSharedSpace* _instance;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
|
VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
|
||||||
GrowableArray<Klass*> *class_promote_order) :
|
GrowableArray<Klass*> *class_promote_order) :
|
||||||
_loader_data(loader_data) {
|
_loader_data(loader_data) {
|
||||||
// Split up and initialize the misc code and data spaces
|
|
||||||
ReservedSpace* shared_rs = MetaspaceShared::shared_rs();
|
|
||||||
size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
|
|
||||||
ReservedSpace shared_ro_rw = shared_rs->first_part(metadata_size);
|
|
||||||
ReservedSpace misc_section = shared_rs->last_part(metadata_size);
|
|
||||||
|
|
||||||
// Now split into misc sections.
|
|
||||||
ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize);
|
|
||||||
ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize);
|
|
||||||
_md_vs.initialize(md_rs, SharedMiscDataSize);
|
|
||||||
_mc_vs.initialize(mc_rs, SharedMiscCodeSize);
|
|
||||||
_class_promote_order = class_promote_order;
|
_class_promote_order = class_promote_order;
|
||||||
|
|
||||||
_md_alloc_low = _md_vs.low();
|
|
||||||
_md_alloc_top = _md_alloc_low + sizeof(char*);
|
|
||||||
_md_alloc_max = _md_vs.low() + SharedMiscDataSize;
|
|
||||||
|
|
||||||
assert(_instance == NULL, "must be singleton");
|
|
||||||
_instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~VM_PopulateDumpSharedSpace() {
|
|
||||||
assert(_instance == this, "must be singleton");
|
|
||||||
_instance = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VM_PopulateDumpSharedSpace* instance() {
|
|
||||||
assert(_instance != NULL, "sanity");
|
|
||||||
return _instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
||||||
void doit(); // outline because gdb sucks
|
void doit(); // outline because gdb sucks
|
||||||
|
|
||||||
char* misc_data_space_alloc(size_t num_bytes) {
|
|
||||||
size_t alignment = sizeof(char*);
|
|
||||||
num_bytes = align_size_up(num_bytes, alignment);
|
|
||||||
_md_alloc_top = (char*)align_ptr_up(_md_alloc_top, alignment);
|
|
||||||
if (_md_alloc_top + num_bytes > _md_alloc_max) {
|
|
||||||
report_out_of_shared_space(SharedMiscData);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* p = _md_alloc_top;
|
|
||||||
_md_alloc_top += num_bytes;
|
|
||||||
|
|
||||||
memset(p, 0, num_bytes);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_misc_data_space_failure(bool success) {
|
void handle_misc_data_space_failure(bool success) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -495,8 +490,6 @@ private:
|
||||||
}
|
}
|
||||||
}; // class VM_PopulateDumpSharedSpace
|
}; // class VM_PopulateDumpSharedSpace
|
||||||
|
|
||||||
VM_PopulateDumpSharedSpace* VM_PopulateDumpSharedSpace::_instance;
|
|
||||||
|
|
||||||
void VM_PopulateDumpSharedSpace::doit() {
|
void VM_PopulateDumpSharedSpace::doit() {
|
||||||
Thread* THREAD = VMThread::vm_thread();
|
Thread* THREAD = VMThread::vm_thread();
|
||||||
NOT_PRODUCT(SystemDictionary::verify();)
|
NOT_PRODUCT(SystemDictionary::verify();)
|
||||||
|
@ -555,17 +548,15 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||||
tty->print_cr("done. ");
|
tty->print_cr("done. ");
|
||||||
|
|
||||||
// Set up the share data and shared code segments.
|
// Set up the share data and shared code segments.
|
||||||
|
_md_vs = *MetaspaceShared::misc_data_region()->virtual_space();
|
||||||
|
_mc_vs = *MetaspaceShared::misc_code_region()->virtual_space();
|
||||||
char* md_low = _md_vs.low();
|
char* md_low = _md_vs.low();
|
||||||
char* md_top = md_low;
|
char* md_top = MetaspaceShared::misc_data_region()->alloc_top();
|
||||||
char* md_end = _md_vs.high();
|
char* md_end = _md_vs.high();
|
||||||
char* mc_low = _mc_vs.low();
|
char* mc_low = _mc_vs.low();
|
||||||
char* mc_top = mc_low;
|
char* mc_top = MetaspaceShared::misc_code_region()->alloc_top();
|
||||||
char* mc_end = _mc_vs.high();
|
char* mc_end = _mc_vs.high();
|
||||||
|
|
||||||
assert(_md_alloc_top != NULL, "sanity");
|
|
||||||
*(char**)_md_alloc_low = _md_alloc_top;
|
|
||||||
md_top = _md_alloc_top;
|
|
||||||
|
|
||||||
// Reserve space for the list of Klass*s whose vtables are used
|
// Reserve space for the list of Klass*s whose vtables are used
|
||||||
// for patching others as needed.
|
// for patching others as needed.
|
||||||
|
|
||||||
|
@ -681,36 +672,32 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||||
|
|
||||||
FileMapInfo* mapinfo = new FileMapInfo();
|
FileMapInfo* mapinfo = new FileMapInfo();
|
||||||
mapinfo->populate_header(MetaspaceShared::max_alignment());
|
mapinfo->populate_header(MetaspaceShared::max_alignment());
|
||||||
|
mapinfo->set_misc_data_patching_start((char*)vtbl_list);
|
||||||
|
|
||||||
// Pass 1 - update file offsets in header.
|
for (int pass=1; pass<=2; pass++) {
|
||||||
mapinfo->write_header();
|
if (pass == 1) {
|
||||||
mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
|
// The first pass doesn't actually write the data to disk. All it
|
||||||
mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
|
// does is to update the fields in the mapinfo->_header.
|
||||||
mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
|
} else {
|
||||||
pointer_delta(md_top, _md_vs.low(), sizeof(char)),
|
// After the first pass, the contents of mapinfo->_header are finalized,
|
||||||
SharedMiscDataSize,
|
// so we can compute the header's CRC, and write the contents of the header
|
||||||
false, false);
|
// and the regions into disk.
|
||||||
mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
|
mapinfo->open_for_write();
|
||||||
pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
|
mapinfo->set_header_crc(mapinfo->compute_header_crc());
|
||||||
SharedMiscCodeSize,
|
}
|
||||||
true, true);
|
mapinfo->write_header();
|
||||||
mapinfo->write_string_regions(_string_regions);
|
mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
|
||||||
|
mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
|
||||||
// Pass 2 - write data.
|
mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
|
||||||
mapinfo->open_for_write();
|
pointer_delta(md_top, _md_vs.low(), sizeof(char)),
|
||||||
mapinfo->set_header_crc(mapinfo->compute_header_crc());
|
SharedMiscDataSize,
|
||||||
mapinfo->write_header();
|
false, false);
|
||||||
mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
|
mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
|
||||||
mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
|
pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
|
||||||
mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
|
SharedMiscCodeSize,
|
||||||
pointer_delta(md_top, _md_vs.low(), sizeof(char)),
|
true, true);
|
||||||
SharedMiscDataSize,
|
mapinfo->write_string_regions(_string_regions);
|
||||||
false, false);
|
}
|
||||||
mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
|
|
||||||
pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
|
|
||||||
SharedMiscCodeSize,
|
|
||||||
true, true);
|
|
||||||
mapinfo->write_string_regions(_string_regions);
|
|
||||||
|
|
||||||
mapinfo->close();
|
mapinfo->close();
|
||||||
|
|
||||||
|
@ -938,11 +925,6 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate misc data blocks during dumping.
|
|
||||||
char* MetaspaceShared::misc_data_space_alloc(size_t num_bytes) {
|
|
||||||
return VM_PopulateDumpSharedSpace::instance()->misc_data_space_alloc(num_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closure for serializing initialization data in from a data area
|
// Closure for serializing initialization data in from a data area
|
||||||
// (ptr_array) read from the shared file.
|
// (ptr_array) read from the shared file.
|
||||||
|
|
||||||
|
@ -1065,10 +1047,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||||
|
|
||||||
void MetaspaceShared::initialize_shared_spaces() {
|
void MetaspaceShared::initialize_shared_spaces() {
|
||||||
FileMapInfo *mapinfo = FileMapInfo::current_info();
|
FileMapInfo *mapinfo = FileMapInfo::current_info();
|
||||||
|
char* buffer = mapinfo->misc_data_patching_start();
|
||||||
char* buffer = mapinfo->header()->region_addr(md);
|
|
||||||
|
|
||||||
buffer = *((char**)buffer); // skip over the md_alloc'ed blocks
|
|
||||||
|
|
||||||
// Skip over (reserve space for) a list of addresses of C++ vtables
|
// Skip over (reserve space for) a list of addresses of C++ vtables
|
||||||
// for Klass objects. They get filled in later.
|
// for Klass objects. They get filled in later.
|
||||||
|
|
|
@ -97,6 +97,26 @@ public:
|
||||||
CompactHashtableStats string;
|
CompactHashtableStats string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SharedMiscRegion VALUE_OBJ_CLASS_SPEC {
|
||||||
|
private:
|
||||||
|
VirtualSpace _vs;
|
||||||
|
char* _alloc_top;
|
||||||
|
SharedSpaceType _space_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void initialize(ReservedSpace rs, size_t committed_byte_size, SharedSpaceType space_type);
|
||||||
|
VirtualSpace* virtual_space() {
|
||||||
|
return &_vs;
|
||||||
|
}
|
||||||
|
char* low() const {
|
||||||
|
return _vs.low();
|
||||||
|
}
|
||||||
|
char* alloc_top() const {
|
||||||
|
return _alloc_top;
|
||||||
|
}
|
||||||
|
char* alloc(size_t num_bytes) NOT_CDS_RETURN_(NULL);
|
||||||
|
};
|
||||||
|
|
||||||
// Class Data Sharing Support
|
// Class Data Sharing Support
|
||||||
class MetaspaceShared : AllStatic {
|
class MetaspaceShared : AllStatic {
|
||||||
|
|
||||||
|
@ -108,6 +128,10 @@ class MetaspaceShared : AllStatic {
|
||||||
static bool _check_classes_made_progress;
|
static bool _check_classes_made_progress;
|
||||||
static bool _has_error_classes;
|
static bool _has_error_classes;
|
||||||
static bool _archive_loading_failed;
|
static bool _archive_loading_failed;
|
||||||
|
|
||||||
|
// Used only during dumping.
|
||||||
|
static SharedMiscRegion _md;
|
||||||
|
static SharedMiscRegion _mc;
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
vtbl_list_size = DEFAULT_VTBL_LIST_SIZE,
|
vtbl_list_size = DEFAULT_VTBL_LIST_SIZE,
|
||||||
|
@ -149,9 +173,7 @@ class MetaspaceShared : AllStatic {
|
||||||
NOT_CDS(return NULL);
|
NOT_CDS(return NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_shared_rs(ReservedSpace* rs) {
|
static void initialize_shared_rs(ReservedSpace* rs) NOT_CDS_RETURN;
|
||||||
CDS_ONLY(_shared_rs = rs;)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_archive_loading_failed() {
|
static void set_archive_loading_failed() {
|
||||||
_archive_loading_failed = true;
|
_archive_loading_failed = true;
|
||||||
|
@ -191,7 +213,17 @@ class MetaspaceShared : AllStatic {
|
||||||
static int count_class(const char* classlist_file);
|
static int count_class(const char* classlist_file);
|
||||||
static void estimate_regions_size() NOT_CDS_RETURN;
|
static void estimate_regions_size() NOT_CDS_RETURN;
|
||||||
|
|
||||||
// Allocate a block of memory from the "md" region.
|
// Allocate a block of memory from the "mc" or "md" regions.
|
||||||
static char* misc_data_space_alloc(size_t num_bytes);
|
static char* misc_code_space_alloc(size_t num_bytes) { return _mc.alloc(num_bytes); }
|
||||||
|
static char* misc_data_space_alloc(size_t num_bytes) { return _md.alloc(num_bytes); }
|
||||||
|
|
||||||
|
static SharedMiscRegion* misc_code_region() {
|
||||||
|
assert(DumpSharedSpaces, "used during dumping only");
|
||||||
|
return &_mc;
|
||||||
|
}
|
||||||
|
static SharedMiscRegion* misc_data_region() {
|
||||||
|
assert(DumpSharedSpaces, "used during dumping only");
|
||||||
|
return &_md;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
|
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue