diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index cf3961955f0..36d86a70029 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -144,8 +144,6 @@ CodeBuffer::~CodeBuffer() { if (_shared_trampoline_requests != nullptr) { delete _shared_trampoline_requests; } - - NOT_PRODUCT(clear_strings()); } void CodeBuffer::initialize_oop_recorder(OopRecorder* r) { @@ -1106,7 +1104,8 @@ CHeapString::~CHeapString() { // offset is a byte offset into an instruction stream (CodeBuffer, CodeBlob or // other memory buffer) and remark is a string (comment). // -AsmRemarks::AsmRemarks() : _remarks(new AsmRemarkCollection()) { +AsmRemarks::AsmRemarks() { + init(); assert(_remarks != nullptr, "Allocation failure!"); } @@ -1114,11 +1113,11 @@ AsmRemarks::~AsmRemarks() { if (_remarks != nullptr) { clear(); } - assert(_remarks == nullptr, "Must 'clear()' before deleting!"); + assert(_remarks == nullptr, "must be"); } -void AsmRemarks::init(AsmRemarks& asm_remarks) { - asm_remarks._remarks = new AsmRemarkCollection(); +void AsmRemarks::init() { + _remarks = new AsmRemarkCollection(); } const char* AsmRemarks::insert(uint offset, const char* remstr) { @@ -1166,6 +1165,7 @@ uint AsmRemarks::print(uint offset, outputStream* strm) const { // in the code generated, and thus requiring a fixed address. // DbgStrings::DbgStrings() : _strings(new DbgStringCollection()) { + init(); assert(_strings != nullptr, "Allocation failure!"); } @@ -1173,11 +1173,11 @@ DbgStrings::~DbgStrings() { if (_strings != nullptr) { clear(); } - assert(_strings == nullptr, "Must 'clear()' before deleting!"); + assert(_strings == nullptr, "must be"); } -void DbgStrings::init(DbgStrings& dbg_strings) { - dbg_strings._strings = new DbgStringCollection(); +void DbgStrings::init() { + _strings = new DbgStringCollection(); } const char* DbgStrings::insert(const char* dbgstr) { diff --git a/src/hotspot/share/asm/codeBuffer.hpp b/src/hotspot/share/asm/codeBuffer.hpp index bc4907b1bba..9cf78ad478f 100644 --- a/src/hotspot/share/asm/codeBuffer.hpp +++ b/src/hotspot/share/asm/codeBuffer.hpp @@ -426,7 +426,7 @@ class AsmRemarks { AsmRemarks(); ~AsmRemarks(); - static void init(AsmRemarks& asm_remarks); + void init(); const char* insert(uint offset, const char* remstr); @@ -454,7 +454,7 @@ class DbgStrings { DbgStrings(); ~DbgStrings(); - static void init(DbgStrings& dbg_strings); + void init(); const char* insert(const char* dbgstr); @@ -825,11 +825,6 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) { #ifndef PRODUCT AsmRemarks &asm_remarks() { return _asm_remarks; } DbgStrings &dbg_strings() { return _dbg_strings; } - - void clear_strings() { - _asm_remarks.clear(); - _dbg_strings.clear(); - } #endif // Code generation diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index fbd5f0527ba..acf13138aa0 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1114,7 +1114,7 @@ void ciEnv::make_code_usable(JavaThread* thread, ciMethod* target, bool preload, } } -void ciEnv::register_aot_method(JavaThread* thread, +nmethod* ciEnv::register_aot_method(JavaThread* thread, ciMethod* target, AbstractCompiler* compiler, nmethod* archived_nm, @@ -1125,10 +1125,6 @@ void ciEnv::register_aot_method(JavaThread* thread, address immutable_data, GrowableArray& reloc_imm_oop_list, GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& asm_remarks, - DbgStrings& dbg_strings, -#endif /* PRODUCT */ AOTCodeReader* aot_code_reader) { AOTCodeEntry* aot_code_entry = task()->aot_code_entry(); @@ -1151,7 +1147,7 @@ void ciEnv::register_aot_method(JavaThread* thread, NoSafepointVerifier nsv; if (!is_compilation_valid(thread, target, preload, true /*install_code*/, nullptr /*code_buffer*/, aot_code_entry)) { - return; + return nullptr; } nm = nmethod::new_nmethod(archived_nm, @@ -1165,8 +1161,6 @@ void ciEnv::register_aot_method(JavaThread* thread, immutable_data, reloc_imm_oop_list, reloc_imm_metadata_list, - NOT_PRODUCT_ARG(asm_remarks) - NOT_PRODUCT_ARG(dbg_strings) aot_code_reader); if (nm != nullptr) { @@ -1183,6 +1177,7 @@ void ciEnv::register_aot_method(JavaThread* thread, // The CodeCache is full. record_failure("code cache is full"); } + return nm; // safepoints are allowed again } diff --git a/src/hotspot/share/ci/ciEnv.hpp b/src/hotspot/share/ci/ciEnv.hpp index 116f8d59b7b..f17121f93ac 100644 --- a/src/hotspot/share/ci/ciEnv.hpp +++ b/src/hotspot/share/ci/ciEnv.hpp @@ -372,22 +372,18 @@ class ciEnv : StackObj { int compile_id(); // task()->compile_id() // Register method loaded from AOT code cache - void register_aot_method(JavaThread* thread, - ciMethod* target, - AbstractCompiler* compiler, - nmethod* archived_nm, - address reloc_data, - GrowableArray& oop_list, - GrowableArray& metadata_list, - ImmutableOopMapSet* oopmaps, - address immutable_data, - GrowableArray& reloc_imm_oop_list, - GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& asm_remarks, - DbgStrings& dbg_strings, -#endif /* PRODUCT */ - AOTCodeReader* aot_code_reader); + nmethod* register_aot_method(JavaThread* thread, + ciMethod* target, + AbstractCompiler* compiler, + nmethod* archived_nm, + address reloc_data, + GrowableArray& oop_list, + GrowableArray& metadata_list, + ImmutableOopMapSet* oopmaps, + address immutable_data, + GrowableArray& reloc_imm_oop_list, + GrowableArray& reloc_imm_metadata_list, + AOTCodeReader* aot_code_reader); // Register the result of a compilation. void register_method(ciMethod* target, diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index f08791f9b96..7f437d04567 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -24,7 +24,6 @@ #include "asm/macroAssembler.hpp" -#include "asm/codeBuffer.hpp" #include "cds/aotCacheAccess.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" @@ -1416,10 +1415,10 @@ bool AOTCodeCache::store_code_blob(CodeBlob& blob, AOTCodeEntry::Kind entry_kind #ifndef PRODUCT // Write asm remarks - if (!cache->write_asm_remarks(blob)) { + if (!cache->write_asm_remarks(blob.asm_remarks(), /* use_string_table */ true)) { return false; } - if (!cache->write_dbg_strings(blob)) { + if (!cache->write_dbg_strings(blob.dbg_strings(), /* use_string_table */ true)) { return false; } #endif /* PRODUCT */ @@ -1491,7 +1490,7 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co } // Read archived code blob - uint offset = entry_position + _entry->blob_offset(); + uint offset = entry_position + _entry->code_offset(); CodeBlob* archived_blob = (CodeBlob*)addr(offset); offset += archived_blob->size(); @@ -1504,26 +1503,22 @@ CodeBlob* AOTCodeReader::compile_code_blob(const char* name, int entry_offset_co oop_maps = read_oop_map_set(); } -#ifndef PRODUCT - AsmRemarks asm_remarks; - read_asm_remarks(asm_remarks); - DbgStrings dbg_strings; - read_dbg_strings(dbg_strings); -#endif // PRODUCT - CodeBlob* code_blob = CodeBlob::create(archived_blob, stored_name, reloc_data, oop_maps -#ifndef PRODUCT - , asm_remarks - , dbg_strings -#endif ); if (code_blob == nullptr) { // no space left in CodeCache return nullptr; } +#ifndef PRODUCT + code_blob->asm_remarks().init(); + read_asm_remarks(code_blob->asm_remarks(), /* use_string_table */ true); + code_blob->dbg_strings().init(); + read_dbg_strings(code_blob->dbg_strings(), /* use_string_table */ true); +#endif // PRODUCT + fix_relocations(code_blob); // Read entries offsets @@ -1601,8 +1596,8 @@ bool AOTCodeCache::store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const c } uint entry_size = cache->_write_position - entry_position; AOTCodeEntry* entry = new(cache) AOTCodeEntry(entry_position, entry_size, name_offset, name_size, - code_offset, code_size, 0, 0, - AOTCodeEntry::Stub, (uint32_t)id); + code_offset, code_size, + AOTCodeEntry::Stub, (uint32_t)id); log_info(aot, codecache, stubs)("Wrote stub '%s' id:%d to AOT Code Cache", name, (int)id); return true; } @@ -1676,6 +1671,8 @@ AOTCodeEntry* AOTCodeCache::store_nmethod(nmethod* nm, AbstractCompiler* compile } AOTCodeEntry* AOTCodeCache::write_nmethod(nmethod* nm, bool for_preload) { + AOTCodeCache* cache = open_for_dump(); + assert(cache != nullptr, "sanity check"); assert(!nm->has_clinit_barriers() || _gen_preload_code, "sanity"); uint comp_id = nm->compile_id(); uint comp_level = nm->comp_level(); @@ -1755,60 +1752,17 @@ AOTCodeEntry* AOTCodeCache::write_nmethod(nmethod* nm, bool for_preload) { } hash = java_lang_String::hash_code((const jbyte*)name, (int)strlen(name)); } - uint archived_nm_offset = _write_position - entry_position; - nmethod* archived_nm = (nmethod*)reserve_bytes(nm->size()); - if (archived_nm == nullptr) { - return nullptr; - } - nm->copy_to((address)archived_nm); - archived_nm->prepare_for_archiving(); - -#ifndef PRODUCT - // Write asm remarks - uint* count_ptr = (uint *)reserve_bytes(sizeof(uint)); - if (count_ptr == nullptr) { - return nullptr; - } - uint count = 0; - bool result = nm->asm_remarks().iterate([&] (uint offset, const char* str) -> bool { - log_info(aot, codecache, nmethod)("asm remark offset=%d, str=%s", offset, str); - n = write_bytes(&offset, sizeof(uint)); - if (n != sizeof(uint)) { - return false; - } - n = write_bytes(str, (uint)strlen(str) + 1); - if (n != strlen(str) + 1) { - return false; - } - count += 1; - return true; - }); - if (!result) { - return nullptr; - } - *count_ptr = count; - - // Write dbg strings - count_ptr = (uint *)reserve_bytes(sizeof(uint)); - if (count_ptr == nullptr) { + // Write CodeBlob + if (!cache->align_write()) { return nullptr; } - count = 0; - result = nm->dbg_strings().iterate([&] (const char* str) -> bool { - log_info(aot, codecache, nmethod)("dbg string[" INTPTR_FORMAT "]=%s", p2i(str), str); - n = write_bytes(str, (uint)strlen(str) + 1); - if (n != strlen(str) + 1) { - return false; - } - count += 1; - return true; - }); - if (!result) { + uint blob_offset = cache->_write_position - entry_position; + address archive_buffer = cache->reserve_bytes(nm->size()); + if (archive_buffer == nullptr) { return nullptr; } - *count_ptr = count; -#endif /* PRODUCT */ + CodeBlob::archive_blob(nm, archive_buffer); uint reloc_data_size = nm->relocation_size(); n = write_bytes((address)nm->relocation_begin(), reloc_data_size); @@ -1832,8 +1786,12 @@ AOTCodeEntry* AOTCodeCache::write_nmethod(nmethod* nm, bool for_preload) { return nullptr; } - if (!write_oop_map_set(*nm)) { - return nullptr; + bool has_oop_maps = false; + if (nm->oop_maps() != nullptr) { + if (!cache->write_oop_map_set(*nm)) { + return nullptr; + } + has_oop_maps = true; } uint immutable_data_size = nm->immutable_data_size(); @@ -1856,15 +1814,26 @@ AOTCodeEntry* AOTCodeCache::write_nmethod(nmethod* nm, bool for_preload) { return nullptr; } - if (!write_nmethod_loadtime_relocations(thread, nm, oop_list, metadata_list)) { + if (!write_relocations(*nm, &oop_list, &metadata_list)) { + return nullptr; + } + +#ifndef PRODUCT + if (!cache->write_asm_remarks(nm->asm_remarks(), /* use_string_table */ false)) { + return nullptr; + } + if (!cache->write_dbg_strings(nm->dbg_strings(), /* use_string_table */ false)) { return nullptr; } +#endif /* PRODUCT */ uint entry_size = _write_position - entry_position; - AOTCodeEntry* entry = new (this) AOTCodeEntry(entry_position, entry_size, name_offset, name_size, - archived_nm_offset, 0, 0, 0, - AOTCodeEntry::Code, hash, nm->content_begin(), comp_level, comp_id, decomp, - nm->has_clinit_barriers(), for_preload, ignore_decompile); + AOTCodeEntry* entry = new (this) AOTCodeEntry(AOTCodeEntry::Code, hash, + entry_position, entry_size, + name_offset, name_size, + blob_offset, has_oop_maps, + nm->content_begin(), comp_level, comp_id, decomp, + nm->has_clinit_barriers(), for_preload, ignore_decompile); if (method_in_cds) { entry->set_method(method); } @@ -1946,33 +1915,6 @@ bool AOTCodeReader::compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompil uint offset; -#ifndef PRODUCT - // Read asm remarks - offset = read_position(); - uint count = *(uint *)addr(offset); - offset += sizeof(uint); - AsmRemarks asm_remarks; - for (uint i = 0; i < count; i++) { - uint remark_offset = *(uint *)addr(offset); - offset += sizeof(uint); - const char* remark = (const char*)addr(offset); - offset += (uint)strlen(remark)+1; - asm_remarks.insert(remark_offset, remark); - } - set_read_position(offset); - - // Read dbg strings - count = *(uint *)addr(offset); - offset += sizeof(uint); - DbgStrings dbg_strings; - for (uint i = 0; i < count; i++) { - const char* str = (const char*)addr(offset); - offset += (uint)strlen(str)+1; - dbg_strings.insert(str); - } - set_read_position(offset); -#endif /* PRODUCT */ - offset = read_position(); address reloc_data = (address)addr(offset); offset += archived_nm->relocation_size(); @@ -2012,20 +1954,18 @@ bool AOTCodeReader::compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompil } TraceTime t1("Total time to register AOT nmethod", &_t_totalRegister, enable_timers(), false); - env->register_aot_method(THREAD, - target, - compiler, - archived_nm, - reloc_data, - oop_list, - metadata_list, - oopmaps, - immutable_data, - reloc_immediate_oop_list, - reloc_immediate_metadata_list, - NOT_PRODUCT_ARG(asm_remarks) - NOT_PRODUCT_ARG(dbg_strings) - this); + nm = env->register_aot_method(THREAD, + target, + compiler, + archived_nm, + reloc_data, + oop_list, + metadata_list, + oopmaps, + immutable_data, + reloc_immediate_oop_list, + reloc_immediate_metadata_list, + this); bool success = task->is_success(); if (success) { aot_code_entry->set_loaded(); @@ -2033,7 +1973,6 @@ bool AOTCodeReader::compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompil #ifdef ASSERT LogStreamHandle(Debug, aot, codecache, nmethod) log; if (log.is_enabled()) { - nmethod* nm = target->get_Method()->code(); FlagSetting fs(PrintRelocations, true); nm->print_on(&log); nm->decode2(&log); @@ -2138,7 +2077,7 @@ void AOTCodeCache::preload_startup_code(TRAPS) { // ------------ process code and data -------------- -bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { +bool AOTCodeCache::write_relocations(CodeBlob& code_blob, GrowableArray* oop_list, GrowableArray* metadata_list) { GrowableArray reloc_data; RelocIterator iter(&code_blob); LogStreamHandle(Trace, aot, codecache, reloc) log; @@ -2146,6 +2085,47 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { int idx = reloc_data.append(0); // default value switch (iter.type()) { case relocInfo::none: + break; + case relocInfo::oop_type: { + oop_Relocation* r = (oop_Relocation*)iter.reloc(); + if (r->oop_is_immediate()) { + assert(oop_list != nullptr, "sanity check"); + // store index of oop in the reloc immediate oop list + Handle h(JavaThread::current(), r->oop_value()); + int oop_idx = oop_list->find(h); + assert(oop_idx != -1, "sanity check"); + reloc_data.at_put(idx, (uint)oop_idx); + } + break; + } + case relocInfo::metadata_type: { + metadata_Relocation* r = (metadata_Relocation*)iter.reloc(); + if (r->metadata_is_immediate()) { + assert(metadata_list != nullptr, "sanity check"); + // store index of metadata in the reloc immediate metadata list + int metadata_idx = metadata_list->find(r->metadata_value()); + assert(metadata_idx != -1, "sanity check"); + reloc_data.at_put(idx, (uint)metadata_idx); + } + break; + } + case relocInfo::virtual_call_type: // Fall through. They all call resolve_*_call blobs. + case relocInfo::opt_virtual_call_type: + case relocInfo::static_call_type: { + CallRelocation* r = (CallRelocation*)iter.reloc(); + address dest = r->destination(); + if (dest == r->addr()) { // possible call via trampoline on Aarch64 + dest = (address)-1; // do nothing in this case when loading this relocation + } + reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob)); + break; + } + case relocInfo::trampoline_stub_type: { + address dest = ((trampoline_stub_Relocation*)iter.reloc())->destination(); + reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob)); + break; + } + case relocInfo::static_stub_type: break; case relocInfo::runtime_call_type: { // Record offset of runtime destination @@ -2154,7 +2134,7 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { if (dest == r->addr()) { // possible call via trampoline on Aarch64 dest = (address)-1; // do nothing in this case when loading this relocation } - reloc_data.at_put(idx, _table->id_for_address(dest, iter, nullptr, &code_blob)); + reloc_data.at_put(idx, _table->id_for_address(dest, iter, &code_blob)); break; } case relocInfo::runtime_call_w_cp_type: @@ -2163,15 +2143,21 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { case relocInfo::external_word_type: { // Record offset of runtime target address target = ((external_word_Relocation*)iter.reloc())->target(); - reloc_data.at_put(idx, _table->id_for_address(target, iter, nullptr, &code_blob)); + reloc_data.at_put(idx, _table->id_for_address(target, iter, &code_blob)); break; } case relocInfo::internal_word_type: break; case relocInfo::section_word_type: break; + case relocInfo::poll_type: + break; + case relocInfo::poll_return_type: + break; case relocInfo::post_call_nop_type: break; + case relocInfo::entry_guard_type: + break; default: fatal("relocation %d unimplemented", (int)iter.type()); break; @@ -2196,29 +2182,30 @@ bool AOTCodeCache::write_relocations(CodeBlob& code_blob) { return true; } -void AOTCodeReader::apply_relocations(nmethod* nm, GrowableArray &oop_list, GrowableArray &metadata_list) { - LogStreamHandle(Info, aot, codecache, reloc) log; - uint buffer_offset = read_position(); - int count = *(int*)addr(buffer_offset); - buffer_offset += sizeof(int); +void AOTCodeReader::fix_relocations(CodeBlob* code_blob, GrowableArray* oop_list, GrowableArray* metadata_list) { + LogStreamHandle(Trace, aot, reloc) log; + uint offset = read_position(); + int count = *(int*)addr(offset); + offset += sizeof(int); if (log.is_enabled()) { log.print_cr("======== extra relocations count=%d", count); } - uint* reloc_data = (uint*)addr(buffer_offset); - buffer_offset += (count * sizeof(uint)); - set_read_position(buffer_offset); + uint* reloc_data = (uint*)addr(offset); + offset += (count * sizeof(uint)); + set_read_position(offset); - RelocIterator iter(nm); + RelocIterator iter(code_blob); int j = 0; - while (iter.next()) { switch (iter.type()) { case relocInfo::none: break; case relocInfo::oop_type: { + assert(code_blob->is_nmethod(), "sanity check"); oop_Relocation* r = (oop_Relocation*)iter.reloc(); if (r->oop_is_immediate()) { - Handle h = oop_list.at(reloc_data[j]); + assert(oop_list != nullptr, "sanity check"); + Handle h = oop_list->at(reloc_data[j]); r->set_value(cast_from_oop
(h())); } else { r->fix_oop_relocation(); @@ -2226,14 +2213,16 @@ void AOTCodeReader::apply_relocations(nmethod* nm, GrowableArray &oop_li break; } case relocInfo::metadata_type: { + assert(code_blob->is_nmethod(), "sanity check"); metadata_Relocation* r = (metadata_Relocation*)iter.reloc(); Metadata* m; if (r->metadata_is_immediate()) { - m = metadata_list.at(reloc_data[j]); + assert(metadata_list != nullptr, "sanity check"); + m = metadata_list->at(reloc_data[j]); } else { // Get already updated value from nmethod. int index = r->metadata_index(); - m = nm->metadata_at(index); + m = code_blob->as_nmethod()->metadata_at(index); } r->set_value((address)m); break; @@ -2263,77 +2252,6 @@ void AOTCodeReader::apply_relocations(nmethod* nm, GrowableArray &oop_li } break; } - case relocInfo::runtime_call_w_cp_type: - fatal("runtime_call_w_cp_type unimplemented"); - //address destination = iter.reloc()->value(); - break; - case relocInfo::external_word_type: { - address target = _cache->address_for_id(reloc_data[j]); - // Add external address to global table - int index = ExternalsRecorder::find_index(target); - // Update index in relocation - Relocation::add_jint(iter.data(), index); - external_word_Relocation* reloc = (external_word_Relocation*)iter.reloc(); - assert(reloc->target() == target, "sanity"); - reloc->set_value(target); // Patch address in the code - break; - } - case relocInfo::internal_word_type: { - internal_word_Relocation* r = (internal_word_Relocation*)iter.reloc(); - r->fix_relocation_after_aot_load(aot_code_entry()->dumptime_content_start_addr(), nm->content_begin()); - break; - } - case relocInfo::section_word_type: { - section_word_Relocation* r = (section_word_Relocation*)iter.reloc(); - r->fix_relocation_after_aot_load(aot_code_entry()->dumptime_content_start_addr(), nm->content_begin()); - break; - } - case relocInfo::poll_type: - break; - case relocInfo::poll_return_type: - break; - case relocInfo::post_call_nop_type: - break; - case relocInfo::entry_guard_type: - break; - default: - fatal("relocation %d unimplemented", (int)iter.type()); - break; - } - if (log.is_enabled()) { - iter.print_current_on(&log); - } - j++; - } - assert(j == count, "must be"); -} - - -void AOTCodeReader::fix_relocations(CodeBlob* code_blob) { - LogStreamHandle(Trace, aot, reloc) log; - uint offset = read_position(); - int count = *(int*)addr(offset); - offset += sizeof(int); - if (log.is_enabled()) { - log.print_cr("======== extra relocations count=%d", count); - } - uint* reloc_data = (uint*)addr(offset); - offset += (count * sizeof(uint)); - set_read_position(offset); - - RelocIterator iter(code_blob); - int j = 0; - while (iter.next()) { - switch (iter.type()) { - case relocInfo::none: - break; - case relocInfo::runtime_call_type: { - address dest = _cache->address_for_id(reloc_data[j]); - if (dest != (address)-1) { - ((CallRelocation*)iter.reloc())->set_destination(dest); - } - break; - } case relocInfo::runtime_call_w_cp_type: fatal("runtime_call_w_cp_type unimplemented"); break; @@ -2358,95 +2276,6 @@ void AOTCodeReader::fix_relocations(CodeBlob* code_blob) { r->fix_relocation_after_aot_load(aot_code_entry()->dumptime_content_start_addr(), code_blob->content_begin()); break; } - case relocInfo::post_call_nop_type: - break; - default: - fatal("relocation %d unimplemented", (int)iter.type()); - break; - } - if (log.is_enabled()) { - iter.print_current_on(&log); - } - j++; - } - assert(j == count, "sanity"); -} - -bool AOTCodeCache::write_nmethod_loadtime_relocations(JavaThread* thread, nmethod* nm, GrowableArray& oop_list, GrowableArray& metadata_list) { - LogStreamHandle(Info, aot, codecache, reloc) log; - GrowableArray reloc_data; - // Collect additional data - RelocIterator iter(nm); - bool has_immediate = false; - while (iter.next()) { - int idx = reloc_data.append(0); // default value - switch (iter.type()) { - case relocInfo::none: - break; - case relocInfo::oop_type: { - oop_Relocation* r = (oop_Relocation*)iter.reloc(); - if (r->oop_is_immediate()) { - // store index of oop in the reloc immediate oop list - Handle h(thread, r->oop_value()); - int oop_idx = oop_list.find(h); - assert(oop_idx != -1, "sanity check"); - reloc_data.at_put(idx, (uint)oop_idx); - has_immediate = true; - } - break; - } - case relocInfo::metadata_type: { - metadata_Relocation* r = (metadata_Relocation*)iter.reloc(); - if (r->metadata_is_immediate()) { - // store index of metadata in the reloc immediate metadata list - int metadata_idx = metadata_list.find(r->metadata_value()); - assert(metadata_idx != -1, "sanity check"); - reloc_data.at_put(idx, (uint)metadata_idx); - has_immediate = true; - } - break; - } - case relocInfo::virtual_call_type: // Fall through. They all call resolve_*_call blobs. - case relocInfo::opt_virtual_call_type: - case relocInfo::static_call_type: { - CallRelocation* r = (CallRelocation*)iter.reloc(); - address dest = r->destination(); - if (dest == r->addr()) { // possible call via trampoline on Aarch64 - dest = (address)-1; // do nothing in this case when loading this relocation - } - reloc_data.at_put(idx, _table->id_for_address(dest, iter, nullptr, nm)); - break; - } - case relocInfo::trampoline_stub_type: { - address dest = ((trampoline_stub_Relocation*)iter.reloc())->destination(); - reloc_data.at_put(idx, _table->id_for_address(dest, iter, nullptr, nm)); - break; - } - case relocInfo::static_stub_type: - break; - case relocInfo::runtime_call_type: { - // Record offset of runtime destination - CallRelocation* r = (CallRelocation*)iter.reloc(); - address dest = r->destination(); - if (dest == r->addr()) { // possible call via trampoline on Aarch64 - dest = (address)-1; // do nothing in this case when loading this relocation - } - reloc_data.at_put(idx, _table->id_for_address(dest, iter, nullptr, nm)); - break; - } - case relocInfo::runtime_call_w_cp_type: - fatal("runtime_call_w_cp_type unimplemented"); - break; - case relocInfo::external_word_type: { - // Record offset of runtime target - address target = ((external_word_Relocation*)iter.reloc())->target(); - reloc_data.at_put(idx, _table->id_for_address(target, iter, nullptr, nm)); - break; - } - case relocInfo::internal_word_type: - break; - case relocInfo::section_word_type: - break; case relocInfo::poll_type: break; case relocInfo::poll_return_type: @@ -2462,27 +2291,9 @@ bool AOTCodeCache::write_nmethod_loadtime_relocations(JavaThread* thread, nmetho if (log.is_enabled()) { iter.print_current_on(&log); } + j++; } - - // Write additional relocation data: uint per relocation - // Write the count first - int count = reloc_data.length(); - write_bytes(&count, sizeof(int)); - uint data_size = count * sizeof(uint); - for (GrowableArrayIterator iter = reloc_data.begin(); - iter != reloc_data.end(); ++iter) { - uint value = *iter; - int n = write_bytes(&value, sizeof(uint)); - if (n != sizeof(uint)) { - return false; - break; - } - } - - if (!align_write()) { - return false; - } - return true; //success; + assert(j == count, "sanity"); } bool AOTCodeCache::write_nmethod_reloc_immediates(GrowableArray& oop_list, GrowableArray& metadata_list) { @@ -2512,59 +2323,6 @@ bool AOTCodeCache::write_nmethod_reloc_immediates(GrowableArray& oop_lis return true; } -bool AOTCodeCache::write_debug_info(DebugInformationRecorder* recorder) { - if (!align_write()) { - return false; - } - // Don't call data_size() and pcs_size(). They will freeze OopRecorder. - int data_size = recorder->stream()->position(); // In bytes - uint n = write_bytes(&data_size, sizeof(int)); - if (n != sizeof(int)) { - return false; - } - int pcs_length = recorder->pcs_length(); // In bytes - n = write_bytes(&pcs_length, sizeof(int)); - if (n != sizeof(int)) { - return false; - } - n = write_bytes(recorder->stream()->buffer(), data_size); - if (n != (uint)data_size) { - return false; - } - uint pcs_size = pcs_length * sizeof(PcDesc); - n = write_bytes(recorder->pcs(), pcs_size); - if (n != pcs_size) { - return false; - } - return true; -} - -DebugInformationRecorder* AOTCodeReader::read_debug_info(OopRecorder* oop_recorder) { - uint code_offset = align_up(read_position(), DATA_ALIGNMENT); - int data_size = *(int*)addr(code_offset); - code_offset += sizeof(int); - int pcs_length = *(int*)addr(code_offset); - code_offset += sizeof(int); - - log_debug(aot, codecache)("======== read DebugInfo [%d, %d]:", data_size, pcs_length); - - // Aligned initial sizes - int data_size_align = align_up(data_size, DATA_ALIGNMENT); - int pcs_length_align = pcs_length + 1; - assert(sizeof(PcDesc) > DATA_ALIGNMENT, "sanity"); - DebugInformationRecorder* recorder = new DebugInformationRecorder(oop_recorder, data_size_align, pcs_length); - - copy_bytes(addr(code_offset), recorder->stream()->buffer(), data_size_align); - recorder->stream()->set_position(data_size); - code_offset += data_size; - - uint pcs_size = pcs_length * sizeof(PcDesc); - copy_bytes(addr(code_offset), (address)recorder->pcs(), pcs_size); - code_offset += pcs_size; - set_read_position(code_offset); - return recorder; -} - bool AOTCodeCache::write_metadata(nmethod* nm) { int count = nm->metadata_count()-1; if (!write_bytes(&count, sizeof(int))) { @@ -2578,36 +2336,6 @@ bool AOTCodeCache::write_metadata(nmethod* nm) { return true; } -bool AOTCodeCache::write_metadata(OopRecorder* oop_recorder) { - int metadata_count = oop_recorder->metadata_count(); - uint n = write_bytes(&metadata_count, sizeof(int)); - if (n != sizeof(int)) { - return false; - } - - log_debug(aot, codecache)("======== write metadata [%d]:", metadata_count); - - for (int i = 1; i < metadata_count; i++) { // skip first virtual nullptr - Metadata* m = oop_recorder->metadata_at(i); - LogStreamHandle(Debug, aot, codecache, metadata) log; - if (log.is_enabled()) { - log.print("%d: " INTPTR_FORMAT " ", i, p2i(m)); - if (m == (Metadata*)Universe::non_oop_word()) { - log.print("non-metadata word"); - } else if (m == nullptr) { - log.print("nullptr-oop"); - } else { - Metadata::print_value_on_maybe_null(&log, m); - } - log.cr(); - } - if (!write_metadata(m)) { - return false; - } - } - return true; -} - bool AOTCodeCache::write_metadata(Metadata* m) { uint n = 0; if (m == nullptr) { @@ -2647,49 +2375,6 @@ bool AOTCodeCache::write_metadata(Metadata* m) { return true; } -bool AOTCodeReader::read_metadata(OopRecorder* oop_recorder, ciMethod* target) { - uint code_offset = read_position(); - int metadata_count = *(int*)addr(code_offset); - code_offset += sizeof(int); - set_read_position(code_offset); - - log_debug(aot, codecache)("======== read metadata [%d]:", metadata_count); - - if (metadata_count == 0) { - return true; - } - { - VM_ENTRY_MARK; - methodHandle comp_method(THREAD, target->get_Method()); - - for (int i = 1; i < metadata_count; i++) { - Metadata* m = read_metadata(comp_method); - if (lookup_failed()) { - return false; - } - if (oop_recorder->is_real(m)) { - oop_recorder->find_index(m); - } else { - oop_recorder->allocate_metadata_index(m); - } - LogTarget(Debug, aot, codecache, metadata) log; - if (log.is_enabled()) { - LogStream ls(log); - ls.print("%d: " INTPTR_FORMAT " ", i, p2i(m)); - if (m == (Metadata*)Universe::non_oop_word()) { - ls.print("non-metadata word"); - } else if (m == nullptr) { - ls.print("nullptr-oop"); - } else { - Metadata::print_value_on_maybe_null(&ls, m); - } - ls.cr(); - } - } - } - return true; -} - Metadata* AOTCodeReader::read_metadata(const methodHandle& comp_method) { uint code_offset = read_position(); Metadata* m = nullptr; @@ -3158,35 +2843,6 @@ Klass* AOTCodeReader::read_klass(const methodHandle& comp_method, bool shared) { return k; } -bool AOTCodeCache::write_oops(OopRecorder* oop_recorder) { - int oop_count = oop_recorder->oop_count(); - uint n = write_bytes(&oop_count, sizeof(int)); - if (n != sizeof(int)) { - return false; - } - log_debug(aot, codecache)("======== write oops [%d]:", oop_count); - - for (int i = 1; i < oop_count; i++) { // skip first virtual nullptr - jobject jo = oop_recorder->oop_at(i); - LogStreamHandle(Info, aot, codecache, oops) log; - if (log.is_enabled()) { - log.print("%d: " INTPTR_FORMAT " ", i, p2i(jo)); - if (jo == (jobject)Universe::non_oop_word()) { - log.print("non-oop word"); - } else if (jo == nullptr) { - log.print("nullptr-oop"); - } else { - JNIHandles::resolve(jo)->print_value_on(&log); - } - log.cr(); - } - if (!write_oop(jo)) { - return false; - } - } - return true; -} - bool AOTCodeCache::write_oop(jobject& jo) { oop obj = JNIHandles::resolve(jo); return write_oop(obj); @@ -3299,46 +2955,6 @@ bool AOTCodeCache::write_oop(oop obj) { return true; } -bool AOTCodeReader::read_oops(OopRecorder* oop_recorder, ciMethod* target) { - uint code_offset = read_position(); - int oop_count = *(int*)addr(code_offset); - code_offset += sizeof(int); - set_read_position(code_offset); - log_debug(aot, codecache)("======== read oops [%d]:", oop_count); - if (oop_count == 0) { - return true; - } - { - VM_ENTRY_MARK; - methodHandle comp_method(THREAD, target->get_Method()); - for (int i = 1; i < oop_count; i++) { - oop obj = read_oop(THREAD, comp_method); - if (lookup_failed()) { - return false; - } - jobject jo = JNIHandles::make_local(THREAD, obj); - if (oop_recorder->is_real(jo)) { - oop_recorder->find_index(jo); - } else { - oop_recorder->allocate_oop_index(jo); - } - LogStreamHandle(Debug, aot, codecache, oops) log; - if (log.is_enabled()) { - log.print("%d: " INTPTR_FORMAT " ", i, p2i(jo)); - if (jo == (jobject)Universe::non_oop_word()) { - log.print("non-oop word"); - } else if (jo == nullptr) { - log.print("nullptr-oop"); - } else { - JNIHandles::resolve(jo)->print_value_on(&log); - } - log.cr(); - } - } - } - return true; -} - oop AOTCodeReader::read_oop(JavaThread* thread, const methodHandle& comp_method) { uint code_offset = read_position(); oop obj = nullptr; @@ -3518,25 +3134,32 @@ bool AOTCodeCache::write_oops(nmethod* nm) { } #ifndef PRODUCT -bool AOTCodeCache::write_asm_remarks(CodeBlob& cb) { +bool AOTCodeCache::write_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table) { // Write asm remarks uint* count_ptr = (uint *)reserve_bytes(sizeof(uint)); if (count_ptr == nullptr) { return false; } uint count = 0; - bool result = cb.asm_remarks().iterate([&] (uint offset, const char* str) -> bool { + bool result = asm_remarks.iterate([&] (uint offset, const char* str) -> bool { log_trace(aot, codecache, stubs)("asm remark offset=%d, str='%s'", offset, str); uint n = write_bytes(&offset, sizeof(uint)); if (n != sizeof(uint)) { return false; } - const char* cstr = add_C_string(str); - int id = _table->id_for_C_string((address)cstr); - assert(id != -1, "asm remark string '%s' not found in AOTCodeAddressTable", str); - n = write_bytes(&id, sizeof(int)); - if (n != sizeof(int)) { - return false; + if (use_string_table) { + const char* cstr = add_C_string(str); + int id = _table->id_for_C_string((address)cstr); + assert(id != -1, "asm remark string '%s' not found in AOTCodeAddressTable", str); + n = write_bytes(&id, sizeof(int)); + if (n != sizeof(int)) { + return false; + } + } else { + n = write_bytes(str, (uint)strlen(str) + 1); + if (n != strlen(str) + 1) { + return false; + } } count += 1; return true; @@ -3545,7 +3168,7 @@ bool AOTCodeCache::write_asm_remarks(CodeBlob& cb) { return result; } -void AOTCodeReader::read_asm_remarks(AsmRemarks& asm_remarks) { +void AOTCodeReader::read_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table) { // Read asm remarks uint offset = read_position(); uint count = *(uint *)addr(offset); @@ -3553,29 +3176,42 @@ void AOTCodeReader::read_asm_remarks(AsmRemarks& asm_remarks) { for (uint i = 0; i < count; i++) { uint remark_offset = *(uint *)addr(offset); offset += sizeof(uint); - int remark_string_id = *(uint *)addr(offset); - offset += sizeof(int); - const char* remark = (const char*)_cache->address_for_C_string(remark_string_id); + const char* remark = nullptr; + if (use_string_table) { + int remark_string_id = *(uint *)addr(offset); + offset += sizeof(int); + remark = (const char*)_cache->address_for_C_string(remark_string_id); + } else { + remark = (const char*)addr(offset); + offset += (uint)strlen(remark)+1; + } asm_remarks.insert(remark_offset, remark); } set_read_position(offset); } -bool AOTCodeCache::write_dbg_strings(CodeBlob& cb) { +bool AOTCodeCache::write_dbg_strings(DbgStrings& dbg_strings, bool use_string_table) { // Write dbg strings uint* count_ptr = (uint *)reserve_bytes(sizeof(uint)); if (count_ptr == nullptr) { return false; } uint count = 0; - bool result = cb.dbg_strings().iterate([&] (const char* str) -> bool { + bool result = dbg_strings.iterate([&] (const char* str) -> bool { log_trace(aot, codecache, stubs)("dbg string=%s", str); - const char* cstr = add_C_string(str); - int id = _table->id_for_C_string((address)cstr); - assert(id != -1, "db string '%s' not found in AOTCodeAddressTable", str); - uint n = write_bytes(&id, sizeof(int)); - if (n != sizeof(int)) { - return false; + if (use_string_table) { + const char* cstr = add_C_string(str); + int id = _table->id_for_C_string((address)cstr); + assert(id != -1, "db string '%s' not found in AOTCodeAddressTable", str); + uint n = write_bytes(&id, sizeof(int)); + if (n != sizeof(int)) { + return false; + } + } else { + uint n = write_bytes(str, (uint)strlen(str) + 1); + if (n != strlen(str) + 1) { + return false; + } } count += 1; return true; @@ -3584,15 +3220,21 @@ bool AOTCodeCache::write_dbg_strings(CodeBlob& cb) { return result; } -void AOTCodeReader::read_dbg_strings(DbgStrings& dbg_strings) { +void AOTCodeReader::read_dbg_strings(DbgStrings& dbg_strings, bool use_string_table) { // Read dbg strings uint offset = read_position(); uint count = *(uint *)addr(offset); offset += sizeof(uint); for (uint i = 0; i < count; i++) { - int string_id = *(uint *)addr(offset); - offset += sizeof(int); - const char* str = (const char*)_cache->address_for_C_string(string_id); + const char* str = nullptr; + if (use_string_table) { + int string_id = *(uint *)addr(offset); + offset += sizeof(int); + str = (const char*)_cache->address_for_C_string(string_id); + } else { + str = (const char*)addr(offset); + offset += (uint)strlen(str)+1; + } dbg_strings.insert(str); } set_read_position(offset); @@ -3610,17 +3252,18 @@ void AOTCodeReader::read_dbg_strings(DbgStrings& dbg_strings) { // [_c_str_base, _c_str_base + _c_str_max -1], #define _extrs_max 140 #define _stubs_max 210 -#define _all_blobs_max 100 #define _shared_blobs_max 25 +#define _C1_blobs_max 50 #define _C2_blobs_max 25 -#define _C1_blobs_max (_all_blobs_max - _shared_blobs_max - _C2_blobs_max) -#define _all_max 450 +#define _blobs_max (_shared_blobs_max+_C1_blobs_max+_C2_blobs_max) +#define _all_max (_extrs_max+_stubs_max+_blobs_max) #define _extrs_base 0 #define _stubs_base (_extrs_base + _extrs_max) #define _shared_blobs_base (_stubs_base + _stubs_max) #define _C1_blobs_base (_shared_blobs_base + _shared_blobs_max) #define _C2_blobs_base (_C1_blobs_base + _C1_blobs_max) +#define _blobs_end (_shared_blobs_base + _blobs_max) #if (_C2_blobs_base >= _all_max) #error AOTCodeAddressTable ranges need adjusting #endif @@ -3635,11 +3278,13 @@ static bool initializing_extrs = false; void AOTCodeAddressTable::init_extrs() { if (_extrs_complete || initializing_extrs) return; // Done already + + assert(_blobs_end <= _all_max, "AOTCodeAddress table ranges need adjusting"); + initializing_extrs = true; _extrs_addr = NEW_C_HEAP_ARRAY(address, _extrs_max, mtCode); _extrs_length = 0; - _stubs_length = 0; // Record addresses of VM runtime methods SET_ADDRESS(_extrs, SharedRuntime::fixup_callers_callsite); @@ -3857,7 +3502,7 @@ void AOTCodeAddressTable::init_early_stubs() { } _early_stubs_complete = true; - log_info(aot, codecache, init)("early stubs recorded"); + log_info(aot, codecache, init)("Early stubs recorded"); } static bool initializing_shared_blobs = false; @@ -3865,19 +3510,17 @@ static bool initializing_shared_blobs = false; void AOTCodeAddressTable::init_shared_blobs() { if (_complete || initializing_shared_blobs) return; // Done already initializing_shared_blobs = true; - address* blobs_addr = NEW_C_HEAP_ARRAY(address, _all_blobs_max, mtCode); - - // Divide _shared_blobs_addr array to chunks because they could be initialized in parrallel + address* blobs_addr = NEW_C_HEAP_ARRAY(address, _blobs_max, mtCode); _shared_blobs_addr = blobs_addr; _C1_blobs_addr = _shared_blobs_addr + _shared_blobs_max;// C1 blobs addresses stored after shared blobs _C2_blobs_addr = _C1_blobs_addr + _C1_blobs_max; // C2 blobs addresses stored after C1 blobs - _shared_blobs_length = 0; // for shared blobs + _shared_blobs_length = 0; _C1_blobs_length = 0; _C2_blobs_length = 0; // clear the address table - memset(blobs_addr, 0, sizeof(address)* _all_blobs_max); + memset(blobs_addr, 0, sizeof(address)* _blobs_max); // Record addresses of generated code blobs SET_ADDRESS(_shared_blobs, SharedRuntime::get_handle_wrong_method_stub()); @@ -3901,9 +3544,15 @@ void AOTCodeAddressTable::init_shared_blobs() { SET_ADDRESS(_shared_blobs, SharedRuntime::deopt_blob()->implicit_exception_uncommon_trap()); } #endif + SET_ADDRESS(_shared_blobs, SharedRuntime::throw_AbstractMethodError_entry()); + SET_ADDRESS(_shared_blobs, SharedRuntime::throw_IncompatibleClassChangeError_entry()); + SET_ADDRESS(_shared_blobs, SharedRuntime::throw_NullPointerException_at_call_entry()); + SET_ADDRESS(_shared_blobs, SharedRuntime::throw_StackOverflowError_entry()); + SET_ADDRESS(_shared_blobs, SharedRuntime::throw_delayed_StackOverflowError_entry()); assert(_shared_blobs_length <= _shared_blobs_max, "increase _shared_blobs_max to %d", _shared_blobs_length); - log_info(aot, codecache,init)("Early shared blobs recorded"); + _shared_blobs_complete = true; + log_info(aot, codecache,init)("All shared blobs recorded"); } static bool initializing_stubs = false; @@ -3911,17 +3560,6 @@ void AOTCodeAddressTable::init_stubs() { if (_complete || initializing_stubs) return; // Done already assert(_early_stubs_complete, "early stubs whould be initialized"); initializing_stubs = true; - // final blobs - SET_ADDRESS(_shared_blobs, SharedRuntime::throw_AbstractMethodError_entry()); - SET_ADDRESS(_shared_blobs, SharedRuntime::throw_IncompatibleClassChangeError_entry()); - SET_ADDRESS(_shared_blobs, SharedRuntime::throw_NullPointerException_at_call_entry()); - SET_ADDRESS(_shared_blobs, SharedRuntime::throw_StackOverflowError_entry()); - SET_ADDRESS(_shared_blobs, SharedRuntime::throw_delayed_StackOverflowError_entry()); - - assert(_shared_blobs_length <= _all_blobs_max, "increase _all_blobs_max to %d", _shared_blobs_length); - - _shared_blobs_complete = true; - log_info(aot, codecache,init)("All shared blobs recorded"); // Stubs SET_ADDRESS(_stubs, StubRoutines::method_entry_barrier()); @@ -4395,7 +4033,7 @@ address AOTCodeAddressTable::address_for_id(int idx) { return nullptr; } -int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeBuffer* buffer, CodeBlob* blob) { +int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeBlob* blob) { if (!_extrs_complete) { fatal("AOT Code Cache VM runtime addresses table is not complete"); } @@ -4483,10 +4121,6 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB } else { reloc.print_current_on(tty); #ifndef PRODUCT - if (buffer != nullptr) { - buffer->print_on(tty); - buffer->decode(); - } if (blob != nullptr) { blob->print_on(tty); blob->print_code_on(tty); @@ -4505,16 +4139,16 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB #undef _extrs_max #undef _stubs_max -#undef _all_blobs_max -#undef _blobs_max +#undef _shared_blobs_max #undef _C1_blobs_max #undef _C2_blobs_max +#undef _blobs_max #undef _extrs_base #undef _stubs_base -#undef _blobs_base +#undef _shared_blobs_base #undef _C1_blobs_base #undef _C2_blobs_base -#undef _c_str_base +#undef _blobs_end void AOTRuntimeConstants::initialize_from_runtime() { BarrierSet* bs = BarrierSet::barrier_set(); @@ -4612,7 +4246,7 @@ AOTCodeStats AOTCodeStats::add_aot_code_stats(AOTCodeStats stats1, AOTCodeStats } void AOTCodeCache::log_stats_on_exit() { - LogStreamHandle(Info, aot, codecache, exit) log; + LogStreamHandle(Debug, aot, codecache, exit) log; if (log.is_enabled()) { AOTCodeStats prev_stats; AOTCodeStats current_stats; diff --git a/src/hotspot/share/code/aotCodeCache.hpp b/src/hotspot/share/code/aotCodeCache.hpp index 7f4035d4a14..09498587a7f 100644 --- a/src/hotspot/share/code/aotCodeCache.hpp +++ b/src/hotspot/share/code/aotCodeCache.hpp @@ -46,7 +46,6 @@ class AsmRemarks; class ciConstant; class ciEnv; class ciMethod; -class CodeBuffer; class CodeBlob; class CodeOffsets; class CompileTask; @@ -102,11 +101,10 @@ class AOTCodeEntry { uint _size; // Entry size uint _name_offset; // Method's or intrinsic name uint _name_size; + uint _num_inlined_bytecodes; + uint _code_offset; // Start of code in cache uint _code_size; // Total size of all code sections - uint _reloc_offset;// Relocations - uint _reloc_size; // Max size of relocations per code section - uint _num_inlined_bytecodes; uint _comp_level; // compilation level uint _comp_id; // compilation id @@ -120,51 +118,48 @@ class AOTCodeEntry { bool _ignore_decompile; // ignore decompile counter if compilation is done // during "assembly" phase without running application address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations + public: + // this constructor is used only by AOTCodeEntry::Stub AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size, - uint code_offset, uint code_size, - uint reloc_offset, uint reloc_size, - Kind kind, uint id, - address dumptime_content_start_addr = nullptr, - uint comp_level = 0, - uint comp_id = 0, uint decomp = 0, - bool has_clinit_barriers = false, - bool for_preload = false, - bool ignore_decompile = false) { + uint code_offset, uint code_size, + Kind kind, uint id) { + assert(kind == AOTCodeEntry::Stub, "sanity check"); _next = nullptr; _method = nullptr; _kind = kind; _id = id; - _offset = offset; _size = size; _name_offset = name_offset; _name_size = name_size; _code_offset = code_offset; _code_size = code_size; - _reloc_offset = reloc_offset; - _reloc_size = reloc_size; - _dumptime_content_start_addr = dumptime_content_start_addr; + _dumptime_content_start_addr = nullptr; _num_inlined_bytecodes = 0; - - _comp_level = comp_level; - _comp_id = comp_id; - _decompile = decomp; + _comp_level = 0; + _comp_id = 0; + _decompile = 0; _has_oop_maps = false; // unused here - _has_clinit_barriers = has_clinit_barriers; - _for_preload = for_preload; + _has_clinit_barriers = false; + _for_preload = false; _loaded = false; _not_entrant = false; _load_fail = false; - _ignore_decompile = ignore_decompile; + _ignore_decompile = true; } AOTCodeEntry(Kind kind, uint id, uint offset, uint size, uint name_offset, uint name_size, uint blob_offset, bool has_oop_maps, - address dumptime_content_start_addr) { + address dumptime_content_start_addr, + uint comp_level = 0, + uint comp_id = 0, uint decomp = 0, + bool has_clinit_barriers = false, + bool for_preload = false, + bool ignore_decompile = false) { _next = nullptr; _method = nullptr; _kind = kind; @@ -174,19 +169,21 @@ class AOTCodeEntry { _name_offset = name_offset; _name_size = name_size; _code_offset = blob_offset; - _code_size = 0; - _reloc_offset = 0; - _reloc_size = 0; + _code_size = 0; // unused _dumptime_content_start_addr = dumptime_content_start_addr; _num_inlined_bytecodes = 0; - _comp_level = 0; - _comp_id = 0; - _decompile = 0; + _comp_level = comp_level; + _comp_id = comp_id; + _decompile = decomp; _has_oop_maps = has_oop_maps; - _has_clinit_barriers = false; - _for_preload = false; + _has_clinit_barriers = has_clinit_barriers; + _for_preload = for_preload; + _loaded = false; + _not_entrant = false; + _load_fail = false; + _loaded = false; _not_entrant = false; _load_fail = false; @@ -216,18 +213,9 @@ class AOTCodeEntry { uint name_size() const { return _name_size; } uint code_offset() const { return _code_offset; } uint code_size() const { return _code_size; } - uint reloc_offset() const { return _reloc_offset; } - uint reloc_size() const { return _reloc_size; } - uint blob_offset() const { return _code_offset; } bool has_oop_maps() const { return _has_oop_maps; } address dumptime_content_start_addr() const { return _dumptime_content_start_addr; } - - static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; } - static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; } - static bool is_adapter(Kind kind) { return kind == Adapter; } - bool is_code() { return _kind == Code; } - uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; } void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; } @@ -249,6 +237,11 @@ class AOTCodeEntry { void set_load_fail() { _load_fail = true; } void print(outputStream* st) const; + + static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; } + static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; } + static bool is_adapter(Kind kind) { return kind == Adapter; } + bool is_code() { return _kind == Code; } }; // Addresses of stubs, blobs and runtime finctions called from compiled code. @@ -303,7 +296,7 @@ class AOTCodeAddressTable : public CHeapObj { const char* add_C_string(const char* str); int id_for_C_string(address str); address address_for_C_string(int idx); - int id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer, CodeBlob* blob = nullptr); + int id_for_address(address addr, RelocIterator iter, CodeBlob* blob); address address_for_id(int id); bool c2_complete() const { return _c2_complete; } bool c1_complete() const { return _c1_complete; } @@ -564,29 +557,23 @@ class AOTCodeCache : public CHeapObj { bool write_klass(Klass* klass); bool write_method(Method* method); - bool write_relocations(CodeBlob& code_blob); - bool write_debug_info(DebugInformationRecorder* recorder); + bool write_relocations(CodeBlob& code_blob, GrowableArray* oop_list = nullptr, GrowableArray* metadata_list = nullptr); bool write_oop_map_set(CodeBlob& cb); bool write_nmethod_reloc_immediates(GrowableArray& oop_list, GrowableArray& metadata_list); - bool write_nmethod_loadtime_relocations(JavaThread* thread, nmethod* nm, GrowableArray& oop_list, GrowableArray& metadata_list); jobject read_oop(JavaThread* thread, const methodHandle& comp_method); Metadata* read_metadata(const methodHandle& comp_method); - bool read_oops(OopRecorder* oop_recorder, ciMethod* target); - bool read_metadata(OopRecorder* oop_recorder, ciMethod* target); bool write_oop(jobject& jo); bool write_oop(oop obj); - bool write_oops(OopRecorder* oop_recorder); bool write_metadata(Metadata* m); - bool write_metadata(OopRecorder* oop_recorder); bool write_oops(nmethod* nm); bool write_metadata(nmethod* nm); #ifndef PRODUCT - bool write_asm_remarks(CodeBlob& cb); - bool write_dbg_strings(CodeBlob& cb); + bool write_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table); + bool write_dbg_strings(DbgStrings& dbg_strings, bool use_string_table); #endif // PRODUCT static bool store_code_blob(CodeBlob& blob, @@ -708,15 +695,12 @@ class AOTCodeReader { // convenience method to convert offset in AOTCodeEntry data to its address bool compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompiler* compiler); - bool compile_blob(CodeBuffer* buffer, int* pc_offset); CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets); Klass* read_klass(const methodHandle& comp_method, bool shared); Method* read_method(const methodHandle& comp_method, bool shared); - DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder); - oop read_oop(JavaThread* thread, const methodHandle& comp_method); Metadata* read_metadata(const methodHandle& comp_method); bool read_oops(OopRecorder* oop_recorder, ciMethod* target); @@ -727,10 +711,10 @@ class AOTCodeReader { ImmutableOopMapSet* read_oop_map_set(); - void fix_relocations(CodeBlob* code_blob); + void fix_relocations(CodeBlob* code_blob, GrowableArray* oop_list = nullptr, GrowableArray* metadata_list = nullptr) NOT_CDS_RETURN; #ifndef PRODUCT - void read_asm_remarks(AsmRemarks& asm_remarks); - void read_dbg_strings(DbgStrings& dbg_strings); + void read_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table); + void read_dbg_strings(DbgStrings& dbg_strings, bool use_string_table); #endif // PRODUCT void print_on(outputStream* st); diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 00c4abdedbe..cf9fdc5a1bc 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -281,10 +281,6 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, const char* name, address archived_reloc_data, ImmutableOopMapSet* archived_oop_maps -#ifndef PRODUCT - , AsmRemarks& archived_asm_remarks - , DbgStrings& archived_dbg_strings -#endif // PRODUCT ) { ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock @@ -301,12 +297,6 @@ CodeBlob* CodeBlob::create(CodeBlob* archived_blob, name, archived_reloc_data, archived_oop_maps); -#ifndef PRODUCT - blob->use_remarks(archived_asm_remarks); - archived_asm_remarks.clear(); - blob->use_strings(archived_dbg_strings); - archived_dbg_strings.clear(); -#endif // PRODUCT assert(blob != nullptr, "sanity check"); // Flush the code block diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 2d5a919dfa9..b7c7c2933f8 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -319,12 +319,7 @@ class CodeBlob { static CodeBlob* create(CodeBlob* archived_blob, const char* name, address archived_reloc_data, - ImmutableOopMapSet* archived_oop_maps -#ifndef PRODUCT - , AsmRemarks& archived_asm_remarks - , DbgStrings& archived_dbg_strings -#endif // PRODUCT - ); + ImmutableOopMapSet* archived_oop_maps); }; //---------------------------------------------------------------------------------------------------- diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index d352a751084..d069de20817 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1251,60 +1251,45 @@ nmethod* nmethod::new_nmethod(const methodHandle& method, return nm; } -void nmethod::restore_from_archive(nmethod* archived_nm, - const methodHandle& method, - int compile_id, - address reloc_data, - GrowableArray& oop_list, - GrowableArray& metadata_list, - ImmutableOopMapSet* oop_maps, - address immutable_data, - GrowableArray& reloc_imm_oop_list, - GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& archived_asm_remarks, - DbgStrings& archived_dbg_strings, -#endif /* PRODUCT */ - AOTCodeReader* aot_code_reader) +nmethod* nmethod::restore(address code_cache_buffer, + const methodHandle& method, + int compile_id, + address reloc_data, + GrowableArray& oop_list, + GrowableArray& metadata_list, + ImmutableOopMapSet* oop_maps, + address immutable_data, + GrowableArray& reloc_imm_oop_list, + GrowableArray& reloc_imm_metadata_list, + AOTCodeReader* aot_code_reader) { - archived_nm->copy_to((address)this); - set_name("nmethod"); - set_method(method()); - - _compile_id = compile_id; - // allocate _mutable_data before copying relocation data because relocation data is now stored as part of mutable data area - if (archived_nm->mutable_data_size() > 0) { - _mutable_data = (address)os::malloc(archived_nm->mutable_data_size(), mtCode); - if (_mutable_data == nullptr) { - vm_exit_out_of_memory(archived_nm->mutable_data_size(), OOM_MALLOC_ERROR, "codebuffer: no space for mutable data"); - } - } - memcpy((address)relocation_begin(), reloc_data, archived_nm->relocation_size()); - set_oop_maps(oop_maps); - set_immutable_data(immutable_data); - copy_values(&oop_list); - copy_values(&metadata_list); + CodeBlob::restore(code_cache_buffer, "nmethod", reloc_data, oop_maps); + nmethod* nm = (nmethod*)code_cache_buffer; + nm->set_method(method()); + nm->_compile_id = compile_id; + nm->set_immutable_data(immutable_data); + nm->copy_values(&oop_list); + nm->copy_values(&metadata_list); - aot_code_reader->apply_relocations(this, reloc_imm_oop_list, reloc_imm_metadata_list); + aot_code_reader->fix_relocations(nm, &reloc_imm_oop_list, &reloc_imm_metadata_list); #ifndef PRODUCT - AsmRemarks::init(asm_remarks()); - use_remarks(archived_asm_remarks); - archived_asm_remarks.clear(); - DbgStrings::init(dbg_strings()); - use_strings(archived_dbg_strings); - archived_dbg_strings.clear(); -#endif /* PRODUCT */ + nm->asm_remarks().init(); + aot_code_reader->read_asm_remarks(nm->asm_remarks(), /* use_string_table */ false); + nm->dbg_strings().init(); + aot_code_reader->read_dbg_strings(nm->dbg_strings(), /* use_string_table */ false); +#endif // Flush the code block - ICache::invalidate_range(code_begin(), code_size()); + ICache::invalidate_range(nm->code_begin(), nm->code_size()); // Create cache after PcDesc data is copied - it will be used to initialize cache - _pc_desc_container = new PcDescContainer(scopes_pcs_begin()); + nm->_pc_desc_container = new PcDescContainer(nm->scopes_pcs_begin()); - set_aot_code_entry(aot_code_reader->aot_code_entry()); + nm->set_aot_code_entry(aot_code_reader->aot_code_entry()); - post_init(); + nm->post_init(); + return nm; } nmethod* nmethod::new_nmethod(nmethod* archived_nm, @@ -1318,10 +1303,6 @@ nmethod* nmethod::new_nmethod(nmethod* archived_nm, address immutable_data, GrowableArray& reloc_imm_oop_list, GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& asm_remarks, - DbgStrings& dbg_strings, -#endif /* PRODUCT */ AOTCodeReader* aot_code_reader) { nmethod* nm = nullptr; @@ -1329,21 +1310,19 @@ nmethod* nmethod::new_nmethod(nmethod* archived_nm, // create nmethod { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - nm = (nmethod *)CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(archived_nm->comp_level())); - if (nm != nullptr) { - nm->restore_from_archive(archived_nm, - method, - compile_id, - reloc_data, - oop_list, - metadata_list, - oop_maps, - immutable_data, - reloc_imm_oop_list, - reloc_imm_metadata_list, - NOT_PRODUCT_ARG(asm_remarks) - NOT_PRODUCT_ARG(dbg_strings) - aot_code_reader); + address code_cache_buffer = (address)CodeCache::allocate(nmethod_size, CodeCache::get_code_blob_type(archived_nm->comp_level())); + if (code_cache_buffer != nullptr) { + nm = archived_nm->restore(code_cache_buffer, + method, + compile_id, + reloc_data, + oop_list, + metadata_list, + oop_maps, + immutable_data, + reloc_imm_oop_list, + reloc_imm_metadata_list, + aot_code_reader); nm->record_nmethod_dependency(); NOT_PRODUCT(note_java_nmethod(nm)); } @@ -4275,8 +4254,8 @@ const char* nmethod::jvmci_name() { } #endif -void nmethod::prepare_for_archiving() { - CodeBlob::prepare_for_archiving(); +void nmethod::prepare_for_archiving_impl() { + CodeBlob::prepare_for_archiving_impl(); _deoptimization_generation = 0; _gc_epoch = 0; _method_profiling_count = 0; diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 2a269fbe4e9..ac0d5b208d5 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -484,21 +484,17 @@ class nmethod : public CodeBlob { void record_nmethod_dependency(); - void restore_from_archive(nmethod* archived_nm, - const methodHandle& method, - int compile_id, - address reloc_data, - GrowableArray& oop_list, - GrowableArray& metadata_list, - ImmutableOopMapSet* oop_maps, - address immutable_data, - GrowableArray& reloc_imm_oop_list, - GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& asm_remarks, - DbgStrings& dbg_strings, -#endif /* PRODUCT */ - AOTCodeReader* aot_code_reader); + nmethod* restore(address code_cache_buffer, + const methodHandle& method, + int compile_id, + address reloc_data, + GrowableArray& oop_list, + GrowableArray& metadata_list, + ImmutableOopMapSet* oop_maps, + address immutable_data, + GrowableArray& reloc_imm_oop_list, + GrowableArray& reloc_imm_metadata_list, + AOTCodeReader* aot_code_reader); public: // create nmethod using archived nmethod from AOT code cache @@ -513,10 +509,6 @@ class nmethod : public CodeBlob { address immutable_data, GrowableArray& reloc_imm_oop_list, GrowableArray& reloc_imm_metadata_list, -#ifndef PRODUCT - AsmRemarks& asm_remarks, - DbgStrings& dbg_strings, -#endif /* PRODUCT */ AOTCodeReader* aot_code_reader); // create nmethod with entry_bci @@ -1058,7 +1050,7 @@ class nmethod : public CodeBlob { void make_deoptimized(); void finalize_relocations(); - void prepare_for_archiving(); + void prepare_for_archiving_impl(); class Vptr : public CodeBlob::Vptr { void print_on(const CodeBlob* instance, outputStream* st) const override { @@ -1068,6 +1060,9 @@ class nmethod : public CodeBlob { void print_value_on(const CodeBlob* instance, outputStream* st) const override { instance->as_nmethod()->print_value_on_impl(st); } + void prepare_for_archiving(CodeBlob* instance) const override { + ((nmethod*)instance)->prepare_for_archiving_impl(); + }; }; static const Vptr _vpntr; diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp index c3628283c42..efa37738c35 100644 --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -182,12 +182,12 @@ RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) { } RelocIterator::RelocIterator(CodeBlob* cb) { - initialize_misc(); if (cb->is_nmethod()) { - _code = cb->as_nmethod(); - } else { - _code = nullptr; + initialize(cb->as_nmethod(), nullptr, nullptr); + return; } + initialize_misc(); + _code = nullptr; _current = cb->relocation_begin() - 1; _end = cb->relocation_end(); _addr = cb->content_begin(); diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 296cb8d29be..18ed554d3d4 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -393,6 +393,9 @@ class Method : public Metadata { void set_preload_code(nmethod* code) { _preload_code = code; } + nmethod* preload_code() const { + return _preload_code; + } void set_aot_code_entry(AOTCodeEntry* entry) { _aot_code_entry = entry; }