8145593: Clean up metaspaceShared.cpp

Reviewed-by: jiangli
This commit is contained in:
Ioi Lam 2016-01-04 13:57:34 -08:00
parent cc9cd893ac
commit 4e9dd68311
4 changed files with 113 additions and 99 deletions

View file

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

View file

@ -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
{ {

View file

@ -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.

View file

@ -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