8329417: Remove objects with no pointers from relocation bitmap
Reviewed-by: ccheung, iklam
This commit is contained in:
parent
383fe6eaab
commit
b6518a5db0
@ -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 ... ");
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user