diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index c3a6e0a4dc36f..93bce8c0d3bd3 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2520,6 +2520,7 @@ ArchivedAdapterTable AdapterHandlerLibrary::_aot_adapter_handler_table; #endif // INCLUDE_CDS static const int AdapterHandlerLibrary_size = 16*K; BufferBlob* AdapterHandlerLibrary::_buffer = nullptr; +volatile uint AdapterHandlerLibrary::_id_counter = 0; BufferBlob* AdapterHandlerLibrary::buffer_blob() { assert(_buffer != nullptr, "should be initialized"); @@ -2600,7 +2601,9 @@ void AdapterHandlerLibrary::initialize() { } AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint) { - return AdapterHandlerEntry::allocate(fingerprint); + uint id = (uint)AtomicAccess::add((int*)&_id_counter, 1); + assert(id > 0, "we can never overflow because AOT cache cannot contain more than 2^32 methods"); + return AdapterHandlerEntry::allocate(id, fingerprint); } AdapterHandlerEntry* AdapterHandlerLibrary::get_simple_adapter(const methodHandle& method) { @@ -2754,8 +2757,8 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& meth void AdapterHandlerLibrary::lookup_aot_cache(AdapterHandlerEntry* handler) { ResourceMark rm; - const char* name = AdapterHandlerLibrary::name(handler->fingerprint()); - const uint32_t id = AdapterHandlerLibrary::id(handler->fingerprint()); + const char* name = AdapterHandlerLibrary::name(handler); + const uint32_t id = AdapterHandlerLibrary::id(handler); CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::Adapter, id, name); if (blob != nullptr) { @@ -2850,8 +2853,8 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterHandlerEntry* handler, handler->set_adapter_blob(adapter_blob); if (!is_transient && AOTCodeCache::is_dumping_adapter()) { // try to save generated code - const char* name = AdapterHandlerLibrary::name(handler->fingerprint()); - const uint32_t id = AdapterHandlerLibrary::id(handler->fingerprint()); + const char* name = AdapterHandlerLibrary::name(handler); + const uint32_t id = AdapterHandlerLibrary::id(handler); bool success = AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name); assert(success || !AOTCodeCache::is_dumping_adapter(), "caching of adapter must be disabled"); } @@ -2991,11 +2994,22 @@ void AdapterHandlerEntry::link() { } void AdapterHandlerLibrary::link_aot_adapters() { + uint max_id = 0; assert(AOTCodeCache::is_using_adapter(), "AOT adapters code should be available"); - _aot_adapter_handler_table.iterate([](AdapterHandlerEntry* entry) { + /* It is possible that some adapters generated in assembly phase are not stored in the cache. + * That implies adapter ids of the adapters in the cache may not be contiguous. + * If the size of the _aot_adapter_handler_table is used to initialize _id_counter, then it may + * result in collision of adapter ids between AOT stored handlers and runtime generated handlers. + * To avoid such situation, initialize the _id_counter with the largest adapter id among the AOT stored handlers. + */ + _aot_adapter_handler_table.iterate([&](AdapterHandlerEntry* entry) { assert(!entry->is_linked(), "AdapterHandlerEntry is already linked!"); entry->link(); + max_id = MAX2(max_id, entry->id()); }); + // Set adapter id to the maximum id found in the AOTCache + assert(_id_counter == 0, "Did not expect new AdapterHandlerEntry to be created at this stage"); + _id_counter = max_id; } // This method is called during production run to lookup simple adapters @@ -3360,13 +3374,12 @@ bool AdapterHandlerLibrary::contains(const CodeBlob* b) { return found; } -const char* AdapterHandlerLibrary::name(AdapterFingerPrint* fingerprint) { - return fingerprint->as_basic_args_string(); +const char* AdapterHandlerLibrary::name(AdapterHandlerEntry* handler) { + return handler->fingerprint()->as_basic_args_string(); } -uint32_t AdapterHandlerLibrary::id(AdapterFingerPrint* fingerprint) { - unsigned int hash = fingerprint->compute_hash(); - return hash; +uint32_t AdapterHandlerLibrary::id(AdapterHandlerEntry* handler) { + return handler->id(); } void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b) { diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 374985ad921b6..6544e380d996b 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -686,6 +686,7 @@ class AdapterHandlerEntry : public MetaspaceObj { private: AdapterFingerPrint* _fingerprint; AdapterBlob* _adapter_blob; + uint _id; bool _linked; static const char *_entry_names[]; @@ -697,9 +698,10 @@ class AdapterHandlerEntry : public MetaspaceObj { int _saved_code_length; #endif - AdapterHandlerEntry(AdapterFingerPrint* fingerprint) : + AdapterHandlerEntry(int id, AdapterFingerPrint* fingerprint) : _fingerprint(fingerprint), _adapter_blob(nullptr), + _id(id), _linked(false) #ifdef ASSERT , _saved_code(nullptr), @@ -720,8 +722,8 @@ class AdapterHandlerEntry : public MetaspaceObj { } public: - static AdapterHandlerEntry* allocate(AdapterFingerPrint* fingerprint) { - return new(0) AdapterHandlerEntry(fingerprint); + static AdapterHandlerEntry* allocate(uint id, AdapterFingerPrint* fingerprint) { + return new(0) AdapterHandlerEntry(id, fingerprint); } static void deallocate(AdapterHandlerEntry *handler) { @@ -772,6 +774,7 @@ class AdapterHandlerEntry : public MetaspaceObj { AdapterBlob* adapter_blob() const { return _adapter_blob; } bool is_linked() const { return _linked; } + uint id() const { return _id; } AdapterFingerPrint* fingerprint() const { return _fingerprint; } #ifdef ASSERT @@ -798,6 +801,7 @@ class ArchivedAdapterTable; class AdapterHandlerLibrary: public AllStatic { friend class SharedRuntime; private: + static volatile uint _id_counter; // counter for generating unique adapter ids, range = [1,UINT_MAX] static BufferBlob* _buffer; // the temporary code buffer in CodeCache static AdapterHandlerEntry* _no_arg_handler; static AdapterHandlerEntry* _int_arg_handler; @@ -837,8 +841,8 @@ class AdapterHandlerLibrary: public AllStatic { static void print_handler(const CodeBlob* b) { print_handler_on(tty, b); } static void print_handler_on(outputStream* st, const CodeBlob* b); static bool contains(const CodeBlob* b); - static const char* name(AdapterFingerPrint* fingerprint); - static uint32_t id(AdapterFingerPrint* fingerprint); + static const char* name(AdapterHandlerEntry* handler); + static uint32_t id(AdapterHandlerEntry* handler); #ifndef PRODUCT static void print_statistics(); #endif // PRODUCT