8377307: Refactor code for AOT cache pointer compression

Reviewed-by: jsjolen, xuelei, asmehra
This commit is contained in:
Ioi Lam 2026-02-11 23:00:50 +00:00
parent e515c10f3a
commit 0867f9b1b4
26 changed files with 343 additions and 234 deletions

View File

@ -0,0 +1,30 @@
/*
* 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/aotCompressedPointers.hpp"
#include "cds/archiveBuilder.hpp"
size_t AOTCompressedPointers::compute_byte_offset(address p) {
return ArchiveBuilder::current()->any_to_offset(p);
}

View File

@ -0,0 +1,142 @@
/*
* 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_AOTCOMPRESSEDPOINTERS_HPP
#define SHARE_CDS_AOTCOMPRESSEDPOINTERS_HPP
#include "cds/cds_globals.hpp"
#include "memory/allStatic.hpp"
#include "memory/metaspace.hpp"
#include "metaprogramming/enableIf.hpp"
#include "utilities/align.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
class AOTCompressedPointers: public AllStatic {
public:
// For space saving, we can encode the location of metadata objects in the "rw" and "ro"
// regions using a 32-bit offset from the bottom of the mapped AOT metaspace.
// Currently we allow only up to 2GB total size in the rw and ro regions (which are
// contiguous to each other).
enum class narrowPtr : u4;
static constexpr size_t MaxMetadataOffsetBytes = 0x7FFFFFFF;
// In the future, this could return a different numerical value than
// narrowp if the encoding contains shifts.
inline static size_t get_byte_offset(narrowPtr narrowp) {
return checked_cast<size_t>(narrowp);
}
inline static narrowPtr null() {
return static_cast<narrowPtr>(0);
}
// Encoding ------
// ptr can point to one of the following
// - an object in the ArchiveBuilder's buffer.
// - an object in the currently mapped AOT cache rw/ro regions.
// - an object that has been copied into the ArchiveBuilder's buffer.
template <typename T>
static narrowPtr encode_not_null(T ptr) {
address p = reinterpret_cast<address>(ptr);
return encode_byte_offset(compute_byte_offset(p));
}
template <typename T>
static narrowPtr encode(T ptr) { // may be null
if (ptr == nullptr) {
return null();
} else {
return encode_not_null(ptr);
}
}
// ptr must be in the currently mapped AOT cache rw/ro regions.
template <typename T>
static narrowPtr encode_address_in_cache(T ptr) {
assert(Metaspace::in_aot_cache(ptr), "must be");
address p = reinterpret_cast<address>(ptr);
address base = reinterpret_cast<address>(SharedBaseAddress);
return encode_byte_offset(pointer_delta(p, base, 1));
}
template <typename T>
static narrowPtr encode_address_in_cache_or_null(T ptr) {
if (ptr == nullptr) {
return null();
} else {
return encode_address_in_cache<T>(ptr);
}
}
// Decoding -----
// If base_address is null, decode an address within the mapped aot cache range.
template <typename T>
static T decode_not_null(narrowPtr narrowp, address base_address = nullptr) {
assert(narrowp != null(), "sanity");
if (base_address == nullptr) {
T p = reinterpret_cast<T>(reinterpret_cast<address>(SharedBaseAddress) + get_byte_offset(narrowp));
assert(Metaspace::in_aot_cache(p), "must be");
return p;
} else {
// This is usually called before the cache is fully mapped.
return reinterpret_cast<T>(base_address + get_byte_offset(narrowp));
}
}
template <typename T>
static T decode(narrowPtr narrowp, address base_address = nullptr) { // may be null
if (narrowp == null()) {
return nullptr;
} else {
return decode_not_null<T>(narrowp, base_address);
}
}
private:
static size_t compute_byte_offset(address p);
static narrowPtr encode_byte_offset(size_t offset) {
assert(offset != 0, "offset 0 is in protection zone");
precond(offset <= MaxMetadataOffsetBytes);
return checked_cast<narrowPtr>(offset);
}
};
// Type casts -- declared as global functions to save a few keystrokes
// A simple type cast. No change in numerical value.
inline AOTCompressedPointers::narrowPtr cast_from_u4(u4 narrowp) {
return checked_cast<AOTCompressedPointers::narrowPtr>(narrowp);
}
// A simple type cast. No change in numerical value.
// !!!DO NOT CALL THIS if you want a byte offset!!!
inline u4 cast_to_u4(AOTCompressedPointers::narrowPtr narrowp) {
return checked_cast<u4>(narrowp);
}
#endif // SHARE_CDS_AOTCOMPRESSEDPOINTERS_HPP

View File

@ -2106,7 +2106,7 @@ MapArchiveResult AOTMetaspace::map_archive(FileMapInfo* mapinfo, char* mapped_ba
// Currently, only static archive uses early serialized data.
char* buffer = mapinfo->early_serialized_data();
intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array, (intptr_t)mapped_base_address);
ReadClosure rc(&array, (address)mapped_base_address);
early_serialize(&rc);
}
@ -2152,7 +2152,7 @@ void AOTMetaspace::initialize_shared_spaces() {
// shared string/symbol tables.
char* buffer = static_mapinfo->serialized_data();
intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array, (intptr_t)SharedBaseAddress);
ReadClosure rc(&array, (address)SharedBaseAddress);
serialize(&rc);
// Finish initializing the heap dump mode used in the archive
@ -2164,7 +2164,7 @@ void AOTMetaspace::initialize_shared_spaces() {
if (dynamic_mapinfo != nullptr) {
intptr_t* buffer = (intptr_t*)dynamic_mapinfo->serialized_data();
ReadClosure rc(&buffer, (intptr_t)SharedBaseAddress);
ReadClosure rc(&buffer, (address)SharedBaseAddress);
DynamicArchive::serialize(&rc);
}

View File

@ -24,6 +24,7 @@
#include "cds/aotArtifactFinder.hpp"
#include "cds/aotClassLinker.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotLogging.hpp"
#include "cds/aotMapLogger.hpp"
#include "cds/aotMetaspace.hpp"
@ -175,10 +176,10 @@ ArchiveBuilder::ArchiveBuilder() :
_mapped_static_archive_bottom(nullptr),
_mapped_static_archive_top(nullptr),
_buffer_to_requested_delta(0),
_pz_region("pz", MAX_SHARED_DELTA), // protection zone -- used only during dumping; does NOT exist in cds archive.
_rw_region("rw", MAX_SHARED_DELTA),
_ro_region("ro", MAX_SHARED_DELTA),
_ac_region("ac", MAX_SHARED_DELTA),
_pz_region("pz"), // protection zone -- used only during dumping; does NOT exist in cds archive.
_rw_region("rw"),
_ro_region("ro"),
_ac_region("ac"),
_ptrmap(mtClassShared),
_rw_ptrmap(mtClassShared),
_ro_ptrmap(mtClassShared),
@ -990,16 +991,15 @@ void ArchiveBuilder::make_training_data_shareable() {
_src_obj_table.iterate_all(clean_td);
}
uintx ArchiveBuilder::buffer_to_offset(address p) const {
size_t ArchiveBuilder::buffer_to_offset(address p) const {
address requested_p = to_requested(p);
assert(requested_p >= _requested_static_archive_bottom, "must be");
return requested_p - _requested_static_archive_bottom;
return pointer_delta(requested_p, _requested_static_archive_bottom, 1);
}
uintx ArchiveBuilder::any_to_offset(address p) const {
size_t ArchiveBuilder::any_to_offset(address p) const {
if (is_in_mapped_static_archive(p)) {
assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
return p - _mapped_static_archive_bottom;
return pointer_delta(p, _mapped_static_archive_bottom, 1);
}
if (!is_in_buffer_space(p)) {
// p must be a "source" address
@ -1008,7 +1008,7 @@ uintx ArchiveBuilder::any_to_offset(address p) const {
return buffer_to_offset(p);
}
address ArchiveBuilder::offset_to_buffered_address(u4 offset) const {
address ArchiveBuilder::offset_to_buffered_address(size_t offset) const {
address requested_addr = _requested_static_archive_bottom + offset;
address buffered_addr = requested_addr - _buffer_to_requested_delta;
assert(is_in_buffer_space(buffered_addr), "bad offset");

View File

@ -329,49 +329,22 @@ public:
return current()->buffer_to_requested_delta();
}
inline static u4 to_offset_u4(uintx offset) {
guarantee(offset <= MAX_SHARED_DELTA, "must be 32-bit offset " INTPTR_FORMAT, offset);
return (u4)offset;
}
public:
static const uintx MAX_SHARED_DELTA = ArchiveUtils::MAX_SHARED_DELTA;;
// The address p points to an object inside the output buffer. When the archive is mapped
// at the requested address, what's the offset of this object from _requested_static_archive_bottom?
uintx buffer_to_offset(address p) const;
size_t buffer_to_offset(address p) const;
// Same as buffer_to_offset, except that the address p points to either (a) an object
// inside the output buffer, or (b), an object in the currently mapped static archive.
uintx any_to_offset(address p) const;
// Same as buffer_to_offset, except that the address p points to one of the following:
// - an object in the ArchiveBuilder's buffer.
// - an object in the currently mapped AOT cache rw/ro regions.
// - an object that has been copied into the ArchiveBuilder's buffer.
size_t any_to_offset(address p) const;
// The reverse of buffer_to_offset()
address offset_to_buffered_address(u4 offset) const;
address offset_to_buffered_address(size_t offset) const;
template <typename T>
u4 buffer_to_offset_u4(T p) const {
uintx offset = buffer_to_offset((address)p);
return to_offset_u4(offset);
}
template <typename T>
u4 any_to_offset_u4(T p) const {
assert(p != nullptr, "must not be null");
uintx offset = any_to_offset((address)p);
return to_offset_u4(offset);
}
template <typename T>
u4 any_or_null_to_offset_u4(T p) const {
if (p == nullptr) {
return 0;
} else {
return any_to_offset_u4<T>(p);
}
}
template <typename T>
T offset_to_buffered(u4 offset) const {
T offset_to_buffered(size_t offset) const {
return (T)offset_to_buffered_address(offset);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@ -22,6 +22,7 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotLogging.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
@ -201,13 +202,13 @@ char* DumpRegion::expand_top_to(char* newtop) {
commit_to(newtop);
_top = newtop;
if (_max_delta > 0) {
if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(_base)) {
uintx delta = ArchiveBuilder::current()->buffer_to_offset((address)(newtop-1));
if (delta > _max_delta) {
if (delta > AOTCompressedPointers::MaxMetadataOffsetBytes) {
// This is just a sanity check and should not appear in any real world usage. This
// happens only if you allocate more than 2GB of shared objects and would require
// millions of shared classes.
aot_log_error(aot)("Out of memory in the CDS archive: Please reduce the number of shared classes.");
aot_log_error(aot)("Out of memory in the %s: Please reduce the number of shared classes.", CDSConfig::type_of_archive_being_written());
AOTMetaspace::unrecoverable_writing_error();
}
}
@ -331,9 +332,8 @@ void WriteClosure::do_ptr(void** p) {
void ReadClosure::do_ptr(void** p) {
assert(*p == nullptr, "initializing previous initialized pointer.");
intptr_t obj = nextPtr();
assert(obj >= 0, "sanity.");
*p = (obj != 0) ? (void*)(_base_address + obj) : (void*)obj;
u4 narrowp = checked_cast<u4>(nextPtr());
*p = AOTCompressedPointers::decode<void*>(cast_from_u4(narrowp), _base_address);
}
void ReadClosure::do_u4(u4* p) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@ -153,7 +153,6 @@ private:
char* _base;
char* _top;
char* _end;
uintx _max_delta;
bool _is_packed;
ReservedSpace* _rs;
VirtualSpace* _vs;
@ -161,9 +160,9 @@ private:
void commit_to(char* newtop);
public:
DumpRegion(const char* name, uintx max_delta = 0)
DumpRegion(const char* name)
: _name(name), _base(nullptr), _top(nullptr), _end(nullptr),
_max_delta(max_delta), _is_packed(false),
_is_packed(false),
_rs(nullptr), _vs(nullptr) {}
char* expand_top_to(char* newtop);
@ -237,13 +236,13 @@ public:
class ReadClosure : public SerializeClosure {
private:
intptr_t** _ptr_array;
intptr_t _base_address;
address _base_address;
inline intptr_t nextPtr() {
return *(*_ptr_array)++;
}
public:
ReadClosure(intptr_t** ptr_array, intptr_t base_address) :
ReadClosure(intptr_t** ptr_array, address base_address) :
_ptr_array(ptr_array), _base_address(base_address) {}
void do_ptr(void** p);
@ -260,7 +259,6 @@ class ArchiveUtils {
template <typename T> static Array<T>* archive_ptr_array(GrowableArray<T>* tmp_array);
public:
static const uintx MAX_SHARED_DELTA = 0x7FFFFFFF;
static void log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) NOT_CDS_RETURN;
static bool has_aot_initialized_mirror(InstanceKlass* src_ik);
@ -273,50 +271,6 @@ public:
static Array<T>* archive_array(GrowableArray<T>* tmp_array) {
return archive_ptr_array(tmp_array);
}
// The following functions translate between a u4 offset and an address in the
// the range of the mapped CDS archive (e.g., Metaspace::in_aot_cache()).
// Since the first 16 bytes in this range are dummy data (see ArchiveBuilder::reserve_buffer()),
// we know that offset 0 never represents a valid object. As a result, an offset of 0
// is used to encode a nullptr.
//
// Use the "archived_address_or_null" variants if a nullptr may be encoded.
// offset must represent an object of type T in the mapped shared space. Return
// a direct pointer to this object.
template <typename T> T static offset_to_archived_address(u4 offset) {
assert(offset != 0, "sanity");
T p = (T)(SharedBaseAddress + offset);
assert(Metaspace::in_aot_cache(p), "must be");
return p;
}
template <typename T> T static offset_to_archived_address_or_null(u4 offset) {
if (offset == 0) {
return nullptr;
} else {
return offset_to_archived_address<T>(offset);
}
}
// p must be an archived object. Get its offset from SharedBaseAddress
template <typename T> static u4 archived_address_to_offset(T p) {
uintx pn = (uintx)p;
uintx base = (uintx)SharedBaseAddress;
assert(Metaspace::in_aot_cache(p), "must be");
assert(pn > base, "sanity"); // No valid object is stored at 0 offset from SharedBaseAddress
uintx offset = pn - base;
assert(offset <= MAX_SHARED_DELTA, "range check");
return static_cast<u4>(offset);
}
template <typename T> static u4 archived_address_or_null_to_offset(T p) {
if (p == nullptr) {
return 0;
} else {
return archived_address_to_offset<T>(p);
}
}
};
class HeapRootSegments {

View File

@ -25,6 +25,7 @@
#include "cds/aotArtifactFinder.hpp"
#include "cds/aotClassLinker.hpp"
#include "cds/aotClassLocation.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotLogging.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
@ -75,13 +76,13 @@ public:
return 0;
}
u4 a_offset = ArchiveBuilder::current()->any_to_offset_u4(a_name);
u4 b_offset = ArchiveBuilder::current()->any_to_offset_u4(b_name);
u4 a_narrowp = cast_to_u4(AOTCompressedPointers::encode_not_null(a_name));
u4 b_narrowp = cast_to_u4(AOTCompressedPointers::encode_not_null(b_name));
if (a_offset < b_offset) {
if (a_narrowp < b_narrowp) {
return -1;
} else {
assert(a_offset > b_offset, "must be");
assert(a_narrowp > b_narrowp, "must be");
return 1;
}
}

View File

@ -298,11 +298,11 @@ void FileMapHeader::print(outputStream* st) {
st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs);
st->print_cr("- narrow_klass_pointer_bits: %d", _narrow_klass_pointer_bits);
st->print_cr("- narrow_klass_shift: %d", _narrow_klass_shift);
st->print_cr("- cloned_vtables_offset: 0x%zx", _cloned_vtables_offset);
st->print_cr("- early_serialized_data_offset: 0x%zx", _early_serialized_data_offset);
st->print_cr("- serialized_data_offset: 0x%zx", _serialized_data_offset);
st->print_cr("- cloned_vtables: %u", cast_to_u4(_cloned_vtables));
st->print_cr("- early_serialized_data: %u", cast_to_u4(_early_serialized_data));
st->print_cr("- serialized_data: %u", cast_to_u4(_serialized_data));
st->print_cr("- jvm_ident: %s", _jvm_ident);
st->print_cr("- class_location_config_offset: 0x%zx", _class_location_config_offset);
st->print_cr("- class_location_config: %d", cast_to_u4(_class_location_config));
st->print_cr("- verify_local: %d", _verify_local);
st->print_cr("- verify_remote: %d", _verify_remote);
st->print_cr("- has_platform_or_app_classes: %d", _has_platform_or_app_classes);
@ -1767,10 +1767,6 @@ void FileMapInfo::print(outputStream* st) const {
}
}
void FileMapHeader::set_as_offset(char* p, size_t *offset) {
*offset = ArchiveBuilder::current()->any_to_offset((address)p);
}
int FileMapHeader::compute_crc() {
char* start = (char*)this;
// start computing from the field after _header_size to end of base archive name.

View File

@ -25,6 +25,7 @@
#ifndef SHARE_CDS_FILEMAP_HPP
#define SHARE_CDS_FILEMAP_HPP
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotMappedHeap.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/aotStreamedHeap.hpp"
@ -104,7 +105,7 @@ public:
class FileMapHeader: private CDSFileMapHeaderBase {
friend class CDSConstants;
friend class VMStructs;
using narrowPtr = AOTCompressedPointers::narrowPtr;
private:
// The following fields record the states of the VM during dump time.
// They are compared with the runtime states to see if the archive
@ -122,16 +123,16 @@ private:
bool _compressed_class_ptrs; // save the flag UseCompressedClassPointers
int _narrow_klass_pointer_bits; // save number of bits in narrowKlass
int _narrow_klass_shift; // save shift width used to pre-compute narrowKlass IDs in archived heap objects
size_t _cloned_vtables_offset; // The address of the first cloned vtable
size_t _early_serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
size_t _serialized_data_offset; // Data accessed using {ReadClosure,WriteClosure}::serialize()
narrowPtr _cloned_vtables; // The address of the first cloned vtable
narrowPtr _early_serialized_data; // Data accessed using {ReadClosure,WriteClosure}::serialize()
narrowPtr _serialized_data; // Data accessed using {ReadClosure,WriteClosure}::serialize()
// The following fields are all sanity checks for whether this archive
// will function correctly with this JVM and the bootclasspath it's
// invoked with.
char _jvm_ident[JVM_IDENT_MAX]; // identifier string of the jvm that created this dump
size_t _class_location_config_offset;
narrowPtr _class_location_config;
bool _verify_local; // BytecodeVerificationLocal setting
bool _verify_remote; // BytecodeVerificationRemote setting
@ -160,12 +161,8 @@ private:
bool _type_profile_casts;
int _spec_trap_limit_extra_entries;
template <typename T> T from_mapped_offset(size_t offset) const {
return (T)(mapped_base_address() + offset);
}
void set_as_offset(char* p, size_t *offset);
template <typename T> void set_as_offset(T p, size_t *offset) {
set_as_offset((char*)p, offset);
template <typename T> T decode(narrowPtr narrowp) const {
return AOTCompressedPointers::decode_not_null<T>(narrowp, reinterpret_cast<address>(mapped_base_address()));
}
public:
@ -193,9 +190,9 @@ public:
bool compact_headers() const { return _compact_headers; }
uintx max_heap_size() const { return _max_heap_size; }
CompressedOops::Mode narrow_oop_mode() const { return _narrow_oop_mode; }
char* cloned_vtables() const { return from_mapped_offset<char*>(_cloned_vtables_offset); }
char* early_serialized_data() const { return from_mapped_offset<char*>(_early_serialized_data_offset); }
char* serialized_data() const { return from_mapped_offset<char*>(_serialized_data_offset); }
char* cloned_vtables() const { return decode<char*>(_cloned_vtables); }
char* early_serialized_data() const { return decode<char*>(_early_serialized_data); }
char* serialized_data() const { return decode<char*>(_serialized_data); }
bool object_streaming_mode() const { return _object_streaming_mode; }
const char* jvm_ident() const { return _jvm_ident; }
char* requested_base_address() const { return _requested_base_address; }
@ -218,9 +215,9 @@ public:
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); }
void set_early_serialized_data(char* p) { set_as_offset(p, &_early_serialized_data_offset); }
void set_serialized_data(char* p) { set_as_offset(p, &_serialized_data_offset); }
void set_cloned_vtables(char* p) { _cloned_vtables = AOTCompressedPointers::encode_not_null(p); }
void set_early_serialized_data(char* p) { _early_serialized_data = AOTCompressedPointers::encode_not_null(p); }
void set_serialized_data(char* p) { _serialized_data = AOTCompressedPointers::encode_not_null(p); }
void set_mapped_base_address(char* p) { _mapped_base_address = p; }
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; }
@ -228,11 +225,11 @@ public:
void copy_base_archive_name(const char* name);
void set_class_location_config(AOTClassLocationConfig* table) {
set_as_offset(table, &_class_location_config_offset);
_class_location_config = AOTCompressedPointers::encode_not_null(table);
}
AOTClassLocationConfig* class_location_config() {
return from_mapped_offset<AOTClassLocationConfig*>(_class_location_config_offset);
return decode<AOTClassLocationConfig*>(_class_location_config);
}
void set_requested_base(char* b) {

View File

@ -25,6 +25,7 @@
#include "cds/aotArtifactFinder.hpp"
#include "cds/aotClassInitializer.hpp"
#include "cds/aotClassLocation.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotLogging.hpp"
#include "cds/aotMappedHeapLoader.hpp"
#include "cds/aotMappedHeapWriter.hpp"
@ -1148,8 +1149,7 @@ public:
ArchivedKlassSubGraphInfoRecord* record = HeapShared::archive_subgraph_info(&info);
Klass* buffered_k = ArchiveBuilder::get_buffered_klass(klass);
unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)buffered_k);
u4 delta = ArchiveBuilder::current()->any_to_offset_u4(record);
_writer->add(hash, delta);
_writer->add(hash, AOTCompressedPointers::encode_not_null(record));
}
return true; // keep on iterating
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -23,6 +23,7 @@
*/
#include "cds/aotClassFilter.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/cdsConfig.hpp"
@ -52,7 +53,7 @@
#include "runtime/mutexLocker.hpp"
GrowableArrayCHeap<char*, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr;
Array<u4>* LambdaFormInvokers::_static_archive_invokers = nullptr;
Array<AOTCompressedPointers::narrowPtr>* LambdaFormInvokers::_static_archive_invokers = nullptr;
static bool _stop_appending = false;
#define NUM_FILTER 4
@ -252,7 +253,7 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
}
}
if (count > 0) {
_static_archive_invokers = ArchiveBuilder::new_ro_array<u4>(count);
_static_archive_invokers = ArchiveBuilder::new_ro_array<narrowPtr>(count);
int index = 0;
for (int i = 0; i < len; i++) {
char* str = _lambdaform_lines->at(i);
@ -261,7 +262,7 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
Array<char>* line = ArchiveBuilder::new_ro_array<char>((int)str_len);
strncpy(line->adr_at(0), str, str_len);
_static_archive_invokers->at_put(index, ArchiveBuilder::current()->any_to_offset_u4(line));
_static_archive_invokers->at_put(index, AOTCompressedPointers::encode_not_null(line));
index++;
}
}
@ -274,8 +275,8 @@ void LambdaFormInvokers::dump_static_archive_invokers() {
void LambdaFormInvokers::read_static_archive_invokers() {
if (_static_archive_invokers != nullptr) {
for (int i = 0; i < _static_archive_invokers->length(); i++) {
u4 offset = _static_archive_invokers->at(i);
Array<char>* line = ArchiveUtils::offset_to_archived_address<Array<char>*>(offset);
narrowPtr encoded = _static_archive_invokers->at(i);
Array<char>* line = AOTCompressedPointers::decode_not_null<Array<char>*>(encoded);
char* str = line->adr_at(0);
append(str);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -24,6 +24,8 @@
#ifndef SHARE_CDS_LAMBDAFORMINVOKERS_HPP
#define SHARE_CDS_LAMBDAFORMINVOKERS_HPP
#include "cds/aotCompressedPointers.hpp"
#include "memory/allStatic.hpp"
#include "oops/oopHandle.hpp"
#include "runtime/handles.hpp"
@ -35,10 +37,11 @@ class Array;
class SerializeClosure;
class LambdaFormInvokers : public AllStatic {
using narrowPtr = AOTCompressedPointers::narrowPtr;
private:
static GrowableArrayCHeap<char*, mtClassShared>* _lambdaform_lines;
// For storing LF form lines (LF_RESOLVE only) in read only table.
static Array<u4>* _static_archive_invokers;
static Array<narrowPtr>* _static_archive_invokers;
static void regenerate_class(char* name, ClassFileStream& st, TRAPS);
public:
static void append(char* line);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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
@ -23,6 +23,7 @@
*/
#include "cds/aotClassFilter.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/cdsConfig.hpp"
#include "cds/cdsProtectionDomain.hpp"
@ -49,11 +50,11 @@ unsigned int LambdaProxyClassKey::hash() const {
}
unsigned int RunTimeLambdaProxyClassKey::hash() const {
return primitive_hash<u4>(_caller_ik) +
primitive_hash<u4>(_invoked_name) +
primitive_hash<u4>(_invoked_type) +
primitive_hash<u4>(_method_type) +
primitive_hash<u4>(_instantiated_method_type);
return primitive_hash<u4>(cast_to_u4(_caller_ik)) +
primitive_hash<u4>(cast_to_u4(_invoked_name)) +
primitive_hash<u4>(cast_to_u4(_invoked_type)) +
primitive_hash<u4>(cast_to_u4(_method_type)) +
primitive_hash<u4>(cast_to_u4(_instantiated_method_type));
}
#ifndef PRODUCT
@ -71,12 +72,12 @@ void LambdaProxyClassKey::print_on(outputStream* st) const {
void RunTimeLambdaProxyClassKey::print_on(outputStream* st) const {
ResourceMark rm;
st->print_cr("LambdaProxyClassKey : " INTPTR_FORMAT " hash: %0x08x", p2i(this), hash());
st->print_cr("_caller_ik : %d", _caller_ik);
st->print_cr("_instantiated_method_type : %d", _instantiated_method_type);
st->print_cr("_invoked_name : %d", _invoked_name);
st->print_cr("_invoked_type : %d", _invoked_type);
st->print_cr("_member_method : %d", _member_method);
st->print_cr("_method_type : %d", _method_type);
st->print_cr("_caller_ik : %d", cast_to_u4(_caller_ik));
st->print_cr("_instantiated_method_type : %d", cast_to_u4(_instantiated_method_type));
st->print_cr("_invoked_name : %d", cast_to_u4(_invoked_name));
st->print_cr("_invoked_type : %d", cast_to_u4(_invoked_type));
st->print_cr("_member_method : %d", cast_to_u4(_member_method));
st->print_cr("_method_type : %d", cast_to_u4(_method_type));
}
void RunTimeLambdaProxyClassInfo::print_on(outputStream* st) const {
@ -418,8 +419,7 @@ public:
(RunTimeLambdaProxyClassInfo*)ArchiveBuilder::ro_region_alloc(byte_size);
runtime_info->init(key, info);
unsigned int hash = runtime_info->hash();
u4 delta = _builder->any_to_offset_u4((void*)runtime_info);
_writer->add(hash, delta);
_writer->add(hash, AOTCompressedPointers::encode_not_null(runtime_info));
return true;
}
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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,8 +25,9 @@
#ifndef SHARE_CDS_LAMBDAPROXYCLASSINFO_HPP
#define SHARE_CDS_LAMBDAPROXYCLASSINFO_HPP
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
#include "classfile/compactHashtable.hpp"
#include "classfile/javaClasses.hpp"
#include "memory/metaspaceClosure.hpp"
#include "utilities/growableArray.hpp"
@ -132,19 +133,20 @@ public:
};
class RunTimeLambdaProxyClassKey {
u4 _caller_ik;
u4 _invoked_name;
u4 _invoked_type;
u4 _method_type;
u4 _member_method;
u4 _instantiated_method_type;
using narrowPtr = AOTCompressedPointers::narrowPtr;
narrowPtr _caller_ik;
narrowPtr _invoked_name;
narrowPtr _invoked_type;
narrowPtr _method_type;
narrowPtr _member_method;
narrowPtr _instantiated_method_type;
RunTimeLambdaProxyClassKey(u4 caller_ik,
u4 invoked_name,
u4 invoked_type,
u4 method_type,
u4 member_method,
u4 instantiated_method_type) :
RunTimeLambdaProxyClassKey(narrowPtr caller_ik,
narrowPtr invoked_name,
narrowPtr invoked_type,
narrowPtr method_type,
narrowPtr member_method,
narrowPtr instantiated_method_type) :
_caller_ik(caller_ik),
_invoked_name(invoked_name),
_invoked_type(invoked_type),
@ -154,15 +156,12 @@ class RunTimeLambdaProxyClassKey {
public:
static RunTimeLambdaProxyClassKey init_for_dumptime(LambdaProxyClassKey& key) {
assert(ArchiveBuilder::is_active(), "sanity");
ArchiveBuilder* b = ArchiveBuilder::current();
u4 caller_ik = b->any_to_offset_u4(key.caller_ik());
u4 invoked_name = b->any_to_offset_u4(key.invoked_name());
u4 invoked_type = b->any_to_offset_u4(key.invoked_type());
u4 method_type = b->any_to_offset_u4(key.method_type());
u4 member_method = b->any_or_null_to_offset_u4(key.member_method()); // could be null
u4 instantiated_method_type = b->any_to_offset_u4(key.instantiated_method_type());
narrowPtr caller_ik = AOTCompressedPointers::encode_not_null(key.caller_ik());
narrowPtr invoked_name = AOTCompressedPointers::encode_not_null(key.invoked_name());
narrowPtr invoked_type = AOTCompressedPointers::encode_not_null(key.invoked_type());
narrowPtr method_type = AOTCompressedPointers::encode_not_null(key.method_type());
narrowPtr member_method = AOTCompressedPointers::encode(key.member_method()); // could be null
narrowPtr instantiated_method_type = AOTCompressedPointers::encode_not_null(key.instantiated_method_type());
return RunTimeLambdaProxyClassKey(caller_ik, invoked_name, invoked_type, method_type,
member_method, instantiated_method_type);
@ -176,12 +175,12 @@ public:
Symbol* instantiated_method_type) {
// All parameters must be in shared space, or else you'd get an assert in
// ArchiveUtils::to_offset().
return RunTimeLambdaProxyClassKey(ArchiveUtils::archived_address_to_offset(caller_ik),
ArchiveUtils::archived_address_to_offset(invoked_name),
ArchiveUtils::archived_address_to_offset(invoked_type),
ArchiveUtils::archived_address_to_offset(method_type),
ArchiveUtils::archived_address_or_null_to_offset(member_method), // could be null
ArchiveUtils::archived_address_to_offset(instantiated_method_type));
return RunTimeLambdaProxyClassKey(AOTCompressedPointers::encode_address_in_cache(caller_ik),
AOTCompressedPointers::encode_address_in_cache(invoked_name),
AOTCompressedPointers::encode_address_in_cache(invoked_type),
AOTCompressedPointers::encode_address_in_cache(method_type),
AOTCompressedPointers::encode_address_in_cache_or_null(member_method), // could be null
AOTCompressedPointers::encode_address_in_cache(instantiated_method_type));
}
unsigned int hash() const;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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
@ -22,15 +22,15 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/dumpTimeClassInfo.hpp"
#include "cds/runTimeClassInfo.hpp"
#include "classfile/systemDictionaryShared.hpp"
void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
ArchiveBuilder* builder = ArchiveBuilder::current();
InstanceKlass* k = info._klass;
_klass_offset = builder->any_to_offset_u4(k);
_klass = AOTCompressedPointers::encode_not_null(k);
if (!SystemDictionaryShared::is_builtin(k)) {
CrcInfo* c = crc();
@ -50,8 +50,8 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
RTVerifierConstraint* vf_constraints = verifier_constraints();
char* flags = verifier_constraint_flags();
for (i = 0; i < _num_verifier_constraints; i++) {
vf_constraints[i]._name = builder->any_to_offset_u4(info._verifier_constraints->at(i).name());
vf_constraints[i]._from_name = builder->any_or_null_to_offset_u4(info._verifier_constraints->at(i).from_name());
vf_constraints[i]._name = AOTCompressedPointers::encode_not_null(info._verifier_constraints->at(i).name());
vf_constraints[i]._from_name = AOTCompressedPointers::encode(info._verifier_constraints->at(i).from_name());
}
for (i = 0; i < _num_verifier_constraints; i++) {
flags[i] = info._verifier_constraint_flags->at(i);
@ -61,14 +61,14 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
if (_num_loader_constraints > 0) {
RTLoaderConstraint* ld_constraints = loader_constraints();
for (i = 0; i < _num_loader_constraints; i++) {
ld_constraints[i]._name = builder->any_to_offset_u4(info._loader_constraints->at(i).name());
ld_constraints[i]._name = AOTCompressedPointers::encode_not_null(info._loader_constraints->at(i).name());
ld_constraints[i]._loader_type1 = info._loader_constraints->at(i).loader_type1();
ld_constraints[i]._loader_type2 = info._loader_constraints->at(i).loader_type2();
}
}
if (k->is_hidden() && info.nest_host() != nullptr) {
_nest_host_offset = builder->any_to_offset_u4(info.nest_host());
_nest_host = AOTCompressedPointers::encode_not_null(info.nest_host());
}
if (k->has_archived_enum_objs()) {
int num = info.num_enum_klass_static_fields();
@ -83,11 +83,12 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
InstanceKlass* RunTimeClassInfo::klass() const {
if (AOTMetaspace::in_aot_cache(this)) {
// <this> is inside a mmaped CDS archive.
return ArchiveUtils::offset_to_archived_address<InstanceKlass*>(_klass_offset);
return AOTCompressedPointers::decode_not_null<InstanceKlass*>(_klass);
} else {
// <this> is a temporary copy of a RunTimeClassInfo that's being initialized
// by the ArchiveBuilder.
return ArchiveBuilder::current()->offset_to_buffered<InstanceKlass*>(_klass_offset);
size_t byte_offset = AOTCompressedPointers::get_byte_offset(_klass);
return ArchiveBuilder::current()->offset_to_buffered<InstanceKlass*>(byte_offset);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 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,6 +25,7 @@
#ifndef SHARE_CDS_RUNTIMECLASSINFO_HPP
#define SHARE_CDS_RUNTIMECLASSINFO_HPP
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/archiveUtils.hpp"
@ -41,8 +42,10 @@ class Method;
class Symbol;
class RunTimeClassInfo {
public:
enum : char {
using narrowPtr = AOTCompressedPointers::narrowPtr;
public:
enum : char {
FROM_FIELD_IS_PROTECTED = 1 << 0,
FROM_IS_ARRAY = 1 << 1,
FROM_IS_OBJECT = 1 << 2
@ -56,19 +59,19 @@ class RunTimeClassInfo {
// This is different than DumpTimeClassInfo::DTVerifierConstraint. We use
// u4 instead of Symbol* to save space on 64-bit CPU.
struct RTVerifierConstraint {
u4 _name;
u4 _from_name;
Symbol* name() { return ArchiveUtils::offset_to_archived_address<Symbol*>(_name); }
narrowPtr _name;
narrowPtr _from_name;
Symbol* name() { return AOTCompressedPointers::decode_not_null<Symbol*>(_name); }
Symbol* from_name() {
return (_from_name == 0) ? nullptr : ArchiveUtils::offset_to_archived_address<Symbol*>(_from_name);
return AOTCompressedPointers::decode<Symbol*>(_from_name);
}
};
struct RTLoaderConstraint {
u4 _name;
narrowPtr _name;
char _loader_type1;
char _loader_type2;
Symbol* constraint_name() { return ArchiveUtils::offset_to_archived_address<Symbol*>(_name); }
Symbol* constraint_name() { return AOTCompressedPointers::decode_not_null<Symbol*>(_name); }
};
struct RTEnumKlassStaticFields {
int _num;
@ -76,8 +79,8 @@ class RunTimeClassInfo {
};
private:
u4 _klass_offset;
u4 _nest_host_offset;
narrowPtr _klass;
narrowPtr _nest_host;
int _num_verifier_constraints;
int _num_loader_constraints;
@ -185,7 +188,7 @@ public:
InstanceKlass* nest_host() {
assert(!ArchiveBuilder::is_active(), "not called when dumping archive");
return ArchiveUtils::offset_to_archived_address_or_null<InstanceKlass*>(_nest_host_offset);
return AOTCompressedPointers::decode<InstanceKlass*>(_nest_host); // may be null
}
RTLoaderConstraint* loader_constraints() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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,6 +25,7 @@
#ifndef SHARE_CLASSFILE_COMPACTHASHTABLE_HPP
#define SHARE_CLASSFILE_COMPACTHASHTABLE_HPP
#include "cds/aotCompressedPointers.hpp"
#include "cds/cds_globals.hpp"
#include "oops/array.hpp"
#include "oops/symbol.hpp"
@ -123,6 +124,9 @@ public:
~CompactHashtableWriter();
void add(unsigned int hash, u4 encoded_value);
void add(unsigned int hash, AOTCompressedPointers::narrowPtr encoded_value) {
add(hash, cast_to_u4(encoded_value));
}
void dump(SimpleCompactHashtable *cht, const char* table_name);
private:
@ -371,11 +375,11 @@ public:
//
// OffsetCompactHashtable -- This is used to store many types of objects
// in the CDS archive. On 64-bit platforms, we save space by using a 32-bit
// offset from the CDS base address.
// narrowPtr from the CDS base address.
template <typename V>
inline V read_value_from_compact_hashtable(address base_address, u4 offset) {
return (V)(base_address + offset);
inline V read_value_from_compact_hashtable(address base_address, u4 narrowp) {
return AOTCompressedPointers::decode_not_null<V>(cast_from_u4(narrowp), base_address);
}
template <

View File

@ -22,6 +22,7 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/cdsConfig.hpp"
#include "cds/dynamicArchive.hpp"
@ -690,7 +691,7 @@ void SymbolTable::copy_shared_symbol_table(GrowableArray<Symbol*>* symbols,
assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false),
"must not rehash during dumping");
sym->set_permanent();
writer->add(fixed_hash, builder->buffer_to_offset_u4((address)sym));
writer->add(fixed_hash, AOTCompressedPointers::encode_not_null(sym));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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,6 +25,7 @@
#include "cds/aotClassFilter.hpp"
#include "cds/aotClassLocation.hpp"
#include "cds/aotCompressedPointers.hpp"
#include "cds/aotLogging.hpp"
#include "cds/aotMetaspace.hpp"
#include "cds/archiveBuilder.hpp"
@ -1282,11 +1283,10 @@ unsigned int SystemDictionaryShared::hash_for_shared_dictionary(address ptr) {
class CopySharedClassInfoToArchive : StackObj {
CompactHashtableWriter* _writer;
bool _is_builtin;
ArchiveBuilder *_builder;
public:
CopySharedClassInfoToArchive(CompactHashtableWriter* writer,
bool is_builtin)
: _writer(writer), _is_builtin(is_builtin), _builder(ArchiveBuilder::current()) {}
: _writer(writer), _is_builtin(is_builtin) {}
void do_entry(InstanceKlass* k, DumpTimeClassInfo& info) {
if (!info.is_excluded() && info.is_builtin() == _is_builtin) {
@ -1299,11 +1299,10 @@ public:
Symbol* name = info._klass->name();
name = ArchiveBuilder::current()->get_buffered_addr(name);
hash = SystemDictionaryShared::hash_for_shared_dictionary((address)name);
u4 delta = _builder->buffer_to_offset_u4((address)record);
if (_is_builtin && info._klass->is_hidden()) {
// skip
} else {
_writer->add(hash, delta);
_writer->add(hash, AOTCompressedPointers::encode_not_null(record));
}
if (log_is_enabled(Trace, aot, hashtables)) {
ResourceMark rm;

View File

@ -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
@ -40,7 +40,7 @@
#define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
#define CDS_PREIMAGE_ARCHIVE_MAGIC 0xcafea07c
#define CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION 13
#define CURRENT_CDS_ARCHIVE_VERSION 19
#define CURRENT_CDS_ARCHIVE_VERSION 20
typedef struct CDSFileMapRegion {
int _crc; // CRC checksum of this region.

View File

@ -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
@ -22,6 +22,7 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/cdsConfig.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciMetadata.hpp"
@ -512,8 +513,7 @@ void TrainingData::dump_training_data() {
#endif // ASSERT
td = ArchiveBuilder::current()->get_buffered_addr(td);
uint hash = TrainingData::Key::cds_hash(td->key());
u4 delta = ArchiveBuilder::current()->buffer_to_offset_u4((address)td);
writer.add(hash, delta);
writer.add(hash, AOTCompressedPointers::encode_not_null(td));
}
writer.dump(&_archived_training_data_dictionary_for_dumping, "training data dictionary");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -22,9 +22,11 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/archiveBuilder.hpp"
#include "cds/archiveUtils.inline.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/compactHashtable.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/vmClasses.hpp"
@ -2933,8 +2935,7 @@ public:
assert(buffered_entry != nullptr,"sanity check");
uint hash = fp->compute_hash();
u4 delta = _builder->buffer_to_offset_u4((address)buffered_entry);
_writer->add(hash, delta);
_writer->add(hash, AOTCompressedPointers::encode_not_null(buffered_entry));
if (lsh.is_enabled()) {
address fp_runtime_addr = (address)buffered_fp + ArchiveBuilder::current()->buffer_to_requested_delta();
address entry_runtime_addr = (address)buffered_entry + ArchiveBuilder::current()->buffer_to_requested_delta();

View File

@ -25,7 +25,6 @@
#ifndef SHARE_RUNTIME_SHAREDRUNTIME_HPP
#define SHARE_RUNTIME_SHAREDRUNTIME_HPP
#include "classfile/compactHashtable.hpp"
#include "code/codeBlob.hpp"
#include "code/vmreg.hpp"
#include "interpreter/linkResolver.hpp"
@ -38,6 +37,7 @@
class AdapterHandlerEntry;
class AdapterFingerPrint;
class MetaspaceClosure;
class SerializeClosure;
class vframeStream;
// Runtime is the base class for various runtime interfaces

View File

@ -22,6 +22,7 @@
*
*/
#include "cds/aotCompressedPointers.hpp"
#include "cds/filemap.hpp"
#include "classfile/classLoaderDataGraph.hpp"
#include "classfile/javaClasses.hpp"
@ -762,7 +763,7 @@
CDS_ONLY(nonstatic_field(FileMapInfo, _header, FileMapHeader*)) \
CDS_ONLY( static_field(FileMapInfo, _current_info, FileMapInfo*)) \
CDS_ONLY(nonstatic_field(FileMapHeader, _regions[0], CDSFileMapRegion)) \
CDS_ONLY(nonstatic_field(FileMapHeader, _cloned_vtables_offset, size_t)) \
CDS_ONLY(nonstatic_field(FileMapHeader, _cloned_vtables, AOTCompressedPointers::narrowPtr)) \
CDS_ONLY(nonstatic_field(FileMapHeader, _mapped_base_address, char*)) \
CDS_ONLY(nonstatic_field(CDSFileMapRegion, _mapped_base, char*)) \
CDS_ONLY(nonstatic_field(CDSFileMapRegion, _used, size_t)) \
@ -1203,6 +1204,7 @@
\
/* all enum types */ \
\
declare_integer_type(AOTCompressedPointers::narrowPtr) \
declare_integer_type(Bytecodes::Code) \
declare_integer_type(InstanceKlass::ClassState) \
declare_integer_type(JavaThreadState) \

View File

@ -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
@ -97,10 +97,12 @@ public class FileMapInfo {
headerObj = VMObjectFactory.newObject(FileMapHeader.class, header);
// char* mapped_base_address = header->_mapped_base_address
// size_t cloned_vtable_offset = header->_cloned_vtable_offset
// narrowPtr cloned_vtable_narrowPtr = header->_cloned_vtable_offset
// size_t cloned_vtable_offset = AOTCompressedPointers::get_byte_offset(cloned_vtable_narrowPtr);
// CppVtableInfo** vtablesIndex = mapped_base_address + cloned_vtable_offset;
mapped_base_address = get_AddressField(FileMapHeader_type, header, "_mapped_base_address");
long cloned_vtable_offset = get_CIntegerField(FileMapHeader_type, header, "_cloned_vtables_offset");
long cloned_vtable_narrowPtr = get_CIntegerField(FileMapHeader_type, header, "_cloned_vtables");
long cloned_vtable_offset = cloned_vtable_narrowPtr; // Currently narrowPtr is the same as offset
vtablesIndex = mapped_base_address.addOffsetTo(cloned_vtable_offset);
// CDSFileMapRegion* rw_region = &header->_region[rw];