mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-23 16:55:09 +00:00
8377307: Refactor code for AOT cache pointer compression
Reviewed-by: jsjolen, xuelei, asmehra
This commit is contained in:
parent
e515c10f3a
commit
0867f9b1b4
30
src/hotspot/share/cds/aotCompressedPointers.cpp
Normal file
30
src/hotspot/share/cds/aotCompressedPointers.cpp
Normal 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);
|
||||
}
|
||||
142
src/hotspot/share/cds/aotCompressedPointers.hpp
Normal file
142
src/hotspot/share/cds/aotCompressedPointers.hpp
Normal 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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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 <
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) \
|
||||
|
||||
@ -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];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user