Skip to content

Commit 3f4964f

Browse files
committed
8293291: Simplify relocation of native pointers in archive heap
Reviewed-by: ccheung, coleenp
1 parent 1553551 commit 3f4964f

17 files changed

+275
-235
lines changed

Diff for: src/hotspot/share/cds/archiveBuilder.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1166,8 +1166,8 @@ void ArchiveBuilder::clean_up_src_obj_table() {
11661166
void ArchiveBuilder::write_archive(FileMapInfo* mapinfo,
11671167
GrowableArray<MemRegion>* closed_heap_regions,
11681168
GrowableArray<MemRegion>* open_heap_regions,
1169-
GrowableArray<ArchiveHeapOopmapInfo>* closed_heap_oopmaps,
1170-
GrowableArray<ArchiveHeapOopmapInfo>* open_heap_oopmaps) {
1169+
GrowableArray<ArchiveHeapBitmapInfo>* closed_heap_bitmaps,
1170+
GrowableArray<ArchiveHeapBitmapInfo>* open_heap_bitmaps) {
11711171
// Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
11721172
// MetaspaceShared::n_regions (internal to hotspot).
11731173
assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity");
@@ -1176,18 +1176,18 @@ void ArchiveBuilder::write_archive(FileMapInfo* mapinfo,
11761176
write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false);
11771177

11781178
size_t bitmap_size_in_bytes;
1179-
char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), closed_heap_oopmaps, open_heap_oopmaps,
1179+
char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), closed_heap_bitmaps, open_heap_bitmaps,
11801180
bitmap_size_in_bytes);
11811181

11821182
if (closed_heap_regions != NULL) {
11831183
_total_closed_heap_region_size = mapinfo->write_heap_regions(
11841184
closed_heap_regions,
1185-
closed_heap_oopmaps,
1185+
closed_heap_bitmaps,
11861186
MetaspaceShared::first_closed_heap_region,
11871187
MetaspaceShared::max_num_closed_heap_regions);
11881188
_total_open_heap_region_size = mapinfo->write_heap_regions(
11891189
open_heap_regions,
1190-
open_heap_oopmaps,
1190+
open_heap_bitmaps,
11911191
MetaspaceShared::first_open_heap_region,
11921192
MetaspaceShared::max_num_open_heap_regions);
11931193
}

Diff for: src/hotspot/share/cds/archiveBuilder.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "utilities/resizeableResourceHash.hpp"
3737
#include "utilities/resourceHash.hpp"
3838

39-
struct ArchiveHeapOopmapInfo;
39+
struct ArchiveHeapBitmapInfo;
4040
class CHeapBitMap;
4141
class FileMapInfo;
4242
class Klass;
@@ -406,8 +406,8 @@ class ArchiveBuilder : public StackObj {
406406
void write_archive(FileMapInfo* mapinfo,
407407
GrowableArray<MemRegion>* closed_heap_regions,
408408
GrowableArray<MemRegion>* open_heap_regions,
409-
GrowableArray<ArchiveHeapOopmapInfo>* closed_heap_oopmaps,
410-
GrowableArray<ArchiveHeapOopmapInfo>* open_heap_oopmaps);
409+
GrowableArray<ArchiveHeapBitmapInfo>* closed_heap_oopmaps,
410+
GrowableArray<ArchiveHeapBitmapInfo>* open_heap_oopmaps);
411411
void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region,
412412
bool read_only, bool allow_exec);
413413

Diff for: src/hotspot/share/cds/archiveHeapLoader.cpp

+53-13
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,14 @@ void ArchiveHeapLoader::fixup_regions() {
7272
if (is_mapped()) {
7373
mapinfo->fixup_mapped_heap_regions();
7474
} else if (_loading_failed) {
75-
fill_failed_loaded_region();
75+
fill_failed_loaded_heap();
7676
}
7777
if (is_fully_available()) {
7878
if (!MetaspaceShared::use_full_module_graph()) {
7979
// Need to remove all the archived java.lang.Module objects from HeapShared::roots().
8080
ClassLoaderDataShared::clear_archived_oops();
8181
}
8282
}
83-
SystemDictionaryShared::update_archived_mirror_native_pointers();
8483
}
8584

8685
// ------------------ Support for Region MAPPING -----------------------------------------
@@ -171,7 +170,7 @@ struct LoadedArchiveHeapRegion {
171170
};
172171

