Skip to content
Permalink
Browse files

8236236: Eliminate CDS md region and consolidate c++ vtable patching …

…code

Reviewed-by: ccheung
  • Loading branch information
iklam committed Jan 22, 2020
1 parent ac7f36c commit d5bdb76e8456fa250c308f7ac8d4366900062273
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, 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
@@ -33,7 +33,7 @@
//
// Also, this is a C header file. Do not use C++ here.

#define NUM_CDS_REGIONS 9 // this must be the same as MetaspaceShared::n_regions
#define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions
#define CDS_ARCHIVE_MAGIC 0xf00baba2
#define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
#define CURRENT_CDS_ARCHIVE_VERSION 9
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@@ -500,18 +500,26 @@ class DynamicArchiveBuilder : ResourceObj {
void sort_methods(InstanceKlass* ik) const;
void set_symbols_permanent();
void relocate_buffer_to_target();
void write_archive(char* serialized_data_start);
void write_regions(FileMapInfo* dynamic_info);
void write_archive(char* serialized_data);

void init_first_dump_space(address reserved_bottom) {
address first_space_base = reserved_bottom;
DumpRegion* mc_space = MetaspaceShared::misc_code_dump_space();
DumpRegion* rw_space = MetaspaceShared::read_write_dump_space();
MetaspaceShared::init_shared_dump_space(rw_space, first_space_base);
_current_dump_space = rw_space;

// Use the same MC->RW->RO ordering as in the base archive.
MetaspaceShared::init_shared_dump_space(mc_space, first_space_base);
_current_dump_space = mc_space;
_last_verified_top = first_space_base;
_num_dump_regions_used = 1;
}

void reserve_buffers_for_trampolines() {
size_t n = _estimated_trampoline_bytes;
assert(n >= SharedRuntime::trampoline_size(), "dont want to be empty");
MetaspaceShared::misc_code_space_alloc(n);
}

public:
DynamicArchiveBuilder() {
_klasses = new (ResourceObj::C_HEAP, mtClass) GrowableArray<InstanceKlass*>(100, true, mtInternal);
@@ -584,7 +592,10 @@ class DynamicArchiveBuilder : ResourceObj {
CHeapBitMap ptrmap;
ArchivePtrMarker::initialize(&ptrmap, (address*)reserved_bottom, (address*)current_dump_space()->top());

verify_estimate_size(sizeof(DynamicArchiveHeader), "header");
reserve_buffers_for_trampolines();
verify_estimate_size(_estimated_trampoline_bytes, "Trampolines");

start_dump_space(MetaspaceShared::read_write_dump_space());

log_info(cds, dynamic)("Copying %d klasses and %d symbols",
_klasses->length(), _symbols->length());
@@ -625,7 +636,7 @@ class DynamicArchiveBuilder : ResourceObj {

verify_estimate_size(_estimated_metsapceobj_bytes, "MetaspaceObjs");

char* serialized_data_start;
char* serialized_data;
{
set_symbols_permanent();

@@ -638,22 +649,15 @@ class DynamicArchiveBuilder : ResourceObj {
SymbolTable::write_to_archive(false);
SystemDictionaryShared::write_to_archive(false);

serialized_data_start = ro_space->top();
serialized_data = ro_space->top();
WriteClosure wc(ro_space);
SymbolTable::serialize_shared_table_header(&wc, false);
SystemDictionaryShared::serialize_dictionary_headers(&wc, false);
}

verify_estimate_size(_estimated_hashtable_bytes, "Hashtables");

// mc space starts ...
{
start_dump_space(MetaspaceShared::misc_code_dump_space());
make_trampolines();
}

verify_estimate_size(_estimated_trampoline_bytes, "Trampolines");

make_trampolines();
make_klasses_shareable();

{
@@ -664,7 +668,7 @@ class DynamicArchiveBuilder : ResourceObj {
relocate_buffer_to_target();
}

write_archive(serialized_data_start);
write_archive(serialized_data);
release_header();

assert(_num_dump_regions_used == _total_dump_regions, "must be");
@@ -801,25 +805,27 @@ size_t DynamicArchiveBuilder::estimate_trampoline_size() {
}

void DynamicArchiveBuilder::make_trampolines() {
DumpRegion* mc_space = MetaspaceShared::misc_code_dump_space();
char* p = mc_space->base();
for (int i = 0; i < _klasses->length(); i++) {
InstanceKlass* ik = _klasses->at(i);
Array<Method*>* methods = ik->methods();
for (int j = 0; j < methods->length(); j++) {
Method* m = methods->at(j);
address c2i_entry_trampoline =
(address)MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size());
address c2i_entry_trampoline = (address)p;
p += SharedRuntime::trampoline_size();
assert(p >= mc_space->base() && p <= mc_space->top(), "must be");
m->set_from_compiled_entry(to_target(c2i_entry_trampoline));
AdapterHandlerEntry** adapter_trampoline =
(AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*));

AdapterHandlerEntry** adapter_trampoline =(AdapterHandlerEntry**)p;
p += sizeof(AdapterHandlerEntry*);
assert(p >= mc_space->base() && p <= mc_space->top(), "must be");
*adapter_trampoline = NULL;
m->set_adapter_trampoline(to_target(adapter_trampoline));
}
}

if (MetaspaceShared::misc_code_dump_space()->used() == 0) {
// We have nothing to archive, but let's avoid having an empty region.
MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size());
}
guarantee(p <= mc_space->top(), "Estimate of trampoline size is insufficient");
}

void DynamicArchiveBuilder::make_klasses_shareable() {
@@ -1002,35 +1008,19 @@ void DynamicArchiveBuilder::relocate_buffer_to_target() {
}
}

void DynamicArchiveBuilder::write_regions(FileMapInfo* dynamic_info) {
dynamic_info->write_region(MetaspaceShared::rw,
MetaspaceShared::read_write_dump_space()->base(),
MetaspaceShared::read_write_dump_space()->used(),
/*read_only=*/false,/*allow_exec=*/false);
dynamic_info->write_region(MetaspaceShared::ro,
MetaspaceShared::read_only_dump_space()->base(),
MetaspaceShared::read_only_dump_space()->used(),
/*read_only=*/true, /*allow_exec=*/false);
dynamic_info->write_region(MetaspaceShared::mc,
MetaspaceShared::misc_code_dump_space()->base(),
MetaspaceShared::misc_code_dump_space()->used(),
/*read_only=*/false,/*allow_exec=*/true);
dynamic_info->write_bitmap_region(ArchivePtrMarker::ptrmap());
}

void DynamicArchiveBuilder::write_archive(char* serialized_data_start) {
void DynamicArchiveBuilder::write_archive(char* serialized_data) {
int num_klasses = _klasses->length();
int num_symbols = _symbols->length();

_header->set_serialized_data_start(to_target(serialized_data_start));
_header->set_serialized_data(to_target(serialized_data));

FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
assert(dynamic_info != NULL, "Sanity");

// Now write the archived data including the file offsets.
const char* archive_name = Arguments::GetSharedDynamicArchivePath();
dynamic_info->open_for_write(archive_name);
write_regions(dynamic_info);
MetaspaceShared::write_core_archive_regions(dynamic_info);
dynamic_info->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
dynamic_info->write_header();
@@ -1355,7 +1355,7 @@ bool FileMapInfo::remap_shared_readonly_as_readwrite() {
}

// Memory map a region in the address space.
static const char* shared_region_name[] = { "MiscData", "ReadWrite", "ReadOnly", "MiscCode", "Bitmap",
static const char* shared_region_name[] = { "MiscCode", "ReadWrite", "ReadOnly", "Bitmap",
"String1", "String2", "OpenArchive1", "OpenArchive2" };

MapArchiveResult FileMapInfo::map_regions(int regions[], int num_regions, char* mapped_base_address, ReservedSpace rs) {
@@ -1972,12 +1972,13 @@ char* FileMapInfo::region_addr(int idx) {
}
}

// The 3 core spaces are MC->RW->RO
FileMapRegion* FileMapInfo::first_core_space() const {
return is_static() ? space_at(MetaspaceShared::mc) : space_at(MetaspaceShared::rw);
return space_at(MetaspaceShared::mc);
}

FileMapRegion* FileMapInfo::last_core_space() const {
return is_static() ? space_at(MetaspaceShared::md) : space_at(MetaspaceShared::mc);
return space_at(MetaspaceShared::ro);
}

int FileMapHeader::compute_crc() {
@@ -2051,8 +2052,7 @@ bool FileMapInfo::validate_header() {
bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
assert(idx == MetaspaceShared::ro ||
idx == MetaspaceShared::rw ||
idx == MetaspaceShared::mc ||
idx == MetaspaceShared::md, "invalid region index");
idx == MetaspaceShared::mc, "invalid region index");
char* base = region_addr(idx);
if (p >= base && p < base + space_at(idx)->used()) {
return true;
@@ -187,7 +187,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
uintx _max_heap_size; // java max heap size during dumping
CompressedOops::Mode _narrow_oop_mode; // compressed oop encoding mode
int _narrow_klass_shift; // save narrow klass base and shift
size_t _misc_data_patching_offset;
size_t _cloned_vtables_offset; // The address of the first cloned vtable
size_t _serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
size_t _i2i_entry_code_buffers_offset;
size_t _i2i_entry_code_buffers_size;
@@ -252,8 +252,8 @@ class FileMapHeader: private CDSFileMapHeaderBase {
CompressedOops::Mode narrow_oop_mode() const { return _narrow_oop_mode; }
int narrow_klass_shift() const { return _narrow_klass_shift; }
address narrow_klass_base() const { return (address)mapped_base_address(); }
char* misc_data_patching_start() const { return from_mapped_offset(_misc_data_patching_offset); }
char* serialized_data_start() const { return from_mapped_offset(_serialized_data_offset); }
char* cloned_vtables() const { return from_mapped_offset(_cloned_vtables_offset); }
char* serialized_data() const { return from_mapped_offset(_serialized_data_offset); }
address i2i_entry_code_buffers() const { return (address)from_mapped_offset(_i2i_entry_code_buffers_offset); }
size_t i2i_entry_code_buffers_size() const { return _i2i_entry_code_buffers_size; }
address heap_end() const { return _heap_end; }
@@ -272,8 +272,8 @@ class FileMapHeader: private CDSFileMapHeaderBase {
jshort num_module_paths() const { return _num_module_paths; }

void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; }
void set_misc_data_patching_start(char* p) { set_mapped_offset(p, &_misc_data_patching_offset); }
void set_serialized_data_start(char* p) { set_mapped_offset(p, &_serialized_data_offset); }
void set_cloned_vtables(char* p) { set_mapped_offset(p, &_cloned_vtables_offset); }
void set_serialized_data(char* p) { set_mapped_offset(p, &_serialized_data_offset); }
void set_base_archive_name_size(size_t s) { _base_archive_name_size = s; }
void set_base_archive_is_default(bool b) { _base_archive_is_default = b; }
void set_header_size(size_t s) { _header_size = s; }
@@ -382,10 +382,10 @@ class FileMapInfo : public CHeapObj<mtInternal> {
jshort app_module_paths_start_index() const { return header()->app_module_paths_start_index(); }
jshort app_class_paths_start_index() const { return header()->app_class_paths_start_index(); }

char* misc_data_patching_start() const { return header()->misc_data_patching_start(); }
void set_misc_data_patching_start(char* p) const { header()->set_misc_data_patching_start(p); }
char* serialized_data_start() const { return header()->serialized_data_start(); }
void set_serialized_data_start(char* p) const { header()->set_serialized_data_start(p); }
char* cloned_vtables() const { return header()->cloned_vtables(); }
void set_cloned_vtables(char* p) const { header()->set_cloned_vtables(p); }
char* serialized_data() const { return header()->serialized_data(); }
void set_serialized_data(char* p) const { header()->set_serialized_data(p); }

bool is_file_position_aligned() const;
void align_file_position();

0 comments on commit d5bdb76

Please sign in to comment.
You can’t perform that action at this time.