< prev index next >
src/share/vm/memory/metaspaceShared.cpp
Print this page
*** 420,429 ****
--- 420,431 ----
private:
ClassLoaderData* _loader_data;
GrowableArray<Klass*> *_class_promote_order;
VirtualSpace _md_vs;
VirtualSpace _mc_vs;
+ CompactHashtableWriter* _string_cht;
+ GrowableArray<MemRegion> *_string_regions;
public:
VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
GrowableArray<Klass*> *class_promote_order) :
_loader_data(loader_data) {
*** 538,555 ****
SystemDictionary::reorder_dictionary();
NOT_PRODUCT(SystemDictionary::verify();)
! // Copy the the symbol table, and the system dictionary to the shared
// space in usable form. Copy the hashtable
// buckets first [read-write], then copy the linked lists of entries
// [read-only].
NOT_PRODUCT(SymbolTable::verify());
handle_misc_data_space_failure(SymbolTable::copy_compact_table(&md_top, md_end));
SystemDictionary::reverse();
SystemDictionary::copy_buckets(&md_top, md_end);
ClassLoader::verify();
ClassLoader::copy_package_info_buckets(&md_top, md_end);
--- 540,566 ----
SystemDictionary::reorder_dictionary();
NOT_PRODUCT(SystemDictionary::verify();)
! // Copy the the symbol table, string table, and the system dictionary to the shared
// space in usable form. Copy the hashtable
// buckets first [read-write], then copy the linked lists of entries
// [read-only].
NOT_PRODUCT(SymbolTable::verify());
handle_misc_data_space_failure(SymbolTable::copy_compact_table(&md_top, md_end));
+ size_t ss_bytes = 0;
+ char* ss_low;
+ // The string space has maximum two regions. See FileMapInfo::write_string_regions() for details.
+ _string_regions = new GrowableArray<MemRegion>(2);
+ NOT_PRODUCT(StringTable::verify());
+ handle_misc_data_space_failure(StringTable::copy_compact_table(&md_top, md_end, _string_regions,
+ &ss_bytes));
+ ss_low = _string_regions->is_empty() ? NULL : (char*)_string_regions->first().start();
+
SystemDictionary::reverse();
SystemDictionary::copy_buckets(&md_top, md_end);
ClassLoader::verify();
ClassLoader::copy_package_info_buckets(&md_top, md_end);
*** 574,597 ****
// Allocated size of each space (may not be all occupied)
const size_t ro_alloced = ro_space->capacity_bytes_slow(Metaspace::NonClassType);
const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
const size_t md_alloced = md_end-md_low;
const size_t mc_alloced = mc_end-mc_low;
! const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced;
// Occupied size of each space.
const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
const size_t md_bytes = size_t(md_top - md_low);
const size_t mc_bytes = size_t(mc_top - mc_low);
// Percent of total size
! const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes;
const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
// Percent of fullness of each space
const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
--- 585,610 ----
// Allocated size of each space (may not be all occupied)
const size_t ro_alloced = ro_space->capacity_bytes_slow(Metaspace::NonClassType);
const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
const size_t md_alloced = md_end-md_low;
const size_t mc_alloced = mc_end-mc_low;
! const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced
! + ss_bytes;
// Occupied size of each space.
const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
const size_t md_bytes = size_t(md_top - md_low);
const size_t mc_bytes = size_t(mc_top - mc_low);
// Percent of total size
! const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes;
const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
+ const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0;
// Percent of fullness of each space
const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
*** 600,609 ****
--- 613,623 ----
tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom());
tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom());
tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low);
tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low);
+ tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes, 100.0, ss_low);
tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]",
total_bytes, total_alloced, total_u_perc);
// Update the vtable pointers in all of the Klass objects in the
// heap. They should point to newly generated vtable.
*** 629,638 ****
--- 643,653 ----
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);
// Pass 2 - write data.
mapinfo->open_for_write();
mapinfo->set_header_crc(mapinfo->compute_header_crc());
mapinfo->write_header();
*** 644,653 ****
--- 659,670 ----
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();
memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
os::free(saved_vtbl);
*** 940,949 ****
--- 957,971 ----
// Return true if given address is in the mapped shared space.
bool MetaspaceShared::is_in_shared_space(const void* p) {
return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
}
+ bool MetaspaceShared::is_string_region(int idx) {
+ return (idx >= MetaspaceShared::first_string &&
+ idx < MetaspaceShared::first_string + MetaspaceShared::max_strings);
+ }
+
void MetaspaceShared::print_shared_spaces() {
if (UseSharedSpaces) {
FileMapInfo::current_info()->print_shared_spaces();
}
}
*** 977,986 ****
--- 999,1010 ----
mapinfo->verify_region_checksum(rw) &&
(_md_base = mapinfo->map_region(md)) != NULL &&
mapinfo->verify_region_checksum(md) &&
(_mc_base = mapinfo->map_region(mc)) != NULL &&
mapinfo->verify_region_checksum(mc) &&
+ mapinfo->map_string_regions() &&
+ mapinfo->verify_string_regions() &&
(image_alignment == (size_t)max_alignment()) &&
mapinfo->validate_classpath_entry_table()) {
// Success (no need to do anything)
return true;
} else {
*** 988,997 ****
--- 1012,1022 ----
// that succeeded
if (_ro_base != NULL) mapinfo->unmap_region(ro);
if (_rw_base != NULL) mapinfo->unmap_region(rw);
if (_md_base != NULL) mapinfo->unmap_region(md);
if (_mc_base != NULL) mapinfo->unmap_region(mc);
+ mapinfo->unmap_string_regions();
#ifndef _WINDOWS
// Release the entire mapped region
shared_rs.release();
#endif
// If -Xshare:on is specified, print out the error message and exit VM,
*** 1009,1019 ****
// serialize it out to its various destinations.
void MetaspaceShared::initialize_shared_spaces() {
FileMapInfo *mapinfo = FileMapInfo::current_info();
! char* buffer = mapinfo->region_base(md);
// Skip over (reserve space for) a list of addresses of C++ vtables
// for Klass objects. They get filled in later.
void** vtbl_list = (void**)buffer;
--- 1034,1044 ----
// serialize it out to its various destinations.
void MetaspaceShared::initialize_shared_spaces() {
FileMapInfo *mapinfo = FileMapInfo::current_info();
! char* buffer = mapinfo->header()->region_addr(md);
// Skip over (reserve space for) a list of addresses of C++ vtables
// for Klass objects. They get filled in later.
void** vtbl_list = (void**)buffer;
*** 1025,1041 ****
intptr_t vtable_size = *(intptr_t*)buffer;
buffer += sizeof(intptr_t);
buffer += vtable_size;
! // Create the shared symbol table using the bucket array at this spot in the
// misc data space. (Todo: move this to read-only space. Currently
// this is mapped copy-on-write but will never be written into).
buffer = (char*)SymbolTable::init_shared_table(buffer);
SymbolTable::create_table();
// Create the shared dictionary using the bucket array at this spot in
// the misc data space. Since the shared dictionary table is never
// modified, this region (of mapped pages) will be (effectively, if
// not explicitly) read-only.
--- 1050,1069 ----
intptr_t vtable_size = *(intptr_t*)buffer;
buffer += sizeof(intptr_t);
buffer += vtable_size;
! // Create the shared symbol table using the compact table at this spot in the
// misc data space. (Todo: move this to read-only space. Currently
// this is mapped copy-on-write but will never be written into).
buffer = (char*)SymbolTable::init_shared_table(buffer);
SymbolTable::create_table();
+ // Create the shared string table using the compact table
+ buffer = (char*)StringTable::init_shared_table(mapinfo, buffer);
+
// Create the shared dictionary using the bucket array at this spot in
// the misc data space. Since the shared dictionary table is never
// modified, this region (of mapped pages) will be (effectively, if
// not explicitly) read-only.
*** 1098,1107 ****
--- 1126,1140 ----
vm_exit(0);
}
}
}
+ void MetaspaceShared::fixup_shared_string_regions() {
+ FileMapInfo *mapinfo = FileMapInfo::current_info();
+ mapinfo->fixup_string_regions();
+ }
+
// JVM/TI RedefineClasses() support:
bool MetaspaceShared::remap_shared_readonly_as_readwrite() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
if (UseSharedSpaces) {
< prev index next >