mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-22 12:51:01 +00:00
8377096: Refactor AOTMapLogger::OopDataIterator implementations
Reviewed-by: eosterlund, kvn
This commit is contained in:
parent
21d4c6c68f
commit
7bc2475962
@ -88,7 +88,7 @@ void AOTMapLogger::ergo_initialize() {
|
||||
}
|
||||
|
||||
void AOTMapLogger::dumptime_log(ArchiveBuilder* builder, FileMapInfo* mapinfo,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info, ArchiveStreamedHeapInfo* streamed_heap_info,
|
||||
AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info,
|
||||
char* bitmap, size_t bitmap_size_in_bytes) {
|
||||
_is_runtime_logging = false;
|
||||
_buffer_to_requested_delta = ArchiveBuilder::current()->buffer_to_requested_delta();
|
||||
@ -823,7 +823,7 @@ public:
|
||||
}
|
||||
}; // AOTMapLogger::ArchivedFieldPrinter
|
||||
|
||||
void AOTMapLogger::dumptime_log_mapped_heap_region(ArchiveMappedHeapInfo* heap_info) {
|
||||
void AOTMapLogger::dumptime_log_mapped_heap_region(AOTMappedHeapInfo* heap_info) {
|
||||
MemRegion r = heap_info->buffer_region();
|
||||
address buffer_start = address(r.start()); // start of the current oop inside the buffer
|
||||
address buffer_end = address(r.end());
|
||||
@ -835,7 +835,7 @@ void AOTMapLogger::dumptime_log_mapped_heap_region(ArchiveMappedHeapInfo* heap_i
|
||||
log_archived_objects(AOTMappedHeapWriter::oop_iterator(heap_info));
|
||||
}
|
||||
|
||||
void AOTMapLogger::dumptime_log_streamed_heap_region(ArchiveStreamedHeapInfo* heap_info) {
|
||||
void AOTMapLogger::dumptime_log_streamed_heap_region(AOTStreamedHeapInfo* heap_info) {
|
||||
MemRegion r = heap_info->buffer_region();
|
||||
address buffer_start = address(r.start()); // start of the current oop inside the buffer
|
||||
address buffer_end = address(r.end());
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
class ArchiveMappedHeapInfo;
|
||||
class ArchiveStreamedHeapInfo;
|
||||
class AOTMappedHeapInfo;
|
||||
class AOTStreamedHeapInfo;
|
||||
class CompileTrainingData;
|
||||
class DumpRegion;
|
||||
class FileMapInfo;
|
||||
@ -157,8 +157,8 @@ private:
|
||||
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
static void dumptime_log_mapped_heap_region(ArchiveMappedHeapInfo* mapped_heap_info);
|
||||
static void dumptime_log_streamed_heap_region(ArchiveStreamedHeapInfo* streamed_heap_info);
|
||||
static void dumptime_log_mapped_heap_region(AOTMappedHeapInfo* mapped_heap_info);
|
||||
static void dumptime_log_streamed_heap_region(AOTStreamedHeapInfo* streamed_heap_info);
|
||||
static void runtime_log_heap_region(FileMapInfo* mapinfo);
|
||||
|
||||
static void print_oop_info_cr(outputStream* st, FakeOop fake_oop, bool print_location = true);
|
||||
@ -173,7 +173,7 @@ public:
|
||||
static bool is_logging_at_bootstrap() { return _is_logging_at_bootstrap; }
|
||||
|
||||
static void dumptime_log(ArchiveBuilder* builder, FileMapInfo* mapinfo,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info, ArchiveStreamedHeapInfo* streamed_heap_info,
|
||||
AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info,
|
||||
char* bitmap, size_t bitmap_size_in_bytes);
|
||||
static void runtime_log(FileMapInfo* static_mapinfo, FileMapInfo* dynamic_mapinfo);
|
||||
};
|
||||
|
||||
49
src/hotspot/share/cds/aotMappedHeap.cpp
Normal file
49
src/hotspot/share/cds/aotMappedHeap.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cds/aotMappedHeap.hpp"
|
||||
|
||||
// Anything that goes in the header must be thoroughly purged from uninitialized memory
|
||||
// as it will be written to disk. Therefore, the constructors memset the memory to 0.
|
||||
// This is not the prettiest thing, but we need to know every byte is initialized,
|
||||
// including potential padding between fields.
|
||||
|
||||
AOTMappedHeapHeader::AOTMappedHeapHeader(size_t ptrmap_start_pos,
|
||||
size_t oopmap_start_pos,
|
||||
HeapRootSegments root_segments) {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
_ptrmap_start_pos = ptrmap_start_pos;
|
||||
_oopmap_start_pos = oopmap_start_pos;
|
||||
_root_segments = root_segments;
|
||||
}
|
||||
|
||||
AOTMappedHeapHeader::AOTMappedHeapHeader() {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
AOTMappedHeapHeader AOTMappedHeapInfo::create_header() {
|
||||
return AOTMappedHeapHeader{_ptrmap_start_pos,
|
||||
_oopmap_start_pos,
|
||||
_root_segments};
|
||||
}
|
||||
168
src/hotspot/share/cds/aotMappedHeap.hpp
Normal file
168
src/hotspot/share/cds/aotMappedHeap.hpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_CDS_AOTMAPPEDHEAP_HPP
|
||||
#define SHARE_CDS_AOTMAPPEDHEAP_HPP
|
||||
|
||||
#include "cds/aotMapLogger.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class AOTMappedHeapHeader {
|
||||
size_t _ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap.
|
||||
size_t _oopmap_start_pos; // The first bit in the oopmap corresponds to this position in the heap.
|
||||
HeapRootSegments _root_segments; // Heap root segments info
|
||||
|
||||
public:
|
||||
AOTMappedHeapHeader();
|
||||
AOTMappedHeapHeader(size_t ptrmap_start_pos,
|
||||
size_t oopmap_start_pos,
|
||||
HeapRootSegments root_segments);
|
||||
|
||||
size_t ptrmap_start_pos() const { return _ptrmap_start_pos; }
|
||||
size_t oopmap_start_pos() const { return _oopmap_start_pos; }
|
||||
HeapRootSegments root_segments() const { return _root_segments; }
|
||||
|
||||
// This class is trivially copyable and assignable.
|
||||
AOTMappedHeapHeader(const AOTMappedHeapHeader&) = default;
|
||||
AOTMappedHeapHeader& operator=(const AOTMappedHeapHeader&) = default;
|
||||
};
|
||||
|
||||
class AOTMappedHeapInfo {
|
||||
MemRegion _buffer_region; // Contains the archived objects to be written into the CDS archive.
|
||||
CHeapBitMap _oopmap;
|
||||
CHeapBitMap _ptrmap;
|
||||
HeapRootSegments _root_segments;
|
||||
size_t _oopmap_start_pos; // How many zeros were removed from the beginning of the bit map?
|
||||
size_t _ptrmap_start_pos; // How many zeros were removed from the beginning of the bit map?
|
||||
|
||||
public:
|
||||
AOTMappedHeapInfo() :
|
||||
_buffer_region(),
|
||||
_oopmap(128, mtClassShared),
|
||||
_ptrmap(128, mtClassShared),
|
||||
_root_segments(),
|
||||
_oopmap_start_pos(),
|
||||
_ptrmap_start_pos() {}
|
||||
bool is_used() { return !_buffer_region.is_empty(); }
|
||||
|
||||
MemRegion buffer_region() { return _buffer_region; }
|
||||
void set_buffer_region(MemRegion r) { _buffer_region = r; }
|
||||
|
||||
char* buffer_start() { return (char*)_buffer_region.start(); }
|
||||
size_t buffer_byte_size() { return _buffer_region.byte_size(); }
|
||||
|
||||
CHeapBitMap* oopmap() { return &_oopmap; }
|
||||
CHeapBitMap* ptrmap() { return &_ptrmap; }
|
||||
|
||||
void set_oopmap_start_pos(size_t start_pos) { _oopmap_start_pos = start_pos; }
|
||||
void set_ptrmap_start_pos(size_t start_pos) { _ptrmap_start_pos = start_pos; }
|
||||
|
||||
void set_root_segments(HeapRootSegments segments) { _root_segments = segments; };
|
||||
HeapRootSegments root_segments() { return _root_segments; }
|
||||
|
||||
AOTMappedHeapHeader create_header();
|
||||
};
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
class AOTMappedHeapOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
protected:
|
||||
address _current;
|
||||
address _next;
|
||||
|
||||
address _buffer_start;
|
||||
address _buffer_end;
|
||||
uint64_t _buffer_start_narrow_oop;
|
||||
intptr_t _buffer_to_requested_delta;
|
||||
int _requested_shift;
|
||||
|
||||
size_t _num_root_segments;
|
||||
size_t _num_obj_arrays_logged;
|
||||
|
||||
public:
|
||||
AOTMappedHeapOopIterator(address buffer_start,
|
||||
address buffer_end,
|
||||
address requested_base,
|
||||
address requested_start,
|
||||
int requested_shift,
|
||||
size_t num_root_segments)
|
||||
: _current(nullptr),
|
||||
_next(buffer_start),
|
||||
_buffer_start(buffer_start),
|
||||
_buffer_end(buffer_end),
|
||||
_requested_shift(requested_shift),
|
||||
_num_root_segments(num_root_segments),
|
||||
_num_obj_arrays_logged(0) {
|
||||
_buffer_to_requested_delta = requested_start - buffer_start;
|
||||
_buffer_start_narrow_oop = 0xdeadbeed;
|
||||
if (UseCompressedOops) {
|
||||
_buffer_start_narrow_oop = (uint64_t)(pointer_delta(requested_start, requested_base, 1)) >> requested_shift;
|
||||
assert(_buffer_start_narrow_oop < 0xffffffff, "sanity");
|
||||
}
|
||||
}
|
||||
|
||||
virtual AOTMapLogger::OopData capture(address buffered_addr) = 0;
|
||||
|
||||
bool has_next() override {
|
||||
return _next < _buffer_end;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
if (result._klass->is_objArray_klass()) {
|
||||
result._is_root_segment = _num_obj_arrays_logged++ < _num_root_segments;
|
||||
}
|
||||
_next = _current + result._size * BytesPerWord;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
uint64_t n = (uint64_t)(*addr);
|
||||
if (n == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
precond(n >= _buffer_start_narrow_oop);
|
||||
address buffer_addr = _buffer_start + ((n - _buffer_start_narrow_oop) << _requested_shift);
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
address requested_value = cast_from_oop<address>(*addr);
|
||||
if (requested_value == nullptr) {
|
||||
return null_data();
|
||||
} else {
|
||||
address buffer_addr = requested_value - _buffer_to_requested_delta;
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* roots() override {
|
||||
return new GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>();
|
||||
}
|
||||
};
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
#endif // SHARE_CDS_AOTMAPPEDHEAP_HPP
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "cds/aotLogging.hpp"
|
||||
#include "cds/aotMappedHeap.hpp"
|
||||
#include "cds/aotMappedHeapLoader.inline.hpp"
|
||||
#include "cds/aotMappedHeapWriter.hpp"
|
||||
#include "cds/aotMetaspace.hpp"
|
||||
@ -221,7 +222,7 @@ void AOTMappedHeapLoader::patch_embedded_pointers(FileMapInfo* info,
|
||||
// the heap object may be loaded at a different address at run time. This structure is used
|
||||
// to translate the dump time addresses for all objects in FileMapInfo::space_at(region_index)
|
||||
// to their runtime addresses.
|
||||
struct LoadedArchiveHeapRegion {
|
||||
struct AOTMappedHeapRegion {
|
||||
int _region_index; // index for FileMapInfo::space_at(index)
|
||||
size_t _region_size; // number of bytes in this region
|
||||
uintptr_t _dumptime_base; // The dump-time (decoded) address of the first object in this region
|
||||
@ -232,7 +233,7 @@ struct LoadedArchiveHeapRegion {
|
||||
}
|
||||
};
|
||||
|
||||
void AOTMappedHeapLoader::init_loaded_heap_relocation(LoadedArchiveHeapRegion* loaded_region) {
|
||||
void AOTMappedHeapLoader::init_loaded_heap_relocation(AOTMappedHeapRegion* loaded_region) {
|
||||
_dumptime_base = loaded_region->_dumptime_base;
|
||||
_dumptime_top = loaded_region->top();
|
||||
_runtime_offset = loaded_region->_runtime_offset;
|
||||
@ -249,7 +250,7 @@ class AOTMappedHeapLoader::PatchLoadedRegionPointers: public BitMapClosure {
|
||||
uintptr_t _top;
|
||||
|
||||
public:
|
||||
PatchLoadedRegionPointers(narrowOop* start, LoadedArchiveHeapRegion* loaded_region)
|
||||
PatchLoadedRegionPointers(narrowOop* start, AOTMappedHeapRegion* loaded_region)
|
||||
: _start(start),
|
||||
_offset(loaded_region->_runtime_offset),
|
||||
_base(loaded_region->_dumptime_base),
|
||||
@ -270,7 +271,7 @@ class AOTMappedHeapLoader::PatchLoadedRegionPointers: public BitMapClosure {
|
||||
}
|
||||
};
|
||||
|
||||
bool AOTMappedHeapLoader::init_loaded_region(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region,
|
||||
bool AOTMappedHeapLoader::init_loaded_region(FileMapInfo* mapinfo, AOTMappedHeapRegion* loaded_region,
|
||||
MemRegion& archive_space) {
|
||||
size_t total_bytes = 0;
|
||||
FileMapRegion* r = mapinfo->region_at(AOTMetaspace::hp);
|
||||
@ -301,7 +302,7 @@ bool AOTMappedHeapLoader::init_loaded_region(FileMapInfo* mapinfo, LoadedArchive
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AOTMappedHeapLoader::load_heap_region_impl(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region,
|
||||
bool AOTMappedHeapLoader::load_heap_region_impl(FileMapInfo* mapinfo, AOTMappedHeapRegion* loaded_region,
|
||||
uintptr_t load_address) {
|
||||
uintptr_t bitmap_base = (uintptr_t)mapinfo->map_bitmap_region();
|
||||
if (bitmap_base == 0) {
|
||||
@ -340,7 +341,7 @@ bool AOTMappedHeapLoader::load_heap_region(FileMapInfo* mapinfo) {
|
||||
assert(can_load(), "loaded heap for must be supported");
|
||||
init_narrow_oop_decoding(mapinfo->narrow_oop_base(), mapinfo->narrow_oop_shift());
|
||||
|
||||
LoadedArchiveHeapRegion loaded_region;
|
||||
AOTMappedHeapRegion loaded_region;
|
||||
memset(&loaded_region, 0, sizeof(loaded_region));
|
||||
|
||||
MemRegion archive_space;
|
||||
@ -733,40 +734,22 @@ void AOTMappedHeapLoader::dealloc_heap_region(FileMapInfo* info) {
|
||||
}
|
||||
|
||||
AOTMapLogger::OopDataIterator* AOTMappedHeapLoader::oop_iterator(FileMapInfo* info, address buffer_start, address buffer_end) {
|
||||
class MappedLoaderOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
private:
|
||||
address _current;
|
||||
address _next;
|
||||
|
||||
address _buffer_start;
|
||||
address _buffer_end;
|
||||
uint64_t _buffer_start_narrow_oop;
|
||||
intptr_t _buffer_to_requested_delta;
|
||||
int _requested_shift;
|
||||
|
||||
size_t _num_root_segments;
|
||||
size_t _num_obj_arrays_logged;
|
||||
|
||||
class MappedLoaderOopIterator : public AOTMappedHeapOopIterator {
|
||||
public:
|
||||
MappedLoaderOopIterator(address buffer_start,
|
||||
address buffer_end,
|
||||
uint64_t buffer_start_narrow_oop,
|
||||
intptr_t buffer_to_requested_delta,
|
||||
address requested_base,
|
||||
address requested_start,
|
||||
int requested_shift,
|
||||
size_t num_root_segments)
|
||||
: _current(nullptr),
|
||||
_next(buffer_start),
|
||||
_buffer_start(buffer_start),
|
||||
_buffer_end(buffer_end),
|
||||
_buffer_start_narrow_oop(buffer_start_narrow_oop),
|
||||
_buffer_to_requested_delta(buffer_to_requested_delta),
|
||||
_requested_shift(requested_shift),
|
||||
_num_root_segments(num_root_segments),
|
||||
_num_obj_arrays_logged(0) {
|
||||
}
|
||||
size_t num_root_segments) :
|
||||
AOTMappedHeapOopIterator(buffer_start,
|
||||
buffer_end,
|
||||
requested_base,
|
||||
requested_start,
|
||||
requested_shift,
|
||||
num_root_segments) {}
|
||||
|
||||
|
||||
AOTMapLogger::OopData capture(address buffered_addr) {
|
||||
AOTMapLogger::OopData capture(address buffered_addr) override {
|
||||
oopDesc* raw_oop = (oopDesc*)buffered_addr;
|
||||
size_t size = raw_oop->size();
|
||||
address requested_addr = buffered_addr + _buffer_to_requested_delta;
|
||||
@ -784,62 +767,17 @@ AOTMapLogger::OopDataIterator* AOTMappedHeapLoader::oop_iterator(FileMapInfo* in
|
||||
size,
|
||||
false };
|
||||
}
|
||||
|
||||
bool has_next() override {
|
||||
return _next < _buffer_end;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
if (result._klass->is_objArray_klass()) {
|
||||
result._is_root_segment = _num_obj_arrays_logged++ < _num_root_segments;
|
||||
}
|
||||
_next = _current + result._size * BytesPerWord;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
uint64_t n = (uint64_t)(*addr);
|
||||
if (n == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
precond(n >= _buffer_start_narrow_oop);
|
||||
address buffer_addr = _buffer_start + ((n - _buffer_start_narrow_oop) << _requested_shift);
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
address requested_value = cast_from_oop<address>(*addr);
|
||||
if (requested_value == nullptr) {
|
||||
return null_data();
|
||||
} else {
|
||||
address buffer_addr = requested_value - _buffer_to_requested_delta;
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* roots() override {
|
||||
return new GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>();
|
||||
}
|
||||
};
|
||||
|
||||
FileMapRegion* r = info->region_at(AOTMetaspace::hp);
|
||||
address requested_base = UseCompressedOops ? (address)info->narrow_oop_base() : heap_region_requested_address(info);
|
||||
address requested_start = requested_base + r->mapping_offset();
|
||||
int requested_shift = info->narrow_oop_shift();
|
||||
intptr_t buffer_to_requested_delta = requested_start - buffer_start;
|
||||
uint64_t buffer_start_narrow_oop = 0xdeadbeed;
|
||||
if (UseCompressedOops) {
|
||||
buffer_start_narrow_oop = (uint64_t)(pointer_delta(requested_start, requested_base, 1)) >> requested_shift;
|
||||
assert(buffer_start_narrow_oop < 0xffffffff, "sanity");
|
||||
}
|
||||
|
||||
return new MappedLoaderOopIterator(buffer_start,
|
||||
buffer_end,
|
||||
buffer_start_narrow_oop,
|
||||
buffer_to_requested_delta,
|
||||
requested_base,
|
||||
requested_start,
|
||||
requested_shift,
|
||||
info->mapped_heap()->root_segments().count());
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,8 +37,8 @@
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
struct AOTMappedHeapRegion;
|
||||
class FileMapInfo;
|
||||
struct LoadedArchiveHeapRegion;
|
||||
|
||||
class AOTMappedHeapLoader : AllStatic {
|
||||
friend class AOTMapLogger;
|
||||
@ -93,7 +93,7 @@ public:
|
||||
// function instead.
|
||||
inline static oop decode_from_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(nullptr);
|
||||
|
||||
// More efficient version, but works only when ArchiveHeap is mapped.
|
||||
// More efficient version, but works only when is_mapped()
|
||||
inline static oop decode_from_mapped_archive(narrowOop v) NOT_CDS_JAVA_HEAP_RETURN_(nullptr);
|
||||
|
||||
static void patch_compressed_embedded_pointers(BitMapView bm,
|
||||
@ -113,7 +113,7 @@ private:
|
||||
static bool _is_loaded;
|
||||
|
||||
// Support for loaded archived heap. These are cached values from
|
||||
// LoadedArchiveHeapRegion's.
|
||||
// AOTMappedHeapRegion's.
|
||||
static uintptr_t _dumptime_base;
|
||||
static uintptr_t _dumptime_top;
|
||||
static intx _runtime_offset;
|
||||
@ -141,10 +141,10 @@ private:
|
||||
static bool _heap_pointers_need_patching;
|
||||
|
||||
static void init_narrow_oop_decoding(address base, int shift);
|
||||
static bool init_loaded_region(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region,
|
||||
static bool init_loaded_region(FileMapInfo* mapinfo, AOTMappedHeapRegion* loaded_region,
|
||||
MemRegion& archive_space);
|
||||
static bool load_heap_region_impl(FileMapInfo* mapinfo, LoadedArchiveHeapRegion* loaded_region, uintptr_t buffer);
|
||||
static void init_loaded_heap_relocation(LoadedArchiveHeapRegion* reloc_info);
|
||||
static bool load_heap_region_impl(FileMapInfo* mapinfo, AOTMappedHeapRegion* loaded_region, uintptr_t buffer);
|
||||
static void init_loaded_heap_relocation(AOTMappedHeapRegion* reloc_info);
|
||||
static void patch_native_pointers();
|
||||
static void finish_loaded_heap();
|
||||
static void verify_loaded_heap();
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cds/aotMappedHeapLoader.hpp"
|
||||
#include "cds/aotMappedHeap.hpp"
|
||||
#include "cds/aotMappedHeapWriter.hpp"
|
||||
#include "cds/aotReferenceObjSupport.hpp"
|
||||
#include "cds/cdsConfig.hpp"
|
||||
@ -151,7 +151,7 @@ void AOTMappedHeapWriter::add_source_obj(oop src_obj) {
|
||||
}
|
||||
|
||||
void AOTMappedHeapWriter::write(GrowableArrayCHeap<oop, mtClassShared>* roots,
|
||||
ArchiveMappedHeapInfo* heap_info) {
|
||||
AOTMappedHeapInfo* heap_info) {
|
||||
assert(CDSConfig::is_dumping_heap(), "sanity");
|
||||
allocate_buffer();
|
||||
copy_source_objs_to_buffer(roots);
|
||||
@ -598,7 +598,7 @@ size_t AOTMappedHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) {
|
||||
//
|
||||
// So we just hard code it to NOCOOPS_REQUESTED_BASE.
|
||||
//
|
||||
void AOTMappedHeapWriter::set_requested_address_range(ArchiveMappedHeapInfo* info) {
|
||||
void AOTMappedHeapWriter::set_requested_address_range(AOTMappedHeapInfo* info) {
|
||||
assert(!info->is_used(), "only set once");
|
||||
|
||||
size_t heap_region_byte_size = _buffer_used;
|
||||
@ -792,7 +792,7 @@ static void log_bitmap_usage(const char* which, BitMap* bitmap, size_t total_bit
|
||||
|
||||
// Update all oop fields embedded in the buffered objects
|
||||
void AOTMappedHeapWriter::relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassShared>* roots,
|
||||
ArchiveMappedHeapInfo* heap_info) {
|
||||
AOTMappedHeapInfo* heap_info) {
|
||||
size_t oopmap_unit = (UseCompressedOops ? sizeof(narrowOop) : sizeof(oop));
|
||||
size_t heap_region_byte_size = _buffer_used;
|
||||
heap_info->oopmap()->resize(heap_region_byte_size / oopmap_unit);
|
||||
@ -862,7 +862,7 @@ void AOTMappedHeapWriter::mark_native_pointers(oop orig_obj) {
|
||||
});
|
||||
}
|
||||
|
||||
void AOTMappedHeapWriter::compute_ptrmap(ArchiveMappedHeapInfo* heap_info) {
|
||||
void AOTMappedHeapWriter::compute_ptrmap(AOTMappedHeapInfo* heap_info) {
|
||||
int num_non_null_ptrs = 0;
|
||||
Metadata** bottom = (Metadata**) _requested_bottom;
|
||||
Metadata** top = (Metadata**) _requested_top; // exclusive
|
||||
@ -909,40 +909,23 @@ void AOTMappedHeapWriter::compute_ptrmap(ArchiveMappedHeapInfo* heap_info) {
|
||||
num_non_null_ptrs, size_t(heap_info->ptrmap()->size()));
|
||||
}
|
||||
|
||||
AOTMapLogger::OopDataIterator* AOTMappedHeapWriter::oop_iterator(ArchiveMappedHeapInfo* heap_info) {
|
||||
class MappedWriterOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
private:
|
||||
address _current;
|
||||
address _next;
|
||||
|
||||
address _buffer_start;
|
||||
address _buffer_end;
|
||||
uint64_t _buffer_start_narrow_oop;
|
||||
intptr_t _buffer_to_requested_delta;
|
||||
int _requested_shift;
|
||||
|
||||
size_t _num_root_segments;
|
||||
size_t _num_obj_arrays_logged;
|
||||
|
||||
AOTMapLogger::OopDataIterator* AOTMappedHeapWriter::oop_iterator(AOTMappedHeapInfo* heap_info) {
|
||||
class MappedWriterOopIterator : public AOTMappedHeapOopIterator {
|
||||
public:
|
||||
MappedWriterOopIterator(address buffer_start,
|
||||
address buffer_end,
|
||||
uint64_t buffer_start_narrow_oop,
|
||||
intptr_t buffer_to_requested_delta,
|
||||
address requested_base,
|
||||
address requested_start,
|
||||
int requested_shift,
|
||||
size_t num_root_segments)
|
||||
: _current(nullptr),
|
||||
_next(buffer_start),
|
||||
_buffer_start(buffer_start),
|
||||
_buffer_end(buffer_end),
|
||||
_buffer_start_narrow_oop(buffer_start_narrow_oop),
|
||||
_buffer_to_requested_delta(buffer_to_requested_delta),
|
||||
_requested_shift(requested_shift),
|
||||
_num_root_segments(num_root_segments),
|
||||
_num_obj_arrays_logged(0) {
|
||||
}
|
||||
size_t num_root_segments) :
|
||||
AOTMappedHeapOopIterator(buffer_start,
|
||||
buffer_end,
|
||||
requested_base,
|
||||
requested_start,
|
||||
requested_shift,
|
||||
num_root_segments) {}
|
||||
|
||||
AOTMapLogger::OopData capture(address buffered_addr) {
|
||||
AOTMapLogger::OopData capture(address buffered_addr) override {
|
||||
oopDesc* raw_oop = (oopDesc*)buffered_addr;
|
||||
size_t size = size_of_buffered_oop(buffered_addr);
|
||||
address requested_addr = buffered_addr_to_requested_addr(buffered_addr);
|
||||
@ -960,45 +943,6 @@ AOTMapLogger::OopDataIterator* AOTMappedHeapWriter::oop_iterator(ArchiveMappedHe
|
||||
size,
|
||||
false };
|
||||
}
|
||||
|
||||
bool has_next() override {
|
||||
return _next < _buffer_end;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
if (result._klass->is_objArray_klass()) {
|
||||
result._is_root_segment = _num_obj_arrays_logged++ < _num_root_segments;
|
||||
}
|
||||
_next = _current + result._size * BytesPerWord;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
uint64_t n = (uint64_t)(*addr);
|
||||
if (n == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
precond(n >= _buffer_start_narrow_oop);
|
||||
address buffer_addr = _buffer_start + ((n - _buffer_start_narrow_oop) << _requested_shift);
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
address requested_value = cast_from_oop<address>(*addr);
|
||||
if (requested_value == nullptr) {
|
||||
return null_data();
|
||||
} else {
|
||||
address buffer_addr = requested_value - _buffer_to_requested_delta;
|
||||
return capture(buffer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* roots() override {
|
||||
return new GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>();
|
||||
}
|
||||
};
|
||||
|
||||
MemRegion r = heap_info->buffer_region();
|
||||
@ -1008,17 +952,11 @@ AOTMapLogger::OopDataIterator* AOTMappedHeapWriter::oop_iterator(ArchiveMappedHe
|
||||
address requested_base = UseCompressedOops ? AOTMappedHeapWriter::narrow_oop_base() : (address)AOTMappedHeapWriter::NOCOOPS_REQUESTED_BASE;
|
||||
address requested_start = UseCompressedOops ? AOTMappedHeapWriter::buffered_addr_to_requested_addr(buffer_start) : requested_base;
|
||||
int requested_shift = AOTMappedHeapWriter::narrow_oop_shift();
|
||||
intptr_t buffer_to_requested_delta = requested_start - buffer_start;
|
||||
uint64_t buffer_start_narrow_oop = 0xdeadbeed;
|
||||
if (UseCompressedOops) {
|
||||
buffer_start_narrow_oop = (uint64_t)(pointer_delta(requested_start, requested_base, 1)) >> requested_shift;
|
||||
assert(buffer_start_narrow_oop < 0xffffffff, "sanity");
|
||||
}
|
||||
|
||||
return new MappedWriterOopIterator(buffer_start,
|
||||
buffer_end,
|
||||
buffer_start_narrow_oop,
|
||||
buffer_to_requested_delta,
|
||||
requested_base,
|
||||
requested_start,
|
||||
requested_shift,
|
||||
heap_info->root_segments().count());
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -196,10 +196,10 @@ private:
|
||||
static int filler_array_length(size_t fill_bytes);
|
||||
static HeapWord* init_filler_array_at_buffer_top(int array_length, size_t fill_bytes);
|
||||
|
||||
static void set_requested_address_range(ArchiveMappedHeapInfo* info);
|
||||
static void set_requested_address_range(AOTMappedHeapInfo* info);
|
||||
static void mark_native_pointers(oop orig_obj);
|
||||
static void relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassShared>* roots, ArchiveMappedHeapInfo* info);
|
||||
static void compute_ptrmap(ArchiveMappedHeapInfo *info);
|
||||
static void relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassShared>* roots, AOTMappedHeapInfo* info);
|
||||
static void compute_ptrmap(AOTMappedHeapInfo *info);
|
||||
static bool is_in_requested_range(oop o);
|
||||
static oop requested_obj_from_buffer_offset(size_t offset);
|
||||
|
||||
@ -229,7 +229,7 @@ public:
|
||||
static bool is_string_too_large_to_archive(oop string);
|
||||
static bool is_dumped_interned_string(oop o);
|
||||
static void add_to_dumped_interned_strings(oop string);
|
||||
static void write(GrowableArrayCHeap<oop, mtClassShared>*, ArchiveMappedHeapInfo* heap_info);
|
||||
static void write(GrowableArrayCHeap<oop, mtClassShared>*, AOTMappedHeapInfo* heap_info);
|
||||
static address requested_address(); // requested address of the lowest achived heap object
|
||||
static size_t get_filler_size_at(address buffered_addr);
|
||||
|
||||
@ -240,7 +240,7 @@ public:
|
||||
static Klass* real_klass_of_buffered_oop(address buffered_addr);
|
||||
static size_t size_of_buffered_oop(address buffered_addr);
|
||||
|
||||
static AOTMapLogger::OopDataIterator* oop_iterator(ArchiveMappedHeapInfo* heap_info);
|
||||
static AOTMapLogger::OopDataIterator* oop_iterator(AOTMappedHeapInfo* heap_info);
|
||||
};
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
#endif // SHARE_CDS_AOTMAPPEDHEAPWRITER_HPP
|
||||
|
||||
@ -661,8 +661,8 @@ void AOTMetaspace::rewrite_bytecodes_and_calculate_fingerprints(Thread* thread,
|
||||
|
||||
class VM_PopulateDumpSharedSpace : public VM_Operation {
|
||||
private:
|
||||
ArchiveMappedHeapInfo _mapped_heap_info;
|
||||
ArchiveStreamedHeapInfo _streamed_heap_info;
|
||||
AOTMappedHeapInfo _mapped_heap_info;
|
||||
AOTStreamedHeapInfo _streamed_heap_info;
|
||||
FileMapInfo* _map_info;
|
||||
StaticArchiveBuilder& _builder;
|
||||
|
||||
@ -682,8 +682,8 @@ public:
|
||||
bool skip_operation() const { return false; }
|
||||
|
||||
VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
|
||||
ArchiveMappedHeapInfo* mapped_heap_info() { return &_mapped_heap_info; }
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info() { return &_streamed_heap_info; }
|
||||
AOTMappedHeapInfo* mapped_heap_info() { return &_mapped_heap_info; }
|
||||
AOTStreamedHeapInfo* streamed_heap_info() { return &_streamed_heap_info; }
|
||||
void doit(); // outline because gdb sucks
|
||||
bool allow_nested_vm_operations() const { return true; }
|
||||
}; // class VM_PopulateDumpSharedSpace
|
||||
@ -1212,8 +1212,8 @@ void AOTMetaspace::dump_static_archive_impl(StaticArchiveBuilder& builder, TRAPS
|
||||
|
||||
bool AOTMetaspace::write_static_archive(ArchiveBuilder* builder,
|
||||
FileMapInfo* map_info,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info) {
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info) {
|
||||
// relocate the data so that it can be mapped to AOTMetaspace::requested_base_address()
|
||||
// without runtime relocation.
|
||||
builder->relocate_to_requested();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,8 +33,8 @@
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class ArchiveBuilder;
|
||||
class ArchiveMappedHeapInfo;
|
||||
class ArchiveStreamedHeapInfo;
|
||||
class AOTMappedHeapInfo;
|
||||
class AOTStreamedHeapInfo;
|
||||
class FileMapInfo;
|
||||
class Method;
|
||||
class outputStream;
|
||||
@ -192,8 +192,8 @@ private:
|
||||
static void open_output_mapinfo();
|
||||
static bool write_static_archive(ArchiveBuilder* builder,
|
||||
FileMapInfo* map_info,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info);
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info);
|
||||
static FileMapInfo* open_static_archive();
|
||||
static FileMapInfo* open_dynamic_archive();
|
||||
// use_requested_addr: If true (default), attempt to map at the address the
|
||||
|
||||
55
src/hotspot/share/cds/aotStreamedHeap.cpp
Normal file
55
src/hotspot/share/cds/aotStreamedHeap.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cds/aotStreamedHeap.hpp"
|
||||
|
||||
// Anything that goes in the header must be thoroughly purged from uninitialized memory
|
||||
// as it will be written to disk. Therefore, the constructors memset the memory to 0.
|
||||
// This is not the prettiest thing, but we need to know every byte is initialized,
|
||||
// including potential padding between fields.
|
||||
|
||||
AOTStreamedHeapHeader::AOTStreamedHeapHeader(size_t forwarding_offset,
|
||||
size_t roots_offset,
|
||||
size_t num_roots,
|
||||
size_t root_highest_object_index_table_offset,
|
||||
size_t num_archived_objects) {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
_forwarding_offset = forwarding_offset;
|
||||
_roots_offset = roots_offset;
|
||||
_num_roots = num_roots;
|
||||
_root_highest_object_index_table_offset = root_highest_object_index_table_offset;
|
||||
_num_archived_objects = num_archived_objects;
|
||||
}
|
||||
|
||||
AOTStreamedHeapHeader::AOTStreamedHeapHeader() {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
AOTStreamedHeapHeader AOTStreamedHeapInfo::create_header() {
|
||||
return AOTStreamedHeapHeader{_forwarding_offset,
|
||||
_roots_offset,
|
||||
_num_roots,
|
||||
_root_highest_object_index_table_offset,
|
||||
_num_archived_objects};
|
||||
}
|
||||
147
src/hotspot/share/cds/aotStreamedHeap.hpp
Normal file
147
src/hotspot/share/cds/aotStreamedHeap.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_CDS_AOTSTREAMEDHEAP_HPP
|
||||
#define SHARE_CDS_AOTSTREAMEDHEAP_HPP
|
||||
|
||||
#include "cds/aotMapLogger.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class AOTStreamedHeapHeader {
|
||||
size_t _forwarding_offset; // Offset of forwarding information in the heap region.
|
||||
size_t _roots_offset; // Start position for the roots
|
||||
size_t _root_highest_object_index_table_offset; // Offset of root dfs depth information
|
||||
size_t _num_roots; // Number of embedded roots
|
||||
size_t _num_archived_objects; // The number of archived heap objects
|
||||
|
||||
public:
|
||||
AOTStreamedHeapHeader();
|
||||
AOTStreamedHeapHeader(size_t forwarding_offset,
|
||||
size_t roots_offset,
|
||||
size_t num_roots,
|
||||
size_t root_highest_object_index_table_offset,
|
||||
size_t num_archived_objects);
|
||||
|
||||
size_t forwarding_offset() const { return _forwarding_offset; }
|
||||
size_t roots_offset() const { return _roots_offset; }
|
||||
size_t num_roots() const { return _num_roots; }
|
||||
size_t root_highest_object_index_table_offset() const { return _root_highest_object_index_table_offset; }
|
||||
size_t num_archived_objects() const { return _num_archived_objects; }
|
||||
|
||||
// This class is trivially copyable and assignable.
|
||||
AOTStreamedHeapHeader(const AOTStreamedHeapHeader&) = default;
|
||||
AOTStreamedHeapHeader& operator=(const AOTStreamedHeapHeader&) = default;
|
||||
};
|
||||
|
||||
class AOTStreamedHeapInfo {
|
||||
MemRegion _buffer_region; // Contains the archived objects to be written into the CDS archive.
|
||||
CHeapBitMap _oopmap;
|
||||
size_t _roots_offset; // Offset of the HeapShared::roots() object, from the bottom
|
||||
// of the archived heap objects, in bytes.
|
||||
size_t _num_roots;
|
||||
|
||||
size_t _forwarding_offset; // Offset of forwarding information from the bottom
|
||||
size_t _root_highest_object_index_table_offset; // Offset to root dfs depth information
|
||||
size_t _num_archived_objects; // The number of archived objects written into the CDS archive.
|
||||
|
||||
public:
|
||||
AOTStreamedHeapInfo()
|
||||
: _buffer_region(),
|
||||
_oopmap(128, mtClassShared),
|
||||
_roots_offset(),
|
||||
_forwarding_offset(),
|
||||
_root_highest_object_index_table_offset(),
|
||||
_num_archived_objects() {}
|
||||
|
||||
bool is_used() { return !_buffer_region.is_empty(); }
|
||||
|
||||
void set_buffer_region(MemRegion r) { _buffer_region = r; }
|
||||
MemRegion buffer_region() { return _buffer_region; }
|
||||
char* buffer_start() { return (char*)_buffer_region.start(); }
|
||||
size_t buffer_byte_size() { return _buffer_region.byte_size(); }
|
||||
|
||||
CHeapBitMap* oopmap() { return &_oopmap; }
|
||||
void set_roots_offset(size_t n) { _roots_offset = n; }
|
||||
size_t roots_offset() { return _roots_offset; }
|
||||
void set_num_roots(size_t n) { _num_roots = n; }
|
||||
size_t num_roots() { return _num_roots; }
|
||||
void set_forwarding_offset(size_t n) { _forwarding_offset = n; }
|
||||
void set_root_highest_object_index_table_offset(size_t n) { _root_highest_object_index_table_offset = n; }
|
||||
void set_num_archived_objects(size_t n) { _num_archived_objects = n; }
|
||||
size_t num_archived_objects() { return _num_archived_objects; }
|
||||
|
||||
AOTStreamedHeapHeader create_header();
|
||||
};
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
class AOTStreamedHeapOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
protected:
|
||||
int _current;
|
||||
int _next;
|
||||
address _buffer_start;
|
||||
int _num_archived_objects;
|
||||
|
||||
public:
|
||||
AOTStreamedHeapOopIterator(address buffer_start,
|
||||
int num_archived_objects)
|
||||
: _current(0),
|
||||
_next(1),
|
||||
_buffer_start(buffer_start),
|
||||
_num_archived_objects(num_archived_objects) {}
|
||||
|
||||
virtual AOTMapLogger::OopData capture(int dfs_index) = 0;
|
||||
|
||||
bool has_next() override {
|
||||
return _next <= _num_archived_objects;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
_next = _current + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
int dfs_index = (int)(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
int dfs_index = (int)cast_from_oop<uintptr_t>(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
|
||||
#endif // SHARE_CDS_AOTSTREAMEDHEAP_HPP
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1102,25 +1102,13 @@ void AOTStreamedHeapLoader::finish_initialization(FileMapInfo* static_mapinfo) {
|
||||
}
|
||||
|
||||
AOTMapLogger::OopDataIterator* AOTStreamedHeapLoader::oop_iterator(FileMapInfo* info, address buffer_start, address buffer_end) {
|
||||
class StreamedLoaderOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
private:
|
||||
int _current;
|
||||
int _next;
|
||||
|
||||
address _buffer_start;
|
||||
|
||||
int _num_archived_objects;
|
||||
|
||||
class StreamedLoaderOopIterator : public AOTStreamedHeapOopIterator {
|
||||
public:
|
||||
StreamedLoaderOopIterator(address buffer_start,
|
||||
int num_archived_objects)
|
||||
: _current(0),
|
||||
_next(1),
|
||||
_buffer_start(buffer_start),
|
||||
_num_archived_objects(num_archived_objects) {
|
||||
}
|
||||
: AOTStreamedHeapOopIterator(buffer_start, num_archived_objects) {}
|
||||
|
||||
AOTMapLogger::OopData capture(int dfs_index) {
|
||||
AOTMapLogger::OopData capture(int dfs_index) override {
|
||||
size_t buffered_offset = buffer_offset_for_object_index(dfs_index);
|
||||
address buffered_addr = _buffer_start + buffered_offset;
|
||||
oopDesc* raw_oop = (oopDesc*)buffered_addr;
|
||||
@ -1142,35 +1130,6 @@ AOTMapLogger::OopDataIterator* AOTStreamedHeapLoader::oop_iterator(FileMapInfo*
|
||||
false };
|
||||
}
|
||||
|
||||
bool has_next() override {
|
||||
return _next <= _num_archived_objects;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
_next = _current + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
int dfs_index = (int)(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
int dfs_index = (int)cast_from_oop<uintptr_t>(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* roots() override {
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* result = new GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>();
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -163,7 +163,7 @@ void AOTStreamedHeapWriter::order_source_objs(GrowableArrayCHeap<oop, mtClassSha
|
||||
}
|
||||
|
||||
void AOTStreamedHeapWriter::write(GrowableArrayCHeap<oop, mtClassShared>* roots,
|
||||
ArchiveStreamedHeapInfo* heap_info) {
|
||||
AOTStreamedHeapInfo* heap_info) {
|
||||
assert(CDSConfig::is_dumping_heap(), "sanity");
|
||||
allocate_buffer();
|
||||
order_source_objs(roots);
|
||||
@ -453,7 +453,7 @@ static void log_bitmap_usage(const char* which, BitMap* bitmap, size_t total_bit
|
||||
}
|
||||
|
||||
// Update all oop fields embedded in the buffered objects
|
||||
void AOTStreamedHeapWriter::map_embedded_oops(ArchiveStreamedHeapInfo* heap_info) {
|
||||
void AOTStreamedHeapWriter::map_embedded_oops(AOTStreamedHeapInfo* heap_info) {
|
||||
size_t oopmap_unit = (UseCompressedOops ? sizeof(narrowOop) : sizeof(oop));
|
||||
size_t heap_region_byte_size = _buffer_used;
|
||||
heap_info->oopmap()->resize(heap_region_byte_size / oopmap_unit);
|
||||
@ -497,7 +497,7 @@ oop AOTStreamedHeapWriter::buffered_addr_to_source_obj(address buffered_addr) {
|
||||
return buffered_offset_to_source_obj(buffered_address_to_offset(buffered_addr));
|
||||
}
|
||||
|
||||
void AOTStreamedHeapWriter::populate_archive_heap_info(ArchiveStreamedHeapInfo* info) {
|
||||
void AOTStreamedHeapWriter::populate_archive_heap_info(AOTStreamedHeapInfo* info) {
|
||||
assert(!info->is_used(), "only set once");
|
||||
|
||||
size_t heap_region_byte_size = _buffer_used;
|
||||
@ -512,15 +512,9 @@ void AOTStreamedHeapWriter::populate_archive_heap_info(ArchiveStreamedHeapInfo*
|
||||
info->set_num_archived_objects((size_t)_source_objs->length());
|
||||
}
|
||||
|
||||
AOTMapLogger::OopDataIterator* AOTStreamedHeapWriter::oop_iterator(ArchiveStreamedHeapInfo* heap_info) {
|
||||
class StreamedWriterOopIterator : public AOTMapLogger::OopDataIterator {
|
||||
AOTMapLogger::OopDataIterator* AOTStreamedHeapWriter::oop_iterator(AOTStreamedHeapInfo* heap_info) {
|
||||
class StreamedWriterOopIterator : public AOTStreamedHeapOopIterator {
|
||||
private:
|
||||
int _current;
|
||||
int _next;
|
||||
|
||||
address _buffer_start;
|
||||
|
||||
int _num_archived_objects;
|
||||
int _num_archived_roots;
|
||||
int* _roots;
|
||||
|
||||
@ -529,15 +523,11 @@ AOTMapLogger::OopDataIterator* AOTStreamedHeapWriter::oop_iterator(ArchiveStream
|
||||
int num_archived_objects,
|
||||
int num_archived_roots,
|
||||
int* roots)
|
||||
: _current(0),
|
||||
_next(1),
|
||||
_buffer_start(buffer_start),
|
||||
_num_archived_objects(num_archived_objects),
|
||||
: AOTStreamedHeapOopIterator(buffer_start, num_archived_objects),
|
||||
_num_archived_roots(num_archived_roots),
|
||||
_roots(roots) {
|
||||
}
|
||||
_roots(roots) {}
|
||||
|
||||
AOTMapLogger::OopData capture(int dfs_index) {
|
||||
AOTMapLogger::OopData capture(int dfs_index) override {
|
||||
size_t buffered_offset = _dfs_to_archive_object_table[dfs_index];
|
||||
address buffered_addr = _buffer_start + buffered_offset;
|
||||
oop src_obj = AOTStreamedHeapWriter::buffered_offset_to_source_obj(buffered_offset);
|
||||
@ -561,35 +551,6 @@ AOTMapLogger::OopDataIterator* AOTStreamedHeapWriter::oop_iterator(ArchiveStream
|
||||
false };
|
||||
}
|
||||
|
||||
bool has_next() override {
|
||||
return _next <= _num_archived_objects;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData next() override {
|
||||
_current = _next;
|
||||
AOTMapLogger::OopData result = capture(_current);
|
||||
_next = _current + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(narrowOop* addr) override {
|
||||
int dfs_index = (int)(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
|
||||
AOTMapLogger::OopData obj_at(oop* addr) override {
|
||||
int dfs_index = (int)cast_from_oop<uintptr_t>(*addr);
|
||||
if (dfs_index == 0) {
|
||||
return null_data();
|
||||
} else {
|
||||
return capture(dfs_index);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* roots() override {
|
||||
GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>* result = new GrowableArrayCHeap<AOTMapLogger::OopData, mtClass>();
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -117,7 +117,7 @@ class AOTStreamedHeapWriter : AllStatic {
|
||||
static void copy_forwarding_to_buffer();
|
||||
static void copy_roots_max_dfs_to_buffer(int roots_length);
|
||||
|
||||
static void map_embedded_oops(ArchiveStreamedHeapInfo* info);
|
||||
static void map_embedded_oops(AOTStreamedHeapInfo* info);
|
||||
static bool is_in_requested_range(oop o);
|
||||
static oop requested_obj_from_buffer_offset(size_t offset);
|
||||
|
||||
@ -131,14 +131,14 @@ class AOTStreamedHeapWriter : AllStatic {
|
||||
|
||||
static void update_header_for_buffered_addr(address buffered_addr, oop src_obj, Klass* src_klass);
|
||||
|
||||
static void populate_archive_heap_info(ArchiveStreamedHeapInfo* info);
|
||||
static void populate_archive_heap_info(AOTStreamedHeapInfo* info);
|
||||
|
||||
public:
|
||||
static void init() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static void delete_tables_with_raw_oops();
|
||||
static void add_source_obj(oop src_obj);
|
||||
static void write(GrowableArrayCHeap<oop, mtClassShared>*, ArchiveStreamedHeapInfo* heap_info);
|
||||
static void write(GrowableArrayCHeap<oop, mtClassShared>*, AOTStreamedHeapInfo* heap_info);
|
||||
static address buffered_heap_roots_addr() {
|
||||
return offset_to_buffered_address<address>(_roots_offset);
|
||||
}
|
||||
@ -156,7 +156,7 @@ public:
|
||||
static oop buffered_offset_to_source_obj(size_t buffered_offset);
|
||||
static oop buffered_addr_to_source_obj(address buffered_addr);
|
||||
|
||||
static AOTMapLogger::OopDataIterator* oop_iterator(ArchiveStreamedHeapInfo* heap_info);
|
||||
static AOTMapLogger::OopDataIterator* oop_iterator(AOTStreamedHeapInfo* heap_info);
|
||||
};
|
||||
#endif // INCLUDE_CDS_JAVA_HEAP
|
||||
#endif // SHARE_CDS_AOTSTREAMEDHEAPWRITER_HPP
|
||||
|
||||
@ -1154,7 +1154,7 @@ void ArchiveBuilder::print_stats() {
|
||||
_alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()));
|
||||
}
|
||||
|
||||
void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, ArchiveMappedHeapInfo* mapped_heap_info, ArchiveStreamedHeapInfo* streamed_heap_info) {
|
||||
void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) {
|
||||
// Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with
|
||||
// AOTMetaspace::n_regions (internal to hotspot).
|
||||
assert(NUM_CDS_REGIONS == AOTMetaspace::n_regions, "sanity");
|
||||
@ -1213,8 +1213,8 @@ void ArchiveBuilder::count_relocated_pointer(bool tagged, bool nulled) {
|
||||
}
|
||||
|
||||
void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info) {
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info) {
|
||||
// Print statistics of all the regions
|
||||
const size_t bitmap_used = mapinfo->region_at(AOTMetaspace::bm)->used();
|
||||
const size_t bitmap_reserved = mapinfo->region_at(AOTMetaspace::bm)->used_aligned();
|
||||
|
||||
@ -39,8 +39,8 @@
|
||||
#include "utilities/hashTable.hpp"
|
||||
#include "utilities/resizableHashTable.hpp"
|
||||
|
||||
class ArchiveMappedHeapInfo;
|
||||
class ArchiveStreamedHeapInfo;
|
||||
class AOTMappedHeapInfo;
|
||||
class AOTStreamedHeapInfo;
|
||||
class CHeapBitMap;
|
||||
class FileMapInfo;
|
||||
class Klass;
|
||||
@ -247,8 +247,8 @@ private:
|
||||
} _relocated_ptr_info;
|
||||
|
||||
void print_region_stats(FileMapInfo *map_info,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info);
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info);
|
||||
void print_bitmap_region_stats(size_t size, size_t total_size);
|
||||
void print_heap_region_stats(char* start, size_t size, size_t total_size);
|
||||
|
||||
@ -438,8 +438,8 @@ public:
|
||||
void make_training_data_shareable();
|
||||
void relocate_to_requested();
|
||||
void write_archive(FileMapInfo* mapinfo,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info);
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info);
|
||||
void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region,
|
||||
bool read_only, bool allow_exec);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -974,8 +974,8 @@ size_t FileMapInfo::remove_bitmap_zeros(CHeapBitMap* map) {
|
||||
|
||||
char* FileMapInfo::write_bitmap_region(CHeapBitMap* rw_ptrmap,
|
||||
CHeapBitMap* ro_ptrmap,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info,
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info,
|
||||
size_t &size_in_bytes) {
|
||||
size_t removed_rw_leading_zeros = remove_bitmap_zeros(rw_ptrmap);
|
||||
size_t removed_ro_leading_zeros = remove_bitmap_zeros(ro_ptrmap);
|
||||
@ -1035,7 +1035,7 @@ char* FileMapInfo::write_bitmap_region(CHeapBitMap* rw_ptrmap,
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS_JAVA_HEAP
|
||||
size_t FileMapInfo::write_mapped_heap_region(ArchiveMappedHeapInfo* heap_info) {
|
||||
size_t FileMapInfo::write_mapped_heap_region(AOTMappedHeapInfo* heap_info) {
|
||||
char* buffer_start = heap_info->buffer_start();
|
||||
size_t buffer_size = heap_info->buffer_byte_size();
|
||||
write_region(AOTMetaspace::hp, buffer_start, buffer_size, false, false);
|
||||
@ -1043,7 +1043,7 @@ size_t FileMapInfo::write_mapped_heap_region(ArchiveMappedHeapInfo* heap_info) {
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
size_t FileMapInfo::write_streamed_heap_region(ArchiveStreamedHeapInfo* heap_info) {
|
||||
size_t FileMapInfo::write_streamed_heap_region(AOTStreamedHeapInfo* heap_info) {
|
||||
char* buffer_start = heap_info->buffer_start();
|
||||
size_t buffer_size = heap_info->buffer_byte_size();
|
||||
write_region(AOTMetaspace::hp, buffer_start, buffer_size, true, false);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,9 @@
|
||||
#ifndef SHARE_CDS_FILEMAP_HPP
|
||||
#define SHARE_CDS_FILEMAP_HPP
|
||||
|
||||
#include "cds/aotMappedHeap.hpp"
|
||||
#include "cds/aotMetaspace.hpp"
|
||||
#include "cds/aotStreamedHeap.hpp"
|
||||
#include "cds/archiveUtils.hpp"
|
||||
#include "cds/heapShared.hpp"
|
||||
#include "include/cds.h"
|
||||
@ -144,8 +146,8 @@ private:
|
||||
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
|
||||
|
||||
ArchiveMappedHeapHeader _mapped_heap_header;
|
||||
ArchiveStreamedHeapHeader _streamed_heap_header;
|
||||
AOTMappedHeapHeader _mapped_heap_header;
|
||||
AOTStreamedHeapHeader _streamed_heap_header;
|
||||
|
||||
// The following are parameters that affect MethodData layout.
|
||||
u1 _compiler_type;
|
||||
@ -209,11 +211,11 @@ public:
|
||||
size_t ro_ptrmap_start_pos() const { return _ro_ptrmap_start_pos; }
|
||||
|
||||
// Heap archiving
|
||||
const ArchiveMappedHeapHeader* mapped_heap() const { return &_mapped_heap_header; }
|
||||
const ArchiveStreamedHeapHeader* streamed_heap() const { return &_streamed_heap_header; }
|
||||
const AOTMappedHeapHeader* mapped_heap() const { return &_mapped_heap_header; }
|
||||
const AOTStreamedHeapHeader* streamed_heap() const { return &_streamed_heap_header; }
|
||||
|
||||
void set_streamed_heap_header(ArchiveStreamedHeapHeader header) { _streamed_heap_header = header; }
|
||||
void set_mapped_heap_header(ArchiveMappedHeapHeader header) { _mapped_heap_header = header; }
|
||||
void set_streamed_heap_header(AOTStreamedHeapHeader header) { _streamed_heap_header = header; }
|
||||
void set_mapped_heap_header(AOTMappedHeapHeader header) { _mapped_heap_header = header; }
|
||||
|
||||
void set_has_platform_or_app_classes(bool v) { _has_platform_or_app_classes = v; }
|
||||
void set_cloned_vtables(char* p) { set_as_offset(p, &_cloned_vtables_offset); }
|
||||
@ -309,8 +311,8 @@ public:
|
||||
uintx max_heap_size() const { return header()->max_heap_size(); }
|
||||
size_t core_region_alignment() const { return header()->core_region_alignment(); }
|
||||
|
||||
const ArchiveMappedHeapHeader* mapped_heap() const { return header()->mapped_heap(); }
|
||||
const ArchiveStreamedHeapHeader* streamed_heap() const { return header()->streamed_heap(); }
|
||||
const AOTMappedHeapHeader* mapped_heap() const { return header()->mapped_heap(); }
|
||||
const AOTStreamedHeapHeader* streamed_heap() const { return header()->streamed_heap(); }
|
||||
|
||||
bool object_streaming_mode() const { return header()->object_streaming_mode(); }
|
||||
CompressedOops::Mode narrow_oop_mode() const { return header()->narrow_oop_mode(); }
|
||||
@ -372,11 +374,11 @@ public:
|
||||
size_t remove_bitmap_zeros(CHeapBitMap* map);
|
||||
char* write_bitmap_region(CHeapBitMap* rw_ptrmap,
|
||||
CHeapBitMap* ro_ptrmap,
|
||||
ArchiveMappedHeapInfo* mapped_heap_info,
|
||||
ArchiveStreamedHeapInfo* streamed_heap_info,
|
||||
AOTMappedHeapInfo* mapped_heap_info,
|
||||
AOTStreamedHeapInfo* streamed_heap_info,
|
||||
size_t &size_in_bytes);
|
||||
size_t write_mapped_heap_region(ArchiveMappedHeapInfo* heap_info) NOT_CDS_JAVA_HEAP_RETURN_(0);
|
||||
size_t write_streamed_heap_region(ArchiveStreamedHeapInfo* heap_info) NOT_CDS_JAVA_HEAP_RETURN_(0);
|
||||
size_t write_mapped_heap_region(AOTMappedHeapInfo* heap_info) NOT_CDS_JAVA_HEAP_RETURN_(0);
|
||||
size_t write_streamed_heap_region(AOTStreamedHeapInfo* heap_info) NOT_CDS_JAVA_HEAP_RETURN_(0);
|
||||
void write_bytes(const void* buffer, size_t count);
|
||||
void write_bytes_aligned(const void* buffer, size_t count);
|
||||
size_t read_bytes(void* buffer, size_t count);
|
||||
|
||||
@ -95,55 +95,6 @@ struct ArchivableStaticFieldInfo {
|
||||
}
|
||||
};
|
||||
|
||||
// Anything that goes in the header must be thoroughly purged from uninitialized memory
|
||||
// as it will be written to disk. Therefore, the constructors memset the memory to 0.
|
||||
// This is not the prettiest thing, but we need to know every byte is initialized,
|
||||
// including potential padding between fields.
|
||||
|
||||
ArchiveMappedHeapHeader::ArchiveMappedHeapHeader(size_t ptrmap_start_pos,
|
||||
size_t oopmap_start_pos,
|
||||
HeapRootSegments root_segments) {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
_ptrmap_start_pos = ptrmap_start_pos;
|
||||
_oopmap_start_pos = oopmap_start_pos;
|
||||
_root_segments = root_segments;
|
||||
}
|
||||
|
||||
ArchiveMappedHeapHeader::ArchiveMappedHeapHeader() {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
ArchiveMappedHeapHeader ArchiveMappedHeapInfo::create_header() {
|
||||
return ArchiveMappedHeapHeader{_ptrmap_start_pos,
|
||||
_oopmap_start_pos,
|
||||
_root_segments};
|
||||
}
|
||||
|
||||
ArchiveStreamedHeapHeader::ArchiveStreamedHeapHeader(size_t forwarding_offset,
|
||||
size_t roots_offset,
|
||||
size_t num_roots,
|
||||
size_t root_highest_object_index_table_offset,
|
||||
size_t num_archived_objects) {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
_forwarding_offset = forwarding_offset;
|
||||
_roots_offset = roots_offset;
|
||||
_num_roots = num_roots;
|
||||
_root_highest_object_index_table_offset = root_highest_object_index_table_offset;
|
||||
_num_archived_objects = num_archived_objects;
|
||||
}
|
||||
|
||||
ArchiveStreamedHeapHeader::ArchiveStreamedHeapHeader() {
|
||||
memset((char*)this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
ArchiveStreamedHeapHeader ArchiveStreamedHeapInfo::create_header() {
|
||||
return ArchiveStreamedHeapHeader{_forwarding_offset,
|
||||
_roots_offset,
|
||||
_num_roots,
|
||||
_root_highest_object_index_table_offset,
|
||||
_num_archived_objects};
|
||||
}
|
||||
|
||||
HeapArchiveMode HeapShared::_heap_load_mode = HeapArchiveMode::_uninitialized;
|
||||
HeapArchiveMode HeapShared::_heap_write_mode = HeapArchiveMode::_uninitialized;
|
||||
|
||||
@ -892,7 +843,7 @@ void HeapShared::end_scanning_for_oops() {
|
||||
delete_seen_objects_table();
|
||||
}
|
||||
|
||||
void HeapShared::write_heap(ArchiveMappedHeapInfo* mapped_heap_info, ArchiveStreamedHeapInfo* streamed_heap_info) {
|
||||
void HeapShared::write_heap(AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) {
|
||||
{
|
||||
NoSafepointVerifier nsv;
|
||||
CDSHeapVerifier::verify();
|
||||
|
||||
@ -142,129 +142,6 @@ enum class HeapArchiveMode {
|
||||
_streaming
|
||||
};
|
||||
|
||||
class ArchiveMappedHeapHeader {
|
||||
size_t _ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap.
|
||||
size_t _oopmap_start_pos; // The first bit in the oopmap corresponds to this position in the heap.
|
||||
HeapRootSegments _root_segments; // Heap root segments info
|
||||
|
||||
public:
|
||||
ArchiveMappedHeapHeader();
|
||||
ArchiveMappedHeapHeader(size_t ptrmap_start_pos,
|
||||
size_t oopmap_start_pos,
|
||||
HeapRootSegments root_segments);
|
||||
|
||||
size_t ptrmap_start_pos() const { return _ptrmap_start_pos; }
|
||||
size_t oopmap_start_pos() const { return _oopmap_start_pos; }
|
||||
HeapRootSegments root_segments() const { return _root_segments; }
|
||||
|
||||
// This class is trivially copyable and assignable.
|
||||
ArchiveMappedHeapHeader(const ArchiveMappedHeapHeader&) = default;
|
||||
ArchiveMappedHeapHeader& operator=(const ArchiveMappedHeapHeader&) = default;
|
||||
};
|
||||
|
||||
|
||||
class ArchiveStreamedHeapHeader {
|
||||
size_t _forwarding_offset; // Offset of forwarding information in the heap region.
|
||||
size_t _roots_offset; // Start position for the roots
|
||||
size_t _root_highest_object_index_table_offset; // Offset of root dfs depth information
|
||||
size_t _num_roots; // Number of embedded roots
|
||||
size_t _num_archived_objects; // The number of archived heap objects
|
||||
|
||||
public:
|
||||
ArchiveStreamedHeapHeader();
|
||||
ArchiveStreamedHeapHeader(size_t forwarding_offset,
|
||||
size_t roots_offset,
|
||||
size_t num_roots,
|
||||
size_t root_highest_object_index_table_offset,
|
||||
size_t num_archived_objects);
|
||||
|
||||
size_t forwarding_offset() const { return _forwarding_offset; }
|
||||
size_t roots_offset() const { return _roots_offset; }
|
||||
size_t num_roots() const { return _num_roots; }
|
||||
size_t root_highest_object_index_table_offset() const { return _root_highest_object_index_table_offset; }
|
||||
size_t num_archived_objects() const { return _num_archived_objects; }
|
||||
|
||||
// This class is trivially copyable and assignable.
|
||||
ArchiveStreamedHeapHeader(const ArchiveStreamedHeapHeader&) = default;
|
||||
ArchiveStreamedHeapHeader& operator=(const ArchiveStreamedHeapHeader&) = default;
|
||||
};
|
||||
|
||||
class ArchiveMappedHeapInfo {
|
||||
MemRegion _buffer_region; // Contains the archived objects to be written into the CDS archive.
|
||||
CHeapBitMap _oopmap;
|
||||
CHeapBitMap _ptrmap;
|
||||
HeapRootSegments _root_segments;
|
||||
size_t _oopmap_start_pos; // How many zeros were removed from the beginning of the bit map?
|
||||
size_t _ptrmap_start_pos; // How many zeros were removed from the beginning of the bit map?
|
||||
|
||||
public:
|
||||
ArchiveMappedHeapInfo() :
|
||||
_buffer_region(),
|
||||
_oopmap(128, mtClassShared),
|
||||
_ptrmap(128, mtClassShared),
|
||||
_root_segments(),
|
||||
_oopmap_start_pos(),
|
||||
_ptrmap_start_pos() {}
|
||||
bool is_used() { return !_buffer_region.is_empty(); }
|
||||
|
||||
MemRegion buffer_region() { return _buffer_region; }
|
||||
void set_buffer_region(MemRegion r) { _buffer_region = r; }
|
||||
|
||||
char* buffer_start() { return (char*)_buffer_region.start(); }
|
||||
size_t buffer_byte_size() { return _buffer_region.byte_size(); }
|
||||
|
||||
CHeapBitMap* oopmap() { return &_oopmap; }
|
||||
CHeapBitMap* ptrmap() { return &_ptrmap; }
|
||||
|
||||
void set_oopmap_start_pos(size_t start_pos) { _oopmap_start_pos = start_pos; }
|
||||
void set_ptrmap_start_pos(size_t start_pos) { _ptrmap_start_pos = start_pos; }
|
||||
|
||||
void set_root_segments(HeapRootSegments segments) { _root_segments = segments; };
|
||||
HeapRootSegments root_segments() { return _root_segments; }
|
||||
|
||||
ArchiveMappedHeapHeader create_header();
|
||||
};
|
||||
|
||||
class ArchiveStreamedHeapInfo {
|
||||
MemRegion _buffer_region; // Contains the archived objects to be written into the CDS archive.
|
||||
CHeapBitMap _oopmap;
|
||||
size_t _roots_offset; // Offset of the HeapShared::roots() object, from the bottom
|
||||
// of the archived heap objects, in bytes.
|
||||
size_t _num_roots;
|
||||
|
||||
size_t _forwarding_offset; // Offset of forwarding information from the bottom
|
||||
size_t _root_highest_object_index_table_offset; // Offset to root dfs depth information
|
||||
size_t _num_archived_objects; // The number of archived objects written into the CDS archive.
|
||||
|
||||
public:
|
||||
ArchiveStreamedHeapInfo()
|
||||
: _buffer_region(),
|
||||
_oopmap(128, mtClassShared),
|
||||
_roots_offset(),
|
||||
_forwarding_offset(),
|
||||
_root_highest_object_index_table_offset(),
|
||||
_num_archived_objects() {}
|
||||
|
||||
bool is_used() { return !_buffer_region.is_empty(); }
|
||||
|
||||
void set_buffer_region(MemRegion r) { _buffer_region = r; }
|
||||
MemRegion buffer_region() { return _buffer_region; }
|
||||
char* buffer_start() { return (char*)_buffer_region.start(); }
|
||||
size_t buffer_byte_size() { return _buffer_region.byte_size(); }
|
||||
|
||||
CHeapBitMap* oopmap() { return &_oopmap; }
|
||||
void set_roots_offset(size_t n) { _roots_offset = n; }
|
||||
size_t roots_offset() { return _roots_offset; }
|
||||
void set_num_roots(size_t n) { _num_roots = n; }
|
||||
size_t num_roots() { return _num_roots; }
|
||||
void set_forwarding_offset(size_t n) { _forwarding_offset = n; }
|
||||
void set_root_highest_object_index_table_offset(size_t n) { _root_highest_object_index_table_offset = n; }
|
||||
void set_num_archived_objects(size_t n) { _num_archived_objects = n; }
|
||||
size_t num_archived_objects() { return _num_archived_objects; }
|
||||
|
||||
ArchiveStreamedHeapHeader create_header();
|
||||
};
|
||||
|
||||
class HeapShared: AllStatic {
|
||||
friend class VerifySharedOopClosure;
|
||||
|
||||
@ -575,7 +452,7 @@ private:
|
||||
public:
|
||||
static void finish_materialize_objects() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
static void write_heap(ArchiveMappedHeapInfo* mapped_heap_info, ArchiveStreamedHeapInfo* streamed_heap_info) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void write_heap(AOTMappedHeapInfo* mapped_heap_info, AOTStreamedHeapInfo* streamed_heap_info) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static objArrayOop scratch_resolved_references(ConstantPool* src);
|
||||
static void add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
static void init_dumping() NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user