173172
void ArchiveHeapLoader::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_regions,
174-
int num_loaded_regions) {
173+
int num_loaded_regions) {
175174
_dumptime_base_0 = loaded_regions[0]._dumptime_base;
176175
_dumptime_base_1 = loaded_regions[1]._dumptime_base;
177176
_dumptime_base_2 = loaded_regions[2]._dumptime_base;
@@ -314,7 +313,7 @@ bool ArchiveHeapLoader::load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegi
314313

315314
if (!mapinfo->read_region(ri->_region_index, (char*)load_address, r->used(), /* do_commit = */ false)) {
316315
// There's no easy way to free the buffer, so we will fill it with zero later
317-
// in fill_failed_loaded_region(), and it will eventually be GC'ed.
316+
// in fill_failed_loaded_heap(), and it will eventually be GC'ed.
318317
log_warning(cds)("Loading of heap region %d has failed. Archived objects are disabled", i);
319318
_loading_failed = true;
320319
return false;
@@ -339,6 +338,7 @@ bool ArchiveHeapLoader::load_regions(FileMapInfo* mapinfo, LoadedArchiveHeapRegi
339338
bm.iterate(&patcher);
340339
}
341340

341+
r->set_mapped_base((char*)load_address);
342342
load_address += r->used();
343343
}
344344

@@ -392,17 +392,24 @@ class VerifyLoadedHeapEmbeddedPointers: public BasicOopIterateClosure {
392392

393393
void ArchiveHeapLoader::finish_initialization() {
394394
if (is_loaded()) {
395-
HeapWord* bottom = (HeapWord*)_loaded_heap_bottom;
396-
HeapWord* top = (HeapWord*)_loaded_heap_top;
397-
398-
MemRegion archive_space = MemRegion(bottom, top);
399-
Universe::heap()->complete_loaded_archive_space(archive_space);
395+
// These operations are needed only when the heap is loaded (not mapped).
396+
finish_loaded_heap();
397+
if (VerifyArchivedFields > 0) {
398+
verify_loaded_heap();
399+
}
400400
}
401+
patch_native_pointers();
402+
}
401403

402-
if (VerifyArchivedFields <= 0 || !is_loaded()) {
403-
return;
404-
}
404+
void ArchiveHeapLoader::finish_loaded_heap() {
405+
HeapWord* bottom = (HeapWord*)_loaded_heap_bottom;
406+
HeapWord* top = (HeapWord*)_loaded_heap_top;
407+
408+
MemRegion archive_space = MemRegion(bottom, top);
409+
Universe::heap()->complete_loaded_archive_space(archive_space);
410+
}
405411

412+
void ArchiveHeapLoader::verify_loaded_heap() {
406413
log_info(cds, heap)("Verify all oops and pointers in loaded heap");
407414

408415
ResourceMark rm;
@@ -424,7 +431,7 @@ void ArchiveHeapLoader::finish_initialization() {
424431
}
425432
}
426433

427-
void ArchiveHeapLoader::fill_failed_loaded_region() {
434+
void ArchiveHeapLoader::fill_failed_loaded_heap() {
428435
assert(_loading_failed, "must be");
429436
if (_loaded_heap_bottom != 0) {
430437
assert(_loaded_heap_top != 0, "must be");
@@ -434,4 +441,37 @@ void ArchiveHeapLoader::fill_failed_loaded_region() {
434441
}
435442
}
436443

444+
class PatchNativePointers: public BitMapClosure {
445+
Metadata** _start;
446+
447+
public:
448+
PatchNativePointers(Metadata** start) : _start(start) {}
449+
450+
bool do_bit(size_t offset) {
451+
Metadata** p = _start + offset;
452+
*p = (Metadata*)(address(*p) + MetaspaceShared::relocation_delta());
453+
// Currently we have only Klass pointers in heap objects.
454+
// This needs to be relaxed when we support other types of native
455+
// pointers such as Method.
456+
assert(((Klass*)(*p))->is_klass(), "must be");
457+
return true;
458+
}
459+
};
460+
461+
void ArchiveHeapLoader::patch_native_pointers() {
462+
if (MetaspaceShared::relocation_delta() == 0) {
463+
return;
464+
}
465+
466+
for (int i = MetaspaceShared::first_archive_heap_region;
467+
i <= MetaspaceShared::last_archive_heap_region; i++) {
468+
FileMapRegion* r = FileMapInfo::current_info()->space_at(i);
469+
if (r->mapped_base() != NULL && r->has_ptrmap()) {
470+
log_info(cds, heap)("Patching native pointers in heap region %d", i);
471+
BitMapView bm = r->ptrmap_view();
472+
PatchNativePointers patcher((Metadata**)r->mapped_base());
473+
bm.iterate(&patcher);
474+
}
475+
}
476+
}
437477
#endif // INCLUDE_CDS_JAVA_HEAP

Diff for: src/hotspot/share/cds/archiveHeapLoader.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ class ArchiveHeapLoader : AllStatic {
146146
int num_loaded_regions, uintptr_t buffer);
147147
static void init_loaded_heap_relocation(LoadedArchiveHeapRegion* reloc_info,
148148
int num_loaded_regions);
149-
static void fill_failed_loaded_region();
149+
static void patch_native_pointers();
150+
static void finish_loaded_heap();
151+
static void verify_loaded_heap();
152+
static void fill_failed_loaded_heap();
150153

151154
static bool is_in_loaded_heap(uintptr_t o) {
152155
return (_loaded_heap_bottom <= o && o < _loaded_heap_top);

Diff for: src/hotspot/share/cds/filemap.cpp

+46-19
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,29 @@ void FileMapRegion::init(int region_index, size_t mapping_offset, size_t size, b
14921492
_mapped_base = NULL;
14931493
}
14941494

1495+
void FileMapRegion::init_bitmaps(ArchiveHeapBitmapInfo oopmap, ArchiveHeapBitmapInfo ptrmap) {
1496+
_oopmap_offset = oopmap._bm_region_offset;
1497+
_oopmap_size_in_bits = oopmap._size_in_bits;
1498+
1499+
_ptrmap_offset = ptrmap._bm_region_offset;
1500+
_ptrmap_size_in_bits = ptrmap._size_in_bits;
1501+
}
1502+
1503+
BitMapView FileMapRegion::bitmap_view(bool is_oopmap) {
1504+
char* bitmap_base = FileMapInfo::current_info()->map_bitmap_region();
1505+
bitmap_base += is_oopmap ? _oopmap_offset : _ptrmap_offset;
1506+
size_t size_in_bits = is_oopmap ? _oopmap_size_in_bits : _ptrmap_size_in_bits;
1507+
return BitMapView((BitMap::bm_word_t*)(bitmap_base), size_in_bits);
1508+
}
1509+
1510+
BitMapView FileMapRegion::oopmap_view() {
1511+
return bitmap_view(true);
1512+
}
1513+
1514+
BitMapView FileMapRegion::ptrmap_view() {
1515+
assert(has_ptrmap(), "must be");
1516+
return bitmap_view(false);
1517+
}
14951518

14961519
static const char* region_name(int region_index) {
14971520
static const char* names[] = {
@@ -1566,41 +1589,41 @@ void FileMapInfo::write_region(int region, char* base, size_t size,
15661589
}
15671590
}
15681591

1569-
size_t FileMapInfo::set_oopmaps_offset(GrowableArray<ArchiveHeapOopmapInfo>* oopmaps, size_t curr_size) {
1570-
for (int i = 0; i < oopmaps->length(); i++) {
1571-
oopmaps->at(i)._offset = curr_size;
1572-
curr_size += oopmaps->at(i)._oopmap_size_in_bytes;
1592+
size_t FileMapInfo::set_bitmaps_offset(GrowableArray<ArchiveHeapBitmapInfo>* bitmaps, size_t curr_size) {
1593+
for (int i = 0; i < bitmaps->length(); i++) {
1594+
bitmaps->at(i)._bm_region_offset = curr_size;
1595+
curr_size += bitmaps->at(i)._size_in_bytes;
15731596
}
15741597
return curr_size;
15751598
}
15761599

1577-
size_t FileMapInfo::write_oopmaps(GrowableArray<ArchiveHeapOopmapInfo>* oopmaps, size_t curr_offset, char* buffer) {
1578-
for (int i = 0; i < oopmaps->length(); i++) {
1579-
memcpy(buffer + curr_offset, oopmaps->at(i)._oopmap, oopmaps->at(i)._oopmap_size_in_bytes);
1580-
curr_offset += oopmaps->at(i)._oopmap_size_in_bytes;
1600+
size_t FileMapInfo::write_bitmaps(GrowableArray<ArchiveHeapBitmapInfo>* bitmaps, size_t curr_offset, char* buffer) {
1601+
for (int i = 0; i < bitmaps->length(); i++) {
1602+
memcpy(buffer + curr_offset, bitmaps->at(i)._map, bitmaps->at(i)._size_in_bytes);
1603+
curr_offset += bitmaps->at(i)._size_in_bytes;
15811604
}
15821605
return curr_offset;
15831606
}
15841607

15851608
char* FileMapInfo::write_bitmap_region(const CHeapBitMap* ptrmap,
1586-
GrowableArray<ArchiveHeapOopmapInfo>* closed_oopmaps,
1587-
GrowableArray<ArchiveHeapOopmapInfo>* open_oopmaps,
1609+
GrowableArray<ArchiveHeapBitmapInfo>* closed_bitmaps,
1610+
GrowableArray<ArchiveHeapBitmapInfo>* open_bitmaps,
15881611
size_t &size_in_bytes) {
15891612
size_t size_in_bits = ptrmap->size();
15901613
size_in_bytes = ptrmap->size_in_bytes();
15911614

1592-
if (closed_oopmaps != NULL && open_oopmaps != NULL) {
1593-
size_in_bytes = set_oopmaps_offset(closed_oopmaps, size_in_bytes);
1594-
size_in_bytes = set_oopmaps_offset(open_oopmaps, size_in_bytes);
1615+
if (closed_bitmaps != NULL && open_bitmaps != NULL) {
1616+
size_in_bytes = set_bitmaps_offset(closed_bitmaps, size_in_bytes);
1617+
size_in_bytes = set_bitmaps_offset(open_bitmaps, size_in_bytes);
15951618
}
15961619

15971620
char* buffer = NEW_C_HEAP_ARRAY(char, size_in_bytes, mtClassShared);
15981621
ptrmap->write_to((BitMap::bm_word_t*)buffer, ptrmap->size_in_bytes());
15991622
header()->set_ptrmap_size_in_bits(size_in_bits);
16001623

1601-
if (closed_oopmaps != NULL && open_oopmaps != NULL) {
1602-
size_t curr_offset = write_oopmaps(closed_oopmaps, ptrmap->size_in_bytes(), buffer);
1603-
write_oopmaps(open_oopmaps, curr_offset, buffer);
1624+
if (closed_bitmaps != NULL && open_bitmaps != NULL) {
1625+
size_t curr_offset = write_bitmaps(closed_bitmaps, ptrmap->size_in_bytes(), buffer);
1626+
write_bitmaps(open_bitmaps, curr_offset, buffer);
16041627
}
16051628

16061629
write_region(MetaspaceShared::bm, (char*)buffer, size_in_bytes, /*read_only=*/true, /*allow_exec=*/false);
@@ -1639,7 +1662,7 @@ char* FileMapInfo::write_bitmap_region(const CHeapBitMap* ptrmap,
16391662
// |
16401663
// +-- gap
16411664
size_t FileMapInfo::write_heap_regions(GrowableArray<MemRegion>* regions,
1642-
GrowableArray<ArchiveHeapOopmapInfo>* oopmaps,
1665+
GrowableArray<ArchiveHeapBitmapInfo>* bitmaps,
16431666
int first_region_id, int max_num_regions) {
16441667
assert(max_num_regions <= 2, "Only support maximum 2 memory regions");
16451668

@@ -1665,8 +1688,10 @@ size_t FileMapInfo::write_heap_regions(GrowableArray<MemRegion>* regions,
16651688
int region_idx = i + first_region_id;
16661689
write_region(region_idx, start, size, false, false);
16671690
if (size > 0) {
1668-
space_at(region_idx)->init_oopmap(oopmaps->at(i)._offset,
1669-
oopmaps->at(i)._oopmap_size_in_bits);
1691+
int oopmap_idx = i * 2;
1692+
int ptrmap_idx = i * 2 + 1;
1693+
space_at(region_idx)->init_bitmaps(bitmaps->at(oopmap_idx),
1694+
bitmaps->at(ptrmap_idx));
16701695
}
16711696
}
16721697
return total_size;
@@ -2307,6 +2332,8 @@ bool FileMapInfo::map_heap_regions(int first, int max, bool is_open_archive,
23072332
log_info(cds)("UseSharedSpaces: mapped heap regions are corrupt");
23082333
return false;
23092334
}
2335+
2336+
si->set_mapped_base(base);
23102337
}
23112338

23122339
cleanup._aborted = false;

Diff for: src/hotspot/share/cds/filemap.hpp

+17-16
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
static const int JVM_IDENT_MAX = 256;
4141

42+
class BitMapView;
4243
class CHeapBitMap;
4344
class ClassFileStream;
4445
class ClassLoaderData;
@@ -102,11 +103,11 @@ class SharedClassPathEntry {
102103
}
103104
};
104105

105-
struct ArchiveHeapOopmapInfo {
106-
address _oopmap; // bitmap for relocating embedded oops
107-
size_t _offset; // this oopmap is stored at this offset from the bottom of the BM region
108-
size_t _oopmap_size_in_bits;
109-
size_t _oopmap_size_in_bytes;
106+
struct ArchiveHeapBitmapInfo {
107+
address _map; // bitmap for relocating embedded oops
108+
size_t _bm_region_offset; // this bitmap is stored at this offset from the bottom of the BM region
109+
size_t _size_in_bits;
110+
size_t _size_in_bytes;
110111
};
111112

112113
class SharedPathTable {
@@ -137,6 +138,7 @@ class SharedPathTable {
137138

138139

139140
class FileMapRegion: private CDSFileMapRegion {
141+
BitMapView bitmap_view(bool is_oopmap);
140142
public:
141143
void assert_is_heap_region() const {
142144
assert(_is_heap_region, "must be heap region");
@@ -156,7 +158,7 @@ class FileMapRegion: private CDSFileMapRegion {
156158
size_t mapping_end_offset() const { return _mapping_offset + used_aligned(); }
157159
size_t used() const { return _used; }
158160
size_t used_aligned() const; // aligned up to MetaspaceShared::core_region_alignment()
159-
char* mapped_base() const { assert_is_not_heap_region(); return _mapped_base; }
161+
char* mapped_base() const { return _mapped_base; }
160162
char* mapped_end() const { return mapped_base() + used_aligned(); }
161163
bool read_only() const { return _read_only != 0; }
162164
bool allow_exec() const { return _allow_exec != 0; }
@@ -170,11 +172,10 @@ class FileMapRegion: private CDSFileMapRegion {
170172
void set_mapped_from_file(bool v) { _mapped_from_file = v; }
171173
void init(int region_index, size_t mapping_offset, size_t size, bool read_only,
172174
bool allow_exec, int crc);
173-
174-
void init_oopmap(size_t oopmap_offset, size_t size_in_bits) {
175-
_oopmap_offset = oopmap_offset;
176-
_oopmap_size_in_bits = size_in_bits;
177-
}
175+
void init_bitmaps(ArchiveHeapBitmapInfo oopmap, ArchiveHeapBitmapInfo ptrmap);
176+
BitMapView oopmap_view();
177+
BitMapView ptrmap_view();
178+
bool has_ptrmap() { return _ptrmap_size_in_bits != 0; }
178179

179180
void print(outputStream* st, int region_index);
180181
};
@@ -444,11 +445,11 @@ class FileMapInfo : public CHeapObj<mtInternal> {
444445
void write_region(int region, char* base, size_t size,
445446
bool read_only, bool allow_exec);
446447
char* write_bitmap_region(const CHeapBitMap* ptrmap,
447-
GrowableArray<ArchiveHeapOopmapInfo>* closed_oopmaps,
448-
GrowableArray<ArchiveHeapOopmapInfo>* open_oopmaps,
448+
GrowableArray<ArchiveHeapBitmapInfo>* closed_bitmaps,
449+
GrowableArray<ArchiveHeapBitmapInfo>* open_bitmaps,
449450
size_t &size_in_bytes);
450451
size_t write_heap_regions(GrowableArray<MemRegion>* regions,
451-
GrowableArray<ArchiveHeapOopmapInfo>* oopmaps,
452+
GrowableArray<ArchiveHeapBitmapInfo>* bitmaps,
452453
int first_region_id, int max_num_regions);
453454
void write_bytes(const void* buffer, size_t count);
454455
void write_bytes_aligned(const void* buffer, size_t count);
@@ -573,8 +574,8 @@ class FileMapInfo : public CHeapObj<mtInternal> {
573574
void map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN;
574575
MapArchiveResult map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs);
575576
bool relocate_pointers_in_core_regions(intx addr_delta);
576-
static size_t set_oopmaps_offset(GrowableArray<ArchiveHeapOopmapInfo> *oopmaps, size_t curr_size);
577-
static size_t write_oopmaps(GrowableArray<ArchiveHeapOopmapInfo> *oopmaps, size_t curr_offset, char* buffer);
577+
static size_t set_bitmaps_offset(GrowableArray<ArchiveHeapBitmapInfo> *bitmaps, size_t curr_size);
578+
static size_t write_bitmaps(GrowableArray<ArchiveHeapBitmapInfo> *bitmaps, size_t curr_offset, char* buffer);
578579

579580
address decode_start_address(FileMapRegion* spc, bool with_current_oop_encoding_mode);
580581

0 commit comments

Comments
 (0)