Skip to content

Commit 7c2de83

Browse files
committed
8231257: Avoid calling FileMapInfo::write_region twice
Reviewed-by: ccheung
1 parent d6b7266 commit 7c2de83

File tree

4 files changed

+64
-85
lines changed

4 files changed

+64
-85
lines changed

src/hotspot/share/memory/dynamicArchive.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ class DynamicArchiveBuilder : ResourceObj {
471471
void set_symbols_permanent();
472472
void relocate_buffer_to_target();
473473
void write_archive(char* read_only_tables_start);
474+
void write_regions(FileMapInfo* dynamic_info);
474475

475476
void init_first_dump_space(address reserved_bottom) {
476477
address first_space_base = reserved_bottom;
@@ -911,9 +912,7 @@ void DynamicArchiveBuilder::relocate_buffer_to_target() {
911912
_header->relocate_shared_path_table(table);
912913
}
913914

914-
static void write_archive_info(FileMapInfo* dynamic_info, DynamicArchiveHeader *header) {
915-
dynamic_info->write_header();
916-
dynamic_info->align_file_position();
915+
void DynamicArchiveBuilder::write_regions(FileMapInfo* dynamic_info) {
917916
dynamic_info->write_region(MetaspaceShared::rw,
918917
MetaspaceShared::read_write_dump_space()->base(),
919918
MetaspaceShared::read_write_dump_space()->used(),
@@ -937,19 +936,14 @@ void DynamicArchiveBuilder::write_archive(char* read_only_tables_start) {
937936
FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
938937
assert(dynamic_info != NULL, "Sanity");
939938

940-
// Populate the file offsets, region crcs, etc. No data is written out.
941-
write_archive_info(dynamic_info, _header);
942-
943-
// the header will no longer change. Compute its crc.
944-
dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
945-
946939
// Now write the archived data including the file offsets.
947940
const char* archive_name = Arguments::GetSharedDynamicArchivePath();
948941
dynamic_info->open_for_write(archive_name);
949-
write_archive_info(dynamic_info, _header);
942+
write_regions(dynamic_info);
943+
dynamic_info->set_header_crc(dynamic_info->compute_header_crc());
944+
dynamic_info->write_header();
950945
dynamic_info->close();
951946

952-
953947
address base = to_target(_alloc_bottom);
954948
address top = address(current_dump_space()->top()) + _buffer_to_target_delta;
955949
size_t file_size = pointer_delta(top, base, sizeof(char));

src/hotspot/share/memory/filemap.cpp

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,11 @@ bool FileMapInfo::init_from_file(int fd, bool is_static) {
10331033
return true;
10341034
}
10351035

1036+
void FileMapInfo::seek_to_position(size_t pos) {
1037+
if (lseek(_fd, (long)pos, SEEK_SET) < 0) {
1038+
fail_stop("Unable to seek to position " SIZE_FORMAT, pos);
1039+
}
1040+
}
10361041

10371042
// Read the FileMapInfo information from the file.
10381043
bool FileMapInfo::open_for_read(const char* path) {
@@ -1088,14 +1093,26 @@ void FileMapInfo::open_for_write(const char* path) {
10881093
os::strerror(errno));
10891094
}
10901095
_fd = fd;
1091-
_file_offset = 0;
10921096
_file_open = true;
1097+
1098+
// Seek past the header. We will write the header after all regions are written
1099+
// and their CRCs computed.
1100+
size_t header_bytes = header()->header_size();
1101+
if (header()->magic() == CDS_DYNAMIC_ARCHIVE_MAGIC) {
1102+
header_bytes += strlen(Arguments::GetSharedArchivePath()) + 1;
1103+
}
1104+
1105+
header_bytes = align_up(header_bytes, os::vm_allocation_granularity());
1106+
_file_offset = header_bytes;
1107+
seek_to_position(_file_offset);
10931108
}
10941109

10951110

10961111
// Write the header to the file, seek to the next allocation boundary.
10971112

10981113
void FileMapInfo::write_header() {
1114+
_file_offset = 0;
1115+
seek_to_position(_file_offset);
10991116
char* base_archive_name = NULL;
11001117
if (header()->magic() == CDS_DYNAMIC_ARCHIVE_MAGIC) {
11011118
base_archive_name = (char*)Arguments::GetSharedArchivePath();
@@ -1108,7 +1125,6 @@ void FileMapInfo::write_header() {
11081125
if (base_archive_name != NULL) {
11091126
write_bytes(base_archive_name, header()->base_archive_name_size());
11101127
}
1111-
align_file_position();
11121128
}
11131129

11141130
void FileMapRegion::init(bool is_heap_region, char* base, size_t size, bool read_only,
@@ -1132,9 +1148,6 @@ void FileMapRegion::init(bool is_heap_region, char* base, size_t size, bool read
11321148
_crc = crc;
11331149
}
11341150

1135-
// Dump region to file.
1136-
// This is called twice for each region during archiving, once before
1137-
// the archive file is open (_file_open is false) and once after.
11381151
void FileMapInfo::write_region(int region, char* base, size_t size,
11391152
bool read_only, bool allow_exec) {
11401153
assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Dump time only");
@@ -1146,14 +1159,10 @@ void FileMapInfo::write_region(int region, char* base, size_t size,
11461159
target_base = DynamicArchive::buffer_to_target(base);
11471160
}
11481161

1149-
if (_file_open) {
1150-
guarantee(si->file_offset() == _file_offset, "file offset mismatch.");
1151-
log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
1152-
" bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
1153-
region, size, p2i(target_base), _file_offset);
1154-
} else {
1155-
si->set_file_offset(_file_offset);
1156-
}
1162+
si->set_file_offset(_file_offset);
1163+
log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
1164+
" bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
1165+
region, size, p2i(target_base), _file_offset);
11571166

11581167
int crc = ClassLoader::crc32(0, base, (jint)size);
11591168
si->init(HeapShared::is_heap_region(region), target_base, size, read_only, allow_exec, crc);
@@ -1196,8 +1205,7 @@ void FileMapInfo::write_region(int region, char* base, size_t size,
11961205
// +-- gap
11971206
size_t FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
11981207
GrowableArray<ArchiveHeapOopmapInfo> *oopmaps,
1199-
int first_region_id, int max_num_regions,
1200-
bool print_log) {
1208+
int first_region_id, int max_num_regions) {
12011209
assert(max_num_regions <= 2, "Only support maximum 2 memory regions");
12021210

12031211
int arr_len = heap_mem == NULL ? 0 : heap_mem->length();
@@ -1221,10 +1229,8 @@ size_t FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> *heap_me
12211229
total_size += size;
12221230
}
12231231

1224-
if (print_log) {
1225-
log_info(cds)("Archive heap region %d " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes",
1226-
i, p2i(start), p2i(start + size), size);
1227-
}
1232+
log_info(cds)("Archive heap region %d " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes",
1233+
i, p2i(start), p2i(start + size), size);
12281234
write_region(i, start, size, false, false);
12291235
if (size > 0) {
12301236
space_at(i)->init_oopmap(oopmaps->at(arr_idx)._oopmap,
@@ -1237,14 +1243,13 @@ size_t FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> *heap_me
12371243
// Dump bytes to file -- at the current file position.
12381244

12391245
void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {
1240-
if (_file_open) {
1241-
size_t n = os::write(_fd, buffer, (unsigned int)nbytes);
1242-
if (n != nbytes) {
1243-
// If the shared archive is corrupted, close it and remove it.
1244-
close();
1245-
remove(_full_path);
1246-
fail_stop("Unable to write to shared archive file.");
1247-
}
1246+
assert(_file_open, "must be");
1247+
size_t n = os::write(_fd, buffer, (unsigned int)nbytes);
1248+
if (n != nbytes) {
1249+
// If the shared archive is corrupted, close it and remove it.
1250+
close();
1251+
remove(_full_path);
1252+
fail_stop("Unable to write to shared archive file.");
12481253
}
12491254
_file_offset += nbytes;
12501255
}
@@ -1257,20 +1262,17 @@ bool FileMapInfo::is_file_position_aligned() const {
12571262
// Align file position to an allocation unit boundary.
12581263

12591264
void FileMapInfo::align_file_position() {
1265+
assert(_file_open, "must be");
12601266
size_t new_file_offset = align_up(_file_offset,
1261-
os::vm_allocation_granularity());
1267+
os::vm_allocation_granularity());
12621268
if (new_file_offset != _file_offset) {
12631269
_file_offset = new_file_offset;
1264-
if (_file_open) {
1265-
// Seek one byte back from the target and write a byte to insure
1266-
// that the written file is the correct length.
1267-
_file_offset -= 1;
1268-
if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) {
1269-
fail_stop("Unable to seek.");
1270-
}
1271-
char zero = 0;
1272-
write_bytes(&zero, 1);
1273-
}
1270+
// Seek one byte back from the target and write a byte to insure
1271+
// that the written file is the correct length.
1272+
_file_offset -= 1;
1273+
seek_to_position(_file_offset);
1274+
char zero = 0;
1275+
write_bytes(&zero, 1);
12741276
}
12751277
}
12761278

src/hotspot/share/memory/filemap.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,7 @@ class FileMapInfo : public CHeapObj<mtInternal> {
412412
bool read_only, bool allow_exec);
413413
size_t write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
414414
GrowableArray<ArchiveHeapOopmapInfo> *oopmaps,
415-
int first_region_id, int max_num_regions,
416-
bool print_log);
415+
int first_region_id, int max_num_regions);
417416
void write_bytes(const void* buffer, size_t count);
418417
void write_bytes_aligned(const void* buffer, size_t count);
419418
size_t read_bytes(void* buffer, size_t count);
@@ -479,6 +478,7 @@ class FileMapInfo : public CHeapObj<mtInternal> {
479478
char* region_addr(int idx);
480479

481480
private:
481+
void seek_to_position(size_t pos);
482482
char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL);
483483
int num_paths(const char* path) NOT_CDS_RETURN_(0);
484484
GrowableArray<const char*>* create_path_array(const char* path) NOT_CDS_RETURN_(NULL);

src/hotspot/share/memory/metaspaceShared.cpp

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,9 @@ class VM_PopulateDumpSharedSpace: public VM_Operation {
11371137

11381138
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
11391139
void doit(); // outline because gdb sucks
1140-
static void write_region(FileMapInfo* mapinfo, int region, DumpRegion* space, bool read_only, bool allow_exec);
1140+
static void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only, bool allow_exec) {
1141+
mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1142+
}
11411143
bool allow_nested_vm_operations() const { return true; }
11421144
}; // class VM_PopulateDumpSharedSpace
11431145

@@ -1406,11 +1408,6 @@ DumpAllocStats* ArchiveCompactor::_alloc_stats;
14061408
SortedSymbolClosure* ArchiveCompactor::_ssc;
14071409
ArchiveCompactor::RelocationTable* ArchiveCompactor::_new_loc_table;
14081410

1409-
void VM_PopulateDumpSharedSpace::write_region(FileMapInfo* mapinfo, int region_idx,
1410-
DumpRegion* dump_region, bool read_only, bool allow_exec) {
1411-
mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec);
1412-
}
1413-
14141411
void VM_PopulateDumpSharedSpace::dump_symbols() {
14151412
tty->print_cr("Dumping symbol table ...");
14161413

@@ -1546,44 +1543,30 @@ void VM_PopulateDumpSharedSpace::doit() {
15461543
mapinfo->set_read_only_tables_start(read_only_tables_start);
15471544
mapinfo->set_misc_data_patching_start(vtbl_list);
15481545
mapinfo->set_i2i_entry_code_buffers(MetaspaceShared::i2i_entry_code_buffers(),
1549-
MetaspaceShared::i2i_entry_code_buffers_size());
1546+
MetaspaceShared::i2i_entry_code_buffers_size());
15501547
mapinfo->set_core_spaces_size(core_spaces_size);
1548+
mapinfo->open_for_write();
15511549

1552-
for (int pass=1; pass<=2; pass++) {
1553-
bool print_archive_log = (pass==1);
1554-
if (pass == 1) {
1555-
// The first pass doesn't actually write the data to disk. All it
1556-
// does is to update the fields in the mapinfo->_header.
1557-
} else {
1558-
// After the first pass, the contents of mapinfo->_header are finalized,
1559-
// so we can compute the header's CRC, and write the contents of the header
1560-
// and the regions into disk.
1561-
mapinfo->open_for_write();
1562-
mapinfo->set_header_crc(mapinfo->compute_header_crc());
1563-
}
1564-
mapinfo->write_header();
1565-
1566-
// NOTE: md contains the trampoline code for method entries, which are patched at run time,
1567-
// so it needs to be read/write.
1568-
write_region(mapinfo, MetaspaceShared::mc, &_mc_region, /*read_only=*/false,/*allow_exec=*/true);
1569-
write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1570-
write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1571-
write_region(mapinfo, MetaspaceShared::md, &_md_region, /*read_only=*/false,/*allow_exec=*/false);
1550+
// NOTE: md contains the trampoline code for method entries, which are patched at run time,
1551+
// so it needs to be read/write.
1552+
write_region(mapinfo, MetaspaceShared::mc, &_mc_region, /*read_only=*/false,/*allow_exec=*/true);
1553+
write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false);
1554+
write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
1555+
write_region(mapinfo, MetaspaceShared::md, &_md_region, /*read_only=*/false,/*allow_exec=*/false);
15721556

1573-
_total_closed_archive_region_size = mapinfo->write_archive_heap_regions(
1557+
_total_closed_archive_region_size = mapinfo->write_archive_heap_regions(
15741558
_closed_archive_heap_regions,
15751559
_closed_archive_heap_oopmaps,
15761560
MetaspaceShared::first_closed_archive_heap_region,
1577-
MetaspaceShared::max_closed_archive_heap_region,
1578-
print_archive_log);
1579-
_total_open_archive_region_size = mapinfo->write_archive_heap_regions(
1561+
MetaspaceShared::max_closed_archive_heap_region);
1562+
_total_open_archive_region_size = mapinfo->write_archive_heap_regions(
15801563
_open_archive_heap_regions,
15811564
_open_archive_heap_oopmaps,
15821565
MetaspaceShared::first_open_archive_heap_region,
1583-
MetaspaceShared::max_open_archive_heap_region,
1584-
print_archive_log);
1585-
}
1566+
MetaspaceShared::max_open_archive_heap_region);
15861567

1568+
mapinfo->set_header_crc(mapinfo->compute_header_crc());
1569+
mapinfo->write_header();
15871570
mapinfo->close();
15881571

15891572
// Restore the vtable in case we invoke any virtual methods.

0 commit comments

Comments
 (0)