8364269: Simplify code cache API by storing adapter entry offsets in blob

Reviewed-by: kvn, shade, asmehra
This commit is contained in:
Andrew Dinn 2025-08-08 09:12:08 +00:00
parent 1b3e23110b
commit 241808e13f
5 changed files with 60 additions and 72 deletions

View File

@ -799,7 +799,7 @@ bool AOTCodeCache::finish_write() {
//------------------Store/Load AOT code ----------------------
bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind, uint id, const char* name, int entry_offset_count, int* entry_offsets) {
bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind, uint id, const char* name) {
AOTCodeCache* cache = open_for_dump();
if (cache == nullptr) {
return false;
@ -883,18 +883,6 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind
return false;
}
// Write entries offsets
n = cache->write_bytes(&entry_offset_count, sizeof(int));
if (n != sizeof(int)) {
return false;
}
for (int i = 0; i < entry_offset_count; i++) {
uint32_t off = (uint32_t)entry_offsets[i];
n = cache->write_bytes(&off, sizeof(uint32_t));
if (n != sizeof(uint32_t)) {
return false;
}
}
uint entry_size = cache->_write_position - entry_position;
AOTCodeEntry* entry = new(cache) AOTCodeEntry(entry_kind, encode_id(entry_kind, id),
entry_position, entry_size, name_offset, name_size,
@ -903,13 +891,13 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind
return true;
}
bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind, BlobId id, int entry_offset_count, int* entry_offsets) {
bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind, BlobId id) {
assert(AOTCodeEntry::is_blob(entry_kind),
"wrong entry kind for blob id %s", StubInfo::name(id));
return store_code_blob(blob, entry_kind, (uint)id, StubInfo::name(id), entry_offset_count, entry_offsets);
return store_code_blob(blob, entry_kind, (uint)id, StubInfo::name(id));
}
CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, uint id, const char* name, int entry_offset_count, int* entry_offsets) {
CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, uint id, const char* name) {
AOTCodeCache* cache = open_for_use();
if (cache == nullptr) {
return nullptr;
@ -929,20 +917,20 @@ CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, uint id, c
return nullptr;
}
AOTCodeReader reader(cache, entry);
CodeBlob* blob = reader.compile_code_blob(name, entry_offset_count, entry_offsets);
CodeBlob* blob = reader.compile_code_blob(name);
log_debug(aot, codecache, stubs)("%sRead blob '%s' (id=%u, kind=%s) from AOT Code Cache",
(blob == nullptr? "Failed to " : ""), name, id, aot_code_entry_kind_name[entry_kind]);
return blob;
}
CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, BlobId id, int entry_offset_count, int* entry_offsets) {
CodeBlob* AOTCodeCache::load_code_blob(AOTCodeEntry::Kind entry_kind, BlobId id) {
assert(AOTCodeEntry::is_blob(entry_kind),
"wrong entry kind for blob id %s", StubInfo::name(id));
return load_code_blob(entry_kind, (uint)id, StubInfo::name(id), entry_offset_count, entry_offsets);
return load_code_blob(entry_kind, (uint)id, StubInfo::name(id));
}
CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets) {
CodeBlob* AOTCodeReader::compile_code_blob(const char* name) {
uint entry_position = _entry->offset();
// Read name
@ -989,21 +977,6 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co
fix_relocations(code_blob);
// Read entries offsets
offset = read_position();
int stored_count = *(int*)addr(offset);
assert(stored_count == entry_offset_count, "entry offset count mismatch, count in AOT code cache=%d, expected=%d", stored_count, entry_offset_count);
offset += sizeof(int);
set_read_position(offset);
for (int i = 0; i < stored_count; i++) {
uint32_t off = *(uint32_t*)addr(offset);
offset += sizeof(uint32_t);
const char* entry_name = (_entry->kind() == AOTCodeEntry::Adapter) ? AdapterHandlerEntry::entry_name(i) : "";
log_trace(aot, codecache, stubs)("Reading adapter '%s:%s' (0x%x) offset: 0x%x from AOT Code Cache",
stored_name, entry_name, _entry->id(), off);
entry_offsets[i] = off;
}
#ifdef ASSERT
LogStreamHandle(Trace, aot, codecache, stubs) log;
if (log.is_enabled()) {

View File

@ -332,26 +332,18 @@ public:
// save and restore API for non-enumerable code blobs
static bool store_code_blob(CodeBlob& blob,
AOTCodeEntry::Kind entry_kind,
uint id, const char* name,
int entry_offset_count = 0,
int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
uint id, const char* name) NOT_CDS_RETURN_(false);
static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
uint id, const char* name,
int entry_offset_count = 0,
int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
uint id, const char* name) NOT_CDS_RETURN_(nullptr);
// save and restore API for enumerable code blobs
static bool store_code_blob(CodeBlob& blob,
AOTCodeEntry::Kind entry_kind,
BlobId id,
int entry_offset_count = 0,
int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
BlobId id) NOT_CDS_RETURN_(false);
static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
BlobId id,
int entry_offset_count = 0,
int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
BlobId id) NOT_CDS_RETURN_(nullptr);
static uint store_entries_cnt() {
if (is_on_for_dump()) {
@ -414,7 +406,7 @@ private:
public:
AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);
CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
CodeBlob* compile_code_blob(const char* name);
ImmutableOopMapSet* read_oop_map_set();

View File

@ -389,8 +389,8 @@ void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const cha
//----------------------------------------------------------------------------------------------------
// Implementation of BufferBlob
BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, int size)
: RuntimeBlob(name, kind, size, sizeof(BufferBlob))
BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size)
: RuntimeBlob(name, kind, size, header_size)
{}
BufferBlob* BufferBlob::create(const char* name, uint buffer_size) {
@ -413,8 +413,8 @@ BufferBlob* BufferBlob::create(const char* name, uint buffer_size) {
}
BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size)
: RuntimeBlob(name, kind, cb, size, sizeof(BufferBlob), CodeOffsets::frame_never_safe, 0, nullptr)
BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size)
: RuntimeBlob(name, kind, cb, size, header_size, CodeOffsets::frame_never_safe, 0, nullptr)
{}
// Used by gtest
@ -446,12 +446,20 @@ void BufferBlob::free(BufferBlob *blob) {
//----------------------------------------------------------------------------------------------------
// Implementation of AdapterBlob
AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) :
BufferBlob("I2C/C2I adapters", CodeBlobKind::Adapter, cb, size) {
AdapterBlob::AdapterBlob(int size, CodeBuffer* cb, int entry_offset[AdapterBlob::ENTRY_COUNT]) :
BufferBlob("I2C/C2I adapters", CodeBlobKind::Adapter, cb, size, sizeof(AdapterBlob)) {
assert(entry_offset[0] == 0, "sanity check");
for (int i = 1; i < AdapterBlob::ENTRY_COUNT; i++) {
assert(entry_offset[i] > 0 && entry_offset[i] < cb->insts()->size(),
"invalid entry offset 0x%x", entry_offset[i]);
}
_c2i_offset = entry_offset[1];
_c2i_unverified_offset = entry_offset[2];
_c2i_no_clinit_check_offset = entry_offset[3];
CodeCache::commit(this);
}
AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
AdapterBlob* AdapterBlob::create(CodeBuffer* cb, int entry_offset[AdapterBlob::ENTRY_COUNT]) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
CodeCache::gc_on_allocation();
@ -460,7 +468,7 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
unsigned int size = CodeBlob::allocation_size(cb, sizeof(AdapterBlob));
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = new (size) AdapterBlob(size, cb);
blob = new (size) AdapterBlob(size, cb, entry_offset);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();
@ -468,6 +476,13 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
return blob;
}
void AdapterBlob::get_offsets(int entry_offset[ENTRY_COUNT]) {
entry_offset[0] = 0;
entry_offset[1] = _c2i_offset;
entry_offset[2] = _c2i_unverified_offset;
entry_offset[3] = _c2i_no_clinit_check_offset;
}
//----------------------------------------------------------------------------------------------------
// Implementation of VtableBlob

View File

@ -372,8 +372,8 @@ class BufferBlob: public RuntimeBlob {
private:
// Creation support
BufferBlob(const char* name, CodeBlobKind kind, int size);
BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size);
BufferBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size = sizeof(BufferBlob));
BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size = sizeof(BufferBlob));
void* operator new(size_t s, unsigned size) throw();
@ -404,12 +404,18 @@ class BufferBlob: public RuntimeBlob {
// AdapterBlob: used to hold C2I/I2C adapters
class AdapterBlob: public BufferBlob {
public:
static const int ENTRY_COUNT = 4;
private:
AdapterBlob(int size, CodeBuffer* cb);
AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
// _i2c_offset is always 0 so no need to store it
int _c2i_offset;
int _c2i_unverified_offset;
int _c2i_no_clinit_check_offset;
public:
// Creation
static AdapterBlob* create(CodeBuffer* cb);
static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]);
void get_offsets(int entry_offset[ENTRY_COUNT]);
};
//---------------------------------------------------------------------------------------------------

View File

@ -2769,12 +2769,13 @@ AdapterBlob* AdapterHandlerLibrary::lookup_aot_cache(AdapterHandlerEntry* handle
ResourceMark rm;
const char* name = AdapterHandlerLibrary::name(handler->fingerprint());
const uint32_t id = AdapterHandlerLibrary::id(handler->fingerprint());
int offsets[AdapterHandlerEntry::ENTRIES_COUNT];
int offsets[AdapterBlob::ENTRY_COUNT];
AdapterBlob* adapter_blob = nullptr;
CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::Adapter, id, name, AdapterHandlerEntry::ENTRIES_COUNT, offsets);
CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::Adapter, id, name);
if (blob != nullptr) {
adapter_blob = blob->as_adapter_blob();
adapter_blob->get_offsets(offsets);
address i2c_entry = adapter_blob->content_begin();
assert(offsets[0] == 0, "sanity check");
handler->set_entry_points(i2c_entry, i2c_entry + offsets[1], i2c_entry + offsets[2], i2c_entry + offsets[3]);
@ -2837,7 +2838,15 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob,
}
#endif
adapter_blob = AdapterBlob::create(&buffer);
int entry_offset[AdapterBlob::ENTRY_COUNT];
assert(AdapterBlob::ENTRY_COUNT == 4, "sanity");
address i2c_entry = handler->get_i2c_entry();
entry_offset[0] = 0; // i2c_entry offset
entry_offset[1] = handler->get_c2i_entry() - i2c_entry;
entry_offset[2] = handler->get_c2i_unverified_entry() - i2c_entry;
entry_offset[3] = handler->get_c2i_no_clinit_check_entry() - i2c_entry;
adapter_blob = AdapterBlob::create(&buffer, entry_offset);
if (adapter_blob == nullptr) {
// CodeCache is full, disable compilation
// Ought to log this but compile log is only per compile thread
@ -2848,14 +2857,7 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob,
// try to save generated code
const char* name = AdapterHandlerLibrary::name(handler->fingerprint());
const uint32_t id = AdapterHandlerLibrary::id(handler->fingerprint());
int entry_offset[AdapterHandlerEntry::ENTRIES_COUNT];
assert(AdapterHandlerEntry::ENTRIES_COUNT == 4, "sanity");
address i2c_entry = handler->get_i2c_entry();
entry_offset[0] = 0; // i2c_entry offset
entry_offset[1] = handler->get_c2i_entry() - i2c_entry;
entry_offset[2] = handler->get_c2i_unverified_entry() - i2c_entry;
entry_offset[3] = handler->get_c2i_no_clinit_check_entry() - i2c_entry;
bool success = AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name, AdapterHandlerEntry::ENTRIES_COUNT, entry_offset);
bool success = AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name);
assert(success || !AOTCodeCache::is_dumping_adapter(), "caching of adapter must be disabled");
}
handler->relocate(adapter_blob->content_begin());