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) { void ArchiveBuilder::SourceObjList::append(SourceObjInfo* src_info) {
// Save this source object for copying // Save this source object for copying
src_info->set_id(_objs->length());
_objs->append(src_info); _objs->append(src_info);
// Prepare for marking the pointers in this source object // 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) { 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, // src_obj contains a pointer. Remember the location of this pointer in _ptrmap,
// so that we can copy/relocate it later. // so that we can copy/relocate it later.
src_info->set_has_embedded_pointer();
address src_obj = src_info->source_addr(); address src_obj = src_info->source_addr();
address* field_addr = ref->addr(); address* field_addr = ref->addr();
assert(src_info->ptrmap_start() < _total_bytes, "sanity"); assert(src_info->ptrmap_start() < _total_bytes, "sanity");
@ -589,6 +591,26 @@ char* ArchiveBuilder::ro_strdup(const char* s) {
return archived_str; 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() { void ArchiveBuilder::dump_rw_metadata() {
ResourceMark rm; ResourceMark rm;
log_info(cds)("Allocating RW objects ... "); 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_start; // The bit-offset of the start of this object (inclusive)
uintx _ptrmap_end; // The bit-offset of the end of this object (exclusive) uintx _ptrmap_end; // The bit-offset of the end of this object (exclusive)
bool _read_only; bool _read_only;
bool _has_embedded_pointer;
FollowMode _follow_mode; FollowMode _follow_mode;
int _size_in_bytes; 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; MetaspaceObj::Type _msotype;
address _source_addr; // The source object to be copied. address _source_addr; // The source object to be copied.
address _buffered_addr; // The copy of this object insider the buffer. address _buffered_addr; // The copy of this object insider the buffer.
public: public:
SourceObjInfo(MetaspaceClosure::Ref* ref, bool read_only, FollowMode follow_mode) : SourceObjInfo(MetaspaceClosure::Ref* ref, bool read_only, FollowMode follow_mode) :
_ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _follow_mode(follow_mode), _ptrmap_start(0), _ptrmap_end(0), _read_only(read_only), _has_embedded_pointer(false), _follow_mode(follow_mode),
_size_in_bytes(ref->size() * BytesPerWord), _msotype(ref->msotype()), _size_in_bytes(ref->size() * BytesPerWord), _id(0), _msotype(ref->msotype()),
_source_addr(ref->obj()) { _source_addr(ref->obj()) {
if (follow_mode == point_to_it) { if (follow_mode == point_to_it) {
_buffered_addr = ref->obj(); _buffered_addr = ref->obj();
@ -164,7 +167,11 @@ private:
uintx ptrmap_start() const { return _ptrmap_start; } // inclusive uintx ptrmap_start() const { return _ptrmap_start; } // inclusive
uintx ptrmap_end() const { return _ptrmap_end; } // exclusive uintx ptrmap_end() const { return _ptrmap_end; } // exclusive
bool read_only() const { return _read_only; } 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 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 source_addr() const { return _source_addr; }
address buffered_addr() const { address buffered_addr() const {
if (_follow_mode != set_to_null) { if (_follow_mode != set_to_null) {
@ -384,6 +391,8 @@ public:
char* ro_strdup(const char* s); 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_rw_metadata();
void dump_ro_metadata(); void dump_ro_metadata();
void relocate_metaspaceobj_embedded_pointers(); 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_roots_offset: " SIZE_FORMAT, _heap_roots_offset);
st->print_cr("- _heap_oopmap_start_pos: " SIZE_FORMAT, _heap_oopmap_start_pos); 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("- _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("- 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("- use_optimized_module_handling: %d", _use_optimized_module_handling);
st->print_cr("- has_full_module_graph %d", _has_full_module_graph); 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. // lots of leading zeros.
size_t FileMapInfo::remove_bitmap_leading_zeros(CHeapBitMap* map) { size_t FileMapInfo::remove_bitmap_leading_zeros(CHeapBitMap* map) {
size_t old_zeros = map->find_first_set_bit(0); 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 // Slice and resize bitmap
map->truncate(old_zeros, map->size()); 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); size_t new_zeros = map->find_first_set_bit(0);
assert(new_zeros == 0, "Should have removed leading zeros"); assert(new_zeros == 0, "Should have removed leading zeros");
) )
assert(map->size() <= old_size, "sanity");
assert(map->size_in_bytes() < old_size, "Map size should have decreased");
return old_zeros; 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 &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(); size_in_bytes = rw_ptrmap->size_in_bytes() + ro_ptrmap->size_in_bytes();
if (heap_info->is_used()) { 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_base = (address)header()->mapped_base_address();
address valid_new_end = (address)mapped_end(); 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); 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); valid_new_base, valid_new_end, addr_delta);
rw_ptrmap.iterate(&rw_patcher); rw_ptrmap.iterate(&rw_patcher);
ro_ptrmap.iterate(&ro_patcher); ro_ptrmap.iterate(&ro_patcher);

View File

@ -229,6 +229,8 @@ private:
// of the archived heap objects, in bytes. // 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_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 _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 { char* from_mapped_offset(size_t offset) const {
return mapped_base_address() + offset; return mapped_base_address() + offset;
} }
@ -269,8 +271,10 @@ public:
bool compressed_oops() const { return _compressed_oops; } bool compressed_oops() const { return _compressed_oops; }
bool compressed_class_pointers() const { return _compressed_class_ptrs; } bool compressed_class_pointers() const { return _compressed_class_ptrs; }
size_t heap_roots_offset() const { return _heap_roots_offset; } 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_oopmap_start_pos() const { return _heap_oopmap_start_pos; }
size_t heap_ptrmap_start_pos() const { return _heap_ptrmap_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 // FIXME: These should really return int
jshort max_used_path_index() const { return _max_used_path_index; } jshort max_used_path_index() const { return _max_used_path_index; }
jshort app_module_paths_start_index() const { return _app_module_paths_start_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_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_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_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 copy_base_archive_name(const char* name);
void set_shared_path_table(SharedPathTable table) { void set_shared_path_table(SharedPathTable table) {
@ -440,7 +446,7 @@ public:
void write_region(int region, char* base, size_t size, void write_region(int region, char* base, size_t size,
bool read_only, bool allow_exec); bool read_only, bool allow_exec);
size_t remove_bitmap_leading_zeros(CHeapBitMap* map); 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 &size_in_bytes);
size_t write_heap_region(ArchiveHeapInfo* heap_info); size_t write_heap_region(ArchiveHeapInfo* heap_info);
void write_bytes(const void* buffer, size_t count); 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); char* cloned_vtables = CppVtables::dumptime_init(&builder);
builder.sort_metadata_objs();
builder.dump_rw_metadata(); builder.dump_rw_metadata();
builder.dump_ro_metadata(); builder.dump_ro_metadata();
builder.relocate_metaspaceobj_embedded_pointers(); builder.relocate_metaspaceobj_embedded_pointers();