8329417: Remove objects with no pointers from relocation bitmap

Reviewed-by: ccheung, iklam
This commit is contained in:
Matias Saavedra Silva 2024-04-23 15:07:55 +00:00
parent 383fe6eaab
commit b6518a5db0
5 changed files with 54 additions and 11 deletions

View File

@ -77,6 +77,7 @@ ArchiveBuilder::SourceObjList::~SourceObjList() {
void ArchiveBuilder::SourceObjList::append(SourceObjInfo* src_info) {
// Save this source object for copying
src_info->set_id(_objs->length());
_objs->append(src_info);
// Prepare for marking the pointers in this source object
@ -94,6 +95,7 @@ void ArchiveBuilder::SourceObjList::append(SourceObjInfo* src_info) {
void ArchiveBuilder::SourceObjList::remember_embedded_pointer(SourceObjInfo* src_info, MetaspaceClosure::Ref* ref) {
// src_obj contains a pointer. Remember the location of this pointer in _ptrmap,
// so that we can copy/relocate it later.
src_info->set_has_embedded_pointer();
address src_obj = src_info->source_addr();
address* field_addr = ref->addr();
assert(src_info->ptrmap_start() < _total_bytes, "sanity");
@ -589,6 +591,26 @@ char* ArchiveBuilder::ro_strdup(const char* s) {
return archived_str;
}
// The objects that have embedded pointers will sink
// towards the end of the list. This ensures we have a maximum
// number of leading zero bits in the relocation bitmap.
int ArchiveBuilder::compare_src_objs(SourceObjInfo** a, SourceObjInfo** b) {
if ((*a)->has_embedded_pointer() && !(*b)->has_embedded_pointer()) {
return 1;
} else if (!(*a)->has_embedded_pointer() && (*b)->has_embedded_pointer()) {
return -1;
} else {
// This is necessary to keep the sorting order stable. Otherwise the
// archive's contents may not be deterministic.
return (*a)->id() - (*b)->id();
}
}
void ArchiveBuilder::sort_metadata_objs() {
_rw_src_objs.objs()->sort(compare_src_objs);
_ro_src_objs.objs()->sort(compare_src_objs);
}
void ArchiveBuilder::dump_rw_metadata() {
ResourceMark rm;
log_info(cds)("Allocating RW objects ... ");

View File

@ -126,15 +126,18 @@ private:
uintx _ptrmap_start; // The bit-offset of the start of this object (inclusive)
uintx _ptrmap_end; // The bit-offset of the end of this object (exclusive)
bool _read_only;
bool _has_embedded_pointer;
FollowMode _follow_mode;
int _size_in_bytes;
int _id; // Each object has a unique serial ID, starting from zero. The ID is assigned
// when the object is added into _source_objs.
MetaspaceObj::Type _msotype;
address _source_addr; // The source object to be copied.
address _buffered_addr; // The copy of this object insider the buffer.
public:
SourceObjInfo(MetaspaceClosure::Ref* ref, bool read_only, FollowMode follow_mode) :
_ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _follow_mode(follow_mode),
_size_in_bytes(ref->size() * BytesPerWord), _msotype(ref->msotype()),
_ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _has_embedded_pointer(false), _follow_mode(follow_mode),
_size_in_bytes(ref->size() * BytesPerWord), _id(0), _msotype(ref->msotype()),
_source_addr(ref->obj()) {
if (follow_mode == point_to_it) {
_buffered_addr = ref->obj();
@ -164,7 +167,11 @@ private:
uintx ptrmap_start() const { return _ptrmap_start; } // inclusive
uintx ptrmap_end() const { return _ptrmap_end; } // exclusive
bool read_only() const { return _read_only; }
bool has_embedded_pointer() const { return _has_embedded_pointer; }
void set_has_embedded_pointer() { _has_embedded_pointer = true; }
int size_in_bytes() const { return _size_in_bytes; }
int id() const { return _id; }
void set_id(int i) { _id = i; }
address source_addr() const { return _source_addr; }
address buffered_addr() const {
if (_follow_mode != set_to_null) {
@ -384,6 +391,8 @@ public:
char* ro_strdup(const char* s);
static int compare_src_objs(SourceObjInfo** a, SourceObjInfo** b);
void sort_metadata_objs();
void dump_rw_metadata();
void dump_ro_metadata();
void relocate_metaspaceobj_embedded_pointers();

View File

@ -293,6 +293,8 @@ void FileMapHeader::print(outputStream* st) {
st->print_cr("- heap_roots_offset: " SIZE_FORMAT, _heap_roots_offset);
st->print_cr("- _heap_oopmap_start_pos: " SIZE_FORMAT, _heap_oopmap_start_pos);
st->print_cr("- _heap_ptrmap_start_pos: " SIZE_FORMAT, _heap_ptrmap_start_pos);
st->print_cr("- _rw_ptrmap_start_pos: " SIZE_FORMAT, _rw_ptrmap_start_pos);
st->print_cr("- _ro_ptrmap_start_pos: " SIZE_FORMAT, _ro_ptrmap_start_pos);
st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent);
st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling);
st->print_cr("- has_full_module_graph %d", _has_full_module_graph);
@ -1580,7 +1582,7 @@ static size_t write_bitmap(const CHeapBitMap* map, char* output, size_t offset)
// lots of leading zeros.
size_t FileMapInfo::remove_bitmap_leading_zeros(CHeapBitMap* map) {
size_t old_zeros = map->find_first_set_bit(0);
size_t old_size = map->size_in_bytes();
size_t old_size = map->size();
// Slice and resize bitmap
map->truncate(old_zeros, map->size());
@ -1589,13 +1591,16 @@ size_t FileMapInfo::remove_bitmap_leading_zeros(CHeapBitMap* map) {
size_t new_zeros = map->find_first_set_bit(0);
assert(new_zeros == 0, "Should have removed leading zeros");
)
assert(map->size_in_bytes() < old_size, "Map size should have decreased");
assert(map->size() <= old_size, "sanity");
return old_zeros;
}
char* FileMapInfo::write_bitmap_region(const CHeapBitMap* rw_ptrmap, const CHeapBitMap* ro_ptrmap, ArchiveHeapInfo* heap_info,
char* FileMapInfo::write_bitmap_region(CHeapBitMap* rw_ptrmap, CHeapBitMap* ro_ptrmap, ArchiveHeapInfo* heap_info,
size_t &size_in_bytes) {
size_t removed_rw_zeros = remove_bitmap_leading_zeros(rw_ptrmap);
size_t removed_ro_zeros = remove_bitmap_leading_zeros(ro_ptrmap);
header()->set_rw_ptrmap_start_pos(removed_rw_zeros);
header()->set_ro_ptrmap_start_pos(removed_ro_zeros);
size_in_bytes = rw_ptrmap->size_in_bytes() + ro_ptrmap->size_in_bytes();
if (heap_info->is_used()) {
@ -1942,9 +1947,9 @@ bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) {
address valid_new_base = (address)header()->mapped_base_address();
address valid_new_end = (address)mapped_end();
SharedDataRelocator rw_patcher((address*)rw_patch_base, (address*)rw_patch_end, valid_old_base, valid_old_end,
SharedDataRelocator rw_patcher((address*)rw_patch_base + header()->rw_ptrmap_start_pos(), (address*)rw_patch_end, valid_old_base, valid_old_end,
valid_new_base, valid_new_end, addr_delta);
SharedDataRelocator ro_patcher((address*)ro_patch_base, (address*)ro_patch_end, valid_old_base, valid_old_end,
SharedDataRelocator ro_patcher((address*)ro_patch_base + header()->ro_ptrmap_start_pos(), (address*)ro_patch_end, valid_old_base, valid_old_end,
valid_new_base, valid_new_end, addr_delta);
rw_ptrmap.iterate(&rw_patcher);
ro_ptrmap.iterate(&ro_patcher);

View File

@ -229,6 +229,8 @@ private:
// of the archived heap objects, in bytes.
size_t _heap_oopmap_start_pos; // The first bit in the oopmap corresponds to this position in the heap.
size_t _heap_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap.
size_t _rw_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the rw region
size_t _ro_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the ro region
char* from_mapped_offset(size_t offset) const {
return mapped_base_address() + offset;
}
@ -269,8 +271,10 @@ public:
bool compressed_oops() const { return _compressed_oops; }
bool compressed_class_pointers() const { return _compressed_class_ptrs; }
size_t heap_roots_offset() const { return _heap_roots_offset; }
size_t heap_oopmap_start_pos() const { return _heap_oopmap_start_pos;}
size_t heap_ptrmap_start_pos() const { return _heap_ptrmap_start_pos;}
size_t heap_oopmap_start_pos() const { return _heap_oopmap_start_pos; }
size_t heap_ptrmap_start_pos() const { return _heap_ptrmap_start_pos; }
size_t rw_ptrmap_start_pos() const { return _rw_ptrmap_start_pos; }
size_t ro_ptrmap_start_pos() const { return _ro_ptrmap_start_pos; }
// FIXME: These should really return int
jshort max_used_path_index() const { return _max_used_path_index; }
jshort app_module_paths_start_index() const { return _app_module_paths_start_index; }
@ -284,6 +288,8 @@ public:
void set_heap_roots_offset(size_t n) { _heap_roots_offset = n; }
void set_heap_oopmap_start_pos(size_t n) { _heap_oopmap_start_pos = n; }
void set_heap_ptrmap_start_pos(size_t n) { _heap_ptrmap_start_pos = n; }
void set_rw_ptrmap_start_pos(size_t n) { _rw_ptrmap_start_pos = n; }
void set_ro_ptrmap_start_pos(size_t n) { _ro_ptrmap_start_pos = n; }
void copy_base_archive_name(const char* name);
void set_shared_path_table(SharedPathTable table) {
@ -440,7 +446,7 @@ public:
void write_region(int region, char* base, size_t size,
bool read_only, bool allow_exec);
size_t remove_bitmap_leading_zeros(CHeapBitMap* map);
char* write_bitmap_region(const CHeapBitMap* rw_ptrmap, const CHeapBitMap* ro_ptrmap, ArchiveHeapInfo* heap_info,
char* write_bitmap_region(CHeapBitMap* rw_ptrmap, CHeapBitMap* ro_ptrmap, ArchiveHeapInfo* heap_info,
size_t &size_in_bytes);
size_t write_heap_region(ArchiveHeapInfo* heap_info);
void write_bytes(const void* buffer, size_t count);

View File

@ -513,6 +513,7 @@ void VM_PopulateDumpSharedSpace::doit() {
char* cloned_vtables = CppVtables::dumptime_init(&builder);
builder.sort_metadata_objs();
builder.dump_rw_metadata();
builder.dump_ro_metadata();
builder.relocate_metaspaceobj_embedded_pointers();