From 241808e13fb032b0ec192e0b7ff94891a653ac94 Mon Sep 17 00:00:00 2001 From: Andrew Dinn Date: Fri, 8 Aug 2025 09:12:08 +0000 Subject: [PATCH] 8364269: Simplify code cache API by storing adapter entry offsets in blob Reviewed-by: kvn, shade, asmehra --- src/hotspot/share/code/aotCodeCache.cpp | 43 ++++----------------- src/hotspot/share/code/aotCodeCache.hpp | 18 +++------ src/hotspot/share/code/codeBlob.cpp | 31 +++++++++++---- src/hotspot/share/code/codeBlob.hpp | 16 +++++--- src/hotspot/share/runtime/sharedRuntime.cpp | 24 ++++++------ 5 files changed, 60 insertions(+), 72 deletions(-) diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index 38974da2eeb..df2e9648b84 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -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()) { diff --git a/src/hotspot/share/code/aotCodeCache.hpp b/src/hotspot/share/code/aotCodeCache.hpp index 69fd7549b43..778ad34e448 100644 --- a/src/hotspot/share/code/aotCodeCache.hpp +++ b/src/hotspot/share/code/aotCodeCache.hpp @@ -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(); diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index cf21f1f89a4..5b87e8c5670 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -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 diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index e5e47e2c5bb..407974f0428 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -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]); }; //--------------------------------------------------------------------------------------------------- diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 554b94b56c6..149ebef4294 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -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());