From d72804e6433112d02be33b02a529eec61530cf7c Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Tue, 1 Oct 2024 05:00:31 +0300 Subject: [PATCH 1/5] 8343789: Move mutable nmethod data out of CodeCache --- .../cpu/aarch64/macroAssembler_aarch64.cpp | 3 +- src/hotspot/share/code/codeBlob.cpp | 24 ++-- src/hotspot/share/code/codeBlob.hpp | 31 ++++-- src/hotspot/share/code/nmethod.cpp | 105 ++++++++++++------ src/hotspot/share/code/nmethod.hpp | 20 ++-- src/hotspot/share/runtime/vmStructs.cpp | 2 + .../classes/sun/jvm/hotspot/code/NMethod.java | 20 +++- 7 files changed, 143 insertions(+), 62 deletions(-) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 252f423211580..6707a3209cc05 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -5270,9 +5270,8 @@ void MacroAssembler::movoop(Register dst, jobject obj) { mov(dst, Address((address)obj, rspec)); } else { address dummy = address(uintptr_t(pc()) & -wordSize); // A nearby aligned address - ldr_constant(dst, Address(dummy, rspec)); + mov(dst, Address(dummy, rspec)); } - } // Move a metadata address into a register. diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 23f621ffec832..b1e77531e1609 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -62,24 +62,32 @@ unsigned int CodeBlob::align_code_offset(int offset) { } // This must be consistent with the CodeBlob constructor's layout actions. -unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) { +unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data) { unsigned int size = header_size; - size += align_up(cb->total_relocation_size(), oopSize); + if (!external_mutable_data) { + // In a standard CodeBlob, the relocation_info is located before the code section. + // However, in an nmethod, the relocation_info is stored in the mutable data, so + // it does not contribute to the nmethod's total size, as it is moved to the C heap. + size += align_up(cb->total_relocation_size(), oopSize); + } // align the size to CodeEntryAlignment size = align_code_offset(size); size += align_up(cb->total_content_size(), oopSize); - size += align_up(cb->total_oop_size(), oopSize); - size += align_up(cb->total_metadata_size(), oopSize); + if (!external_mutable_data) { + size += align_up(cb->total_oop_size(), oopSize); + size += align_up(cb->total_metadata_size(), oopSize); + } return size; } CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, - int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) : + int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments, + bool external_mutable_data) : _oop_maps(nullptr), // will be set by set_oop_maps() call _name(name), _size(size), _relocation_size(align_up(cb->total_relocation_size(), oopSize)), - _content_offset(CodeBlob::align_code_offset(header_size + _relocation_size)), + _content_offset(CodeBlob::align_code_offset(header_size + (external_mutable_data ? 0 : _relocation_size))), _code_offset(_content_offset + cb->total_offset_of(cb->insts())), _data_offset(_content_offset + align_up(cb->total_content_size(), oopSize)), _frame_size(frame_size), @@ -87,7 +95,9 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size _header_size(header_size), _frame_complete_offset(frame_complete_offset), _kind(kind), - _caller_must_gc_arguments(caller_must_gc_arguments) + _caller_must_gc_arguments(caller_must_gc_arguments), + _mutable_data(nullptr), + _mutable_data_size(0) { assert(is_aligned(_size, oopSize), "unaligned size"); assert(is_aligned(header_size, oopSize), "unaligned size"); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 8ecd9e21537df..d13f24d1c7483 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -124,13 +124,17 @@ class CodeBlob { bool _caller_must_gc_arguments; + address _mutable_data; + int _mutable_data_size; + #ifndef PRODUCT AsmRemarks _asm_remarks; DbgStrings _dbg_strings; #endif CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, - int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments); + int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments, + bool external_mutable_data = false); // Simple CodeBlob used for simple BufferBlob. CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size); @@ -144,7 +148,7 @@ class CodeBlob { } // Returns the space needed for CodeBlob - static unsigned int allocation_size(CodeBuffer* cb, int header_size); + static unsigned int allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data = false); static unsigned int align_code_offset(int offset); // Deletion @@ -170,18 +174,31 @@ class CodeBlob { UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; } RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; } + address mutable_data_begin() const { return _mutable_data; } + address mutable_data_end() const { return _mutable_data + _mutable_data_size; } + int mutable_data_size() const { return _mutable_data_size; } + bool relocInfo_in_mutable_data() const { return _mutable_data != nullptr; } + // Boundaries address header_begin() const { return (address) this; } address header_end() const { return ((address) this) + _header_size; } - relocInfo* relocation_begin() const { return (relocInfo*) header_end(); } - relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); } + relocInfo* relocation_begin() const { return relocInfo_in_mutable_data() ? + (relocInfo*)_mutable_data : (relocInfo*) header_end(); } + relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); } address content_begin() const { return (address) header_begin() + _content_offset; } address content_end() const { return (address) header_begin() + _data_offset; } address code_begin() const { return (address) header_begin() + _code_offset; } // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor address code_end() const { return (address) header_begin() + _data_offset; } - address data_begin() const { return (address) header_begin() + _data_offset; } - address data_end() const { return (address) header_begin() + _size; } + address data_begin() const { return (address) header_begin() + _data_offset; } + address data_end() const { return (address) header_begin() + _size; } + address blob_end() const { return data_end(); } + + // [relocations, oops, metatada, jvmci_data] stays in _mutable_data or in nmethod with _data_offset + address mdata_begin() const { return (_mutable_data != nullptr) ? _mutable_data : + (address) header_begin() + _data_offset; } + address mdata_end() const { return (_mutable_data != nullptr) ? _mutable_data + _mutable_data_size: + (address) header_begin() + _size; } // Offsets int content_offset() const { return _content_offset; } @@ -208,7 +225,7 @@ class CodeBlob { } // Containment - bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); } + bool blob_contains(address addr) const { return header_begin() <= addr && addr < blob_end(); } bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); } bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); } bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe && diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 7fb72997749dc..3e5e74ae0e92d 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -128,6 +128,7 @@ struct java_nmethod_stats_struct { uint nmethod_count; uint total_nm_size; uint total_immut_size; + uint total_mut_size; uint relocation_size; uint consts_size; uint insts_size; @@ -148,6 +149,7 @@ struct java_nmethod_stats_struct { nmethod_count += 1; total_nm_size += nm->size(); total_immut_size += nm->immutable_data_size(); + total_mut_size += nm->mutable_data_size(); relocation_size += nm->relocation_size(); consts_size += nm->consts_size(); insts_size += nm->insts_size(); @@ -167,7 +169,7 @@ struct java_nmethod_stats_struct { void print_nmethod_stats(const char* name) { if (nmethod_count == 0) return; tty->print_cr("Statistics for %u bytecoded nmethods for %s:", nmethod_count, name); - uint total_size = total_nm_size + total_immut_size; + uint total_size = total_nm_size + total_immut_size + total_mut_size; if (total_nm_size != 0) { tty->print_cr(" total size = %u (100%%)", total_size); tty->print_cr(" in CodeCache = %u (%f%%)", total_nm_size, (total_nm_size * 100.0f)/total_size); @@ -176,9 +178,6 @@ struct java_nmethod_stats_struct { if (nmethod_count != 0) { tty->print_cr(" header = %u (%f%%)", header_size, (header_size * 100.0f)/total_nm_size); } - if (relocation_size != 0) { - tty->print_cr(" relocation = %u (%f%%)", relocation_size, (relocation_size * 100.0f)/total_nm_size); - } if (consts_size != 0) { tty->print_cr(" constants = %u (%f%%)", consts_size, (consts_size * 100.0f)/total_nm_size); } @@ -188,6 +187,12 @@ struct java_nmethod_stats_struct { if (stub_size != 0) { tty->print_cr(" stub code = %u (%f%%)", stub_size, (stub_size * 100.0f)/total_nm_size); } + if (total_mut_size != 0) { + tty->print_cr(" mutable data = %u (%f%%)", total_mut_size, (total_mut_size * 100.0f)/total_size); + } + if (relocation_size != 0) { + tty->print_cr(" relocation = %u (%f%%)", relocation_size, (relocation_size * 100.0f)/total_nm_size); + } if (oops_size != 0) { tty->print_cr(" oops = %u (%f%%)", oops_size, (oops_size * 100.0f)/total_nm_size); } @@ -1143,12 +1148,7 @@ nmethod* nmethod::new_nmethod(const methodHandle& method, code_buffer->finalize_oop_references(method); // create nmethod nmethod* nm = nullptr; - int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod)); -#if INCLUDE_JVMCI - if (compiler->is_jvmci()) { - nmethod_size += align_up(jvmci_data->size(), oopSize); - } -#endif + int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod), true); int immutable_data_size = adjust_pcs_size(debug_info->pcs_size()) @@ -1169,12 +1169,28 @@ nmethod* nmethod::new_nmethod(const methodHandle& method, return nullptr; } } + + int mutable_data_size = align_up(code_buffer->total_relocation_size(), oopSize) + + + align_up(code_buffer->total_oop_size(), oopSize) + + + align_up(code_buffer->total_metadata_size(), oopSize); +#if INCLUDE_JVMCI + mutable_data_size += align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize); +#endif + address mutable_data = nullptr; + if (mutable_data_size > 0) { + mutable_data = (address)os::malloc(mutable_data_size, mtCode); + if (mutable_data == nullptr) { + vm_exit_out_of_memory(mutable_data_size, OOM_MALLOC_ERROR, "nmethod: no space for mutable data"); + return nullptr; + } + } + { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); nm = new (nmethod_size, comp_level) - nmethod(method(), compiler->type(), nmethod_size, immutable_data_size, - compile_id, entry_bci, immutable_data, offsets, orig_pc_offset, + nmethod(method(), compiler->type(), nmethod_size, immutable_data_size, mutable_data_size, + compile_id, entry_bci, immutable_data, mutable_data, offsets, orig_pc_offset, debug_info, dependencies, code_buffer, frame_size, oop_maps, handler_table, nul_chk_table, compiler, comp_level #if INCLUDE_JVMCI @@ -1322,7 +1338,7 @@ nmethod::nmethod( assert((data_offset() + data_end_offset) <= nmethod_size, "wrong nmethod's size: %d < %d", nmethod_size, (data_offset() + data_end_offset)); // native wrapper does not have read-only data but we need unique not null address - _immutable_data = data_end(); + _immutable_data = blob_end(); _immutable_data_size = 0; _nul_chk_table_offset = 0; _handler_table_offset = 0; @@ -1399,9 +1415,11 @@ nmethod::nmethod( CompilerType type, int nmethod_size, int immutable_data_size, + int mutable_data_size, int compile_id, int entry_bci, address immutable_data, + address mutable_data, CodeOffsets* offsets, int orig_pc_offset, DebugInformationRecorder* debug_info, @@ -1420,7 +1438,7 @@ nmethod::nmethod( #endif ) : CodeBlob("nmethod", CodeBlobKind::Nmethod, code_buffer, nmethod_size, sizeof(nmethod), - offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false), + offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), _deoptimization_generation(0), _gc_epoch(CodeCache::gc_epoch()), _method(method), @@ -1486,18 +1504,21 @@ nmethod::nmethod( } else { _unwind_handler_offset = -1; } - CHECKED_CAST(_metadata_offset, uint16_t, (align_up(code_buffer->total_oop_size(), oopSize))); - int metadata_end_offset = _metadata_offset + align_up(code_buffer->total_metadata_size(), wordSize); + int reloc_size = align_up(code_buffer->total_relocation_size(), oopSize); + int oop_size = align_up(code_buffer->total_oop_size(), oopSize); + int metadata_size = align_up(code_buffer->total_metadata_size(), wordSize); + CHECKED_CAST(_metadata_offset, uint16_t, reloc_size + oop_size); + int jvmci_data_size = 0; #if INCLUDE_JVMCI - CHECKED_CAST(_jvmci_data_offset, uint16_t, metadata_end_offset); - int jvmci_data_size = compiler->is_jvmci() ? jvmci_data->size() : 0; - DEBUG_ONLY( int data_end_offset = _jvmci_data_offset + align_up(jvmci_data_size, oopSize); ) -#else - DEBUG_ONLY( int data_end_offset = metadata_end_offset; ) + CHECKED_CAST(_jvmci_data_offset, uint16_t, _metadata_offset + metadata_size); + jvmci_data_size = align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize); #endif - assert((data_offset() + data_end_offset) <= nmethod_size, "wrong nmethod's size: %d > %d", - (data_offset() + data_end_offset), nmethod_size); + assert(mutable_data_size == reloc_size + oop_size + metadata_size + jvmci_data_size, + "wrong mutable data size: %d != %d + %d + %d + %d", + mutable_data_size, reloc_size, oop_size, metadata_size, jvmci_data_size); + assert(nmethod_size == code_end() - header_begin(), "wrong nmethod size: %d != %d", + nmethod_size, (int)(code_end() - header_begin())); _immutable_data_size = immutable_data_size; if (immutable_data_size > 0) { @@ -1505,7 +1526,15 @@ nmethod::nmethod( _immutable_data = immutable_data; } else { // We need unique not null address - _immutable_data = data_end(); + _immutable_data = blob_end(); + } + _mutable_data_size = mutable_data_size; + if (mutable_data_size > 0) { + assert(mutable_data != nullptr, "required"); + _mutable_data = mutable_data; + } else { + // We need unique not null address + _mutable_data = blob_end(); } CHECKED_CAST(_nul_chk_table_offset, uint16_t, (align_up((int)dependencies->size_in_bytes(), oopSize))); CHECKED_CAST(_handler_table_offset, uint16_t, (_nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize))); @@ -2127,9 +2156,13 @@ void nmethod::purge(bool unregister_nmethod) { } delete[] _compiled_ic_data; - if (_immutable_data != data_end()) { + if (_immutable_data != blob_end()) { os::free(_immutable_data); - _immutable_data = data_end(); // Valid not null address + _immutable_data = blob_end(); // Valid not null address + } + if (_mutable_data != blob_end()) { + os::free(_mutable_data); + _mutable_data = blob_end(); // Valid not null address } if (unregister_nmethod) { Universe::heap()->unregister_nmethod(this); @@ -2143,14 +2176,14 @@ oop nmethod::oop_at(int index) const { if (index == 0) { return nullptr; } - return NMethodAccess::oop_load(oop_addr_at(index)); + return RawAccess<>::oop_load(oop_addr_at(index)); } oop nmethod::oop_at_phantom(int index) const { if (index == 0) { return nullptr; } - return NMethodAccess::oop_load(oop_addr_at(index)); + return RawAccess::oop_load(oop_addr_at(index)); } // @@ -3062,10 +3095,6 @@ void nmethod::print(outputStream* st) const { p2i(this), p2i(this) + size(), size()); - if (relocation_size () > 0) st->print_cr(" relocation [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", - p2i(relocation_begin()), - p2i(relocation_end()), - relocation_size()); if (consts_size () > 0) st->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", p2i(consts_begin()), p2i(consts_end()), @@ -3078,6 +3107,14 @@ void nmethod::print(outputStream* st) const { p2i(stub_begin()), p2i(stub_end()), stub_size()); + if (mutable_data_size() > 0) st->print_cr(" mutable data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", + p2i(mutable_data_begin()), + p2i(mutable_data_end()), + immutable_data_size()); + if (relocation_size() > 0) st->print_cr(" relocation [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", + p2i(relocation_begin()), + p2i(relocation_end()), + relocation_size()); if (oops_size () > 0) st->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", p2i(oops_begin()), p2i(oops_end()), @@ -3116,6 +3153,10 @@ void nmethod::print(outputStream* st) const { p2i(scopes_data_begin()), p2i(scopes_data_end()), scopes_data_size()); + if (mutable_data_size() > 0) st->print_cr(" mutable data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", + p2i(mutable_data_begin()), + p2i(mutable_data_end()), + mutable_data_size()); #if INCLUDE_JVMCI if (speculations_size () > 0) st->print_cr(" speculations [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", p2i(speculations_begin()), diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index 095c0ba4a26a4..bd761d61c3977 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -135,8 +135,6 @@ class PcDescContainer : public CHeapObj { // // An nmethod contains: // - header (the nmethod structure) -// [Relocation] -// - relocation information // - constant part (doubles, longs and floats used in nmethod) // - oop table // [Code] @@ -236,7 +234,7 @@ class nmethod : public CodeBlob { uint16_t _num_stack_arg_slots; // Offsets in mutable data section - // _oops_offset == _data_offset, offset where embedded oop table begins (inside data) + uint16_t oops_offset () const { return (_mutable_data != nullptr) ? _relocation_size : 0; } uint16_t _metadata_offset; // embedded meta data table #if INCLUDE_JVMCI uint16_t _jvmci_data_offset; @@ -312,9 +310,11 @@ class nmethod : public CodeBlob { CompilerType type, int nmethod_size, int immutable_data_size, + int mutable_data_size, int compile_id, int entry_bci, address immutable_data, + address mutable_data, CodeOffsets* offsets, int orig_pc_offset, DebugInformationRecorder *recorder, @@ -533,15 +533,15 @@ class nmethod : public CodeBlob { address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (insts_end() - _unwind_handler_offset) : nullptr; } // mutable data - oop* oops_begin () const { return (oop*) data_begin(); } - oop* oops_end () const { return (oop*) (data_begin() + _metadata_offset) ; } - Metadata** metadata_begin () const { return (Metadata**) (data_begin() + _metadata_offset) ; } + oop* oops_begin () const { return (oop*) (mdata_begin() + oops_offset()) ; } + oop* oops_end () const { return (oop*) (mdata_begin() + _metadata_offset) ; } + Metadata** metadata_begin () const { return (Metadata**) (mdata_begin() + _metadata_offset) ; } #if INCLUDE_JVMCI - Metadata** metadata_end () const { return (Metadata**) (data_begin() + _jvmci_data_offset) ; } - address jvmci_data_begin () const { return data_begin() + _jvmci_data_offset ; } - address jvmci_data_end () const { return data_end(); } + Metadata** metadata_end () const { return (Metadata**) (mdata_begin() + _jvmci_data_offset) ; } + address jvmci_data_begin () const { return mdata_begin() + _jvmci_data_offset ; } + address jvmci_data_end () const { return mdata_end(); } #else - Metadata** metadata_end () const { return (Metadata**) data_end(); } + Metadata** metadata_end () const { return (Metadata**) mdata_end(); } #endif // immutable data diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 3060e225427a8..45db3b6b7f3d9 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -592,6 +592,8 @@ nonstatic_field(nmethod, _osr_entry_point, address) \ nonstatic_field(nmethod, _immutable_data, address) \ nonstatic_field(nmethod, _immutable_data_size, int) \ + nonstatic_field(nmethod, _mutable_data, address) \ + nonstatic_field(nmethod, _mutable_data_size, int) \ nonstatic_field(nmethod, _compile_id, int) \ nonstatic_field(nmethod, _comp_level, CompLevel) \ volatile_nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \ diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java index 8eacd1a8a8643..e5e574dbcec19 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java @@ -44,6 +44,9 @@ public class NMethod extends CodeBlob { private static AddressField osrLinkField; private static AddressField immutableDataField; private static CIntegerField immutableDataSizeField; + private static AddressField mutableDataField; + private static CIntegerField mutableDataSizeField; + private static CIntegerField relocationSizeField; /** Offsets for different nmethod parts */ private static CIntegerField exceptionOffsetField; @@ -85,6 +88,9 @@ private static void initialize(TypeDataBase db) { osrLinkField = type.getAddressField("_osr_link"); immutableDataField = type.getAddressField("_immutable_data"); immutableDataSizeField = type.getCIntegerField("_immutable_data_size"); + mutableDataField = type.getAddressField("_mutable_data"); + mutableDataSizeField = type.getCIntegerField("_mutable_data_size"); + relocationSizeField = type.getCIntegerField("_relocation_size"); exceptionOffsetField = type.getCIntegerField("_exception_offset"); deoptHandlerOffsetField = type.getCIntegerField("_deopt_handler_offset"); @@ -132,10 +138,6 @@ public Method getMethod() { public Address deoptMhHandlerBegin() { return headerBegin().addOffsetTo(getDeoptMhHandlerOffset()); } public Address stubBegin() { return headerBegin().addOffsetTo(getStubOffset()); } public Address stubEnd() { return dataBegin(); } - public Address oopsBegin() { return dataBegin(); } - public Address oopsEnd() { return dataBegin().addOffsetTo(getMetadataOffset()); } - public Address metadataBegin() { return dataBegin().addOffsetTo(getMetadataOffset()); } - public Address metadataEnd() { return dataEnd(); } public Address immutableDataBegin() { return immutableDataField.getValue(addr); } public Address immutableDataEnd() { return immutableDataBegin().addOffsetTo(getImmutableDataSize()); } @@ -150,7 +152,17 @@ public Method getMethod() { public Address scopesPCsBegin() { return immutableDataBegin().addOffsetTo(getScopesPCsOffset()); } public Address scopesPCsEnd() { return immutableDataEnd(); } + public Address mutableDataBegin() { return mutableDataField.getValue(addr); } + public Address mutableDataEnd() { return mutableDataBegin().addOffsetTo(getMutableDataSize()); } + + public Address oopsBegin() { return mutableDataBegin().addOffsetTo(getRelocationSize()); } + public Address oopsEnd() { return mutableDataBegin().addOffsetTo(getMetadataOffset()); } + public Address metadataBegin() { return mutableDataBegin().addOffsetTo(getMetadataOffset()); } + public Address metadataEnd() { return mutableDataEnd(); } + public int getImmutableDataSize() { return (int) immutableDataSizeField.getValue(addr); } + public int getMutableDataSize() { return (int) mutableDataSizeField.getValue(addr); } + public int getRelocationSize() { return (int) relocationSizeField.getValue(addr); } public int constantsSize() { return (int) constantsEnd() .minus(constantsBegin()); } public int instsSize() { return (int) instsEnd() .minus(instsBegin()); } public int stubSize() { return (int) stubEnd() .minus(stubBegin()); } From 52dd5270a26750d17d2cae4e8d049a38d01d0934 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Sat, 9 Nov 2024 14:49:09 +0300 Subject: [PATCH 2/5] fix stat printout --- src/hotspot/share/code/nmethod.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 3e5e74ae0e92d..1dcaade7addf0 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -191,13 +191,13 @@ struct java_nmethod_stats_struct { tty->print_cr(" mutable data = %u (%f%%)", total_mut_size, (total_mut_size * 100.0f)/total_size); } if (relocation_size != 0) { - tty->print_cr(" relocation = %u (%f%%)", relocation_size, (relocation_size * 100.0f)/total_nm_size); + tty->print_cr(" relocation = %u (%f%%)", relocation_size, (relocation_size * 100.0f)/total_mut_size); } if (oops_size != 0) { - tty->print_cr(" oops = %u (%f%%)", oops_size, (oops_size * 100.0f)/total_nm_size); + tty->print_cr(" oops = %u (%f%%)", oops_size, (oops_size * 100.0f)/total_mut_size); } if (metadata_size != 0) { - tty->print_cr(" metadata = %u (%f%%)", metadata_size, (metadata_size * 100.0f)/total_nm_size); + tty->print_cr(" metadata = %u (%f%%)", metadata_size, (metadata_size * 100.0f)/total_mut_size); } #if INCLUDE_JVMCI if (jvmci_data_size != 0) { From c401e774e2ec655b6a094eb4f51262c27a81ca5e Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Fri, 15 Nov 2024 20:35:13 +0300 Subject: [PATCH 3/5] update: mutable data for all CodeBlobs with relocations --- src/hotspot/share/code/codeBlob.cpp | 35 +++++++------- src/hotspot/share/code/codeBlob.hpp | 31 +++++-------- src/hotspot/share/code/nmethod.cpp | 61 +++++++++++-------------- src/hotspot/share/code/nmethod.hpp | 6 +-- src/hotspot/share/runtime/vmStructs.cpp | 2 +- 5 files changed, 59 insertions(+), 76 deletions(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index b1e77531e1609..4c4e15b7a621d 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -62,34 +62,23 @@ unsigned int CodeBlob::align_code_offset(int offset) { } // This must be consistent with the CodeBlob constructor's layout actions. -unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data) { - unsigned int size = header_size; - if (!external_mutable_data) { - // In a standard CodeBlob, the relocation_info is located before the code section. - // However, in an nmethod, the relocation_info is stored in the mutable data, so - // it does not contribute to the nmethod's total size, as it is moved to the C heap. - size += align_up(cb->total_relocation_size(), oopSize); - } +unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) { // align the size to CodeEntryAlignment - size = align_code_offset(size); + unsigned int size = align_code_offset(header_size); size += align_up(cb->total_content_size(), oopSize); - if (!external_mutable_data) { - size += align_up(cb->total_oop_size(), oopSize); - size += align_up(cb->total_metadata_size(), oopSize); - } return size; } CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments, - bool external_mutable_data) : + int mutable_data_size) : _oop_maps(nullptr), // will be set by set_oop_maps() call _name(name), _size(size), _relocation_size(align_up(cb->total_relocation_size(), oopSize)), - _content_offset(CodeBlob::align_code_offset(header_size + (external_mutable_data ? 0 : _relocation_size))), + _content_offset(CodeBlob::align_code_offset(header_size)), _code_offset(_content_offset + cb->total_offset_of(cb->insts())), - _data_offset(_content_offset + align_up(cb->total_content_size(), oopSize)), + _code_end_offset(_content_offset + align_up(cb->total_content_size(), oopSize)), _frame_size(frame_size), S390_ONLY(_ctable_offset(0) COMMA) _header_size(header_size), @@ -102,13 +91,23 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size assert(is_aligned(_size, oopSize), "unaligned size"); assert(is_aligned(header_size, oopSize), "unaligned size"); assert(is_aligned(_relocation_size, oopSize), "unaligned size"); - assert(_data_offset <= _size, "codeBlob is too small: %d > %d", _data_offset, _size); + assert(_code_end_offset <= _size, "codeBlob is too small: %d > %d", _code_end_offset, _size); assert(code_end() == content_end(), "must be the same - see code_end()"); #ifdef COMPILER1 // probably wrong for tiered assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs"); #endif // COMPILER1 + // The mutable_data_size is either calculated by the nmethod constructor to account + // for reloc_info and additional data, or it is set here to accommodate only the relocation data. + _mutable_data_size = (mutable_data_size == 0) ? cb->total_relocation_size() : mutable_data_size; + if (_mutable_data_size > 0) { + _mutable_data = (address)os::malloc(_mutable_data_size, mtCode); + if (_mutable_data == nullptr) { + vm_exit_out_of_memory(_mutable_data_size, OOM_MALLOC_ERROR, "codebuffer: no space for mutable data"); + } + } + set_oop_maps(oop_maps); } @@ -120,7 +119,7 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t heade _relocation_size(0), _content_offset(CodeBlob::align_code_offset(header_size)), _code_offset(_content_offset), - _data_offset(size), + _code_end_offset(size), _frame_size(0), S390_ONLY(_ctable_offset(0) COMMA) _header_size(header_size), diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index d13f24d1c7483..745637c2eda0d 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -108,8 +108,7 @@ class CodeBlob { int _relocation_size; // size of relocation (could be bigger than 64Kb) int _content_offset; // offset to where content region begins (this includes consts, insts, stubs) int _code_offset; // offset to where instructions region begins (this includes insts, stubs) - - int _data_offset; // offset to where data region begins + int _code_end_offset; // offset to where code region ends int _frame_size; // size of stack frame in words (NOT slots. On x64 these are 64bit words) S390_ONLY(int _ctable_offset;) @@ -134,7 +133,7 @@ class CodeBlob { CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size, int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments, - bool external_mutable_data = false); + int mutable_data_size = 0); // Simple CodeBlob used for simple BufferBlob. CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t header_size); @@ -148,7 +147,7 @@ class CodeBlob { } // Returns the space needed for CodeBlob - static unsigned int allocation_size(CodeBuffer* cb, int header_size, bool external_mutable_data = false); + static unsigned int allocation_size(CodeBuffer* cb, int header_size); static unsigned int align_code_offset(int offset); // Deletion @@ -177,33 +176,25 @@ class CodeBlob { address mutable_data_begin() const { return _mutable_data; } address mutable_data_end() const { return _mutable_data + _mutable_data_size; } int mutable_data_size() const { return _mutable_data_size; } - bool relocInfo_in_mutable_data() const { return _mutable_data != nullptr; } // Boundaries address header_begin() const { return (address) this; } address header_end() const { return ((address) this) + _header_size; } - relocInfo* relocation_begin() const { return relocInfo_in_mutable_data() ? - (relocInfo*)_mutable_data : (relocInfo*) header_end(); } + relocInfo* relocation_begin() const { return (relocInfo*)_mutable_data; } relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); } address content_begin() const { return (address) header_begin() + _content_offset; } - address content_end() const { return (address) header_begin() + _data_offset; } + address content_end() const { return (address) header_begin() + _code_end_offset; } address code_begin() const { return (address) header_begin() + _code_offset; } // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor - address code_end() const { return (address) header_begin() + _data_offset; } - address data_begin() const { return (address) header_begin() + _data_offset; } - address data_end() const { return (address) header_begin() + _size; } - address blob_end() const { return data_end(); } - - // [relocations, oops, metatada, jvmci_data] stays in _mutable_data or in nmethod with _data_offset - address mdata_begin() const { return (_mutable_data != nullptr) ? _mutable_data : - (address) header_begin() + _data_offset; } - address mdata_end() const { return (_mutable_data != nullptr) ? _mutable_data + _mutable_data_size: - (address) header_begin() + _size; } + address code_end() const { return (address) header_begin() + _code_end_offset; } + address blob_end() const { return (address) header_begin() + _size; } + // [relocations, oops, metatada, jvmci_data] stays in _mutable_data + address mdata_begin() const { return mutable_data_begin(); } + address mdata_end() const { return mutable_data_end(); } // Offsets int content_offset() const { return _content_offset; } int code_offset() const { return _code_offset; } - int data_offset() const { return _data_offset; } // This field holds the beginning of the const section in the old code buffer. // It is needed to fix relocations of pc-relative loads when resizing the @@ -221,7 +212,7 @@ class CodeBlob { // Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed void adjust_size(size_t used) { _size = (int)used; - _data_offset = (int)used; + _code_end_offset = (int)used; } // Containment diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 1dcaade7addf0..81ba1df59af51 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -1077,6 +1077,14 @@ static void assert_no_oops_or_metadata(nmethod* nm) { } #endif +static int required_mutable_data_space(CodeBuffer* code_buffer, + int jvmci_data_size = 0) { + return align_up(code_buffer->total_relocation_size(), oopSize) + + align_up(code_buffer->total_oop_size(), oopSize) + + align_up(jvmci_data_size, oopSize) + + align_up(code_buffer->total_metadata_size(), oopSize); +} + nmethod* nmethod::new_native_nmethod(const methodHandle& method, int compile_id, CodeBuffer *code_buffer, @@ -1101,6 +1109,8 @@ nmethod* nmethod::new_native_nmethod(const methodHandle& method, offsets.set_value(CodeOffsets::Exceptions, exception_handler); } + int mutable_data_size = required_mutable_data_space(code_buffer); + // MH intrinsics are dispatch stubs which are compatible with NonNMethod space. // IsUnloadingBehaviour::is_unloading needs to handle them separately. bool allow_NonNMethod_space = method->can_be_allocated_in_NonNMethod_space(); @@ -1110,7 +1120,7 @@ nmethod* nmethod::new_native_nmethod(const methodHandle& method, code_buffer, frame_size, basic_lock_owner_sp_offset, basic_lock_sp_offset, - oop_maps); + oop_maps, mutable_data_size); DEBUG_ONLY( if (allow_NonNMethod_space) assert_no_oops_or_metadata(nm); ) NOT_PRODUCT(if (nm != nullptr) native_nmethod_stats.note_native_nmethod(nm)); } @@ -1148,7 +1158,7 @@ nmethod* nmethod::new_nmethod(const methodHandle& method, code_buffer->finalize_oop_references(method); // create nmethod nmethod* nm = nullptr; - int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod), true); + int nmethod_size = CodeBlob::allocation_size(code_buffer, sizeof(nmethod)); int immutable_data_size = adjust_pcs_size(debug_info->pcs_size()) @@ -1170,27 +1180,15 @@ nmethod* nmethod::new_nmethod(const methodHandle& method, } } - int mutable_data_size = align_up(code_buffer->total_relocation_size(), oopSize) + - + align_up(code_buffer->total_oop_size(), oopSize) + - + align_up(code_buffer->total_metadata_size(), oopSize); -#if INCLUDE_JVMCI - mutable_data_size += align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize); -#endif - address mutable_data = nullptr; - if (mutable_data_size > 0) { - mutable_data = (address)os::malloc(mutable_data_size, mtCode); - if (mutable_data == nullptr) { - vm_exit_out_of_memory(mutable_data_size, OOM_MALLOC_ERROR, "nmethod: no space for mutable data"); - return nullptr; - } - } + int mutable_data_size = required_mutable_data_space(code_buffer + JVMCI_ONLY(COMMA (compiler->is_jvmci() ? jvmci_data->size() : 0))); { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); nm = new (nmethod_size, comp_level) nmethod(method(), compiler->type(), nmethod_size, immutable_data_size, mutable_data_size, - compile_id, entry_bci, immutable_data, mutable_data, offsets, orig_pc_offset, + compile_id, entry_bci, immutable_data, offsets, orig_pc_offset, debug_info, dependencies, code_buffer, frame_size, oop_maps, handler_table, nul_chk_table, compiler, comp_level #if INCLUDE_JVMCI @@ -1292,9 +1290,10 @@ nmethod::nmethod( int frame_size, ByteSize basic_lock_owner_sp_offset, ByteSize basic_lock_sp_offset, - OopMapSet* oop_maps ) + OopMapSet* oop_maps, + int mutable_data_size) : CodeBlob("native nmethod", CodeBlobKind::Nmethod, code_buffer, nmethod_size, sizeof(nmethod), - offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false), + offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, mutable_data_size), _deoptimization_generation(0), _gc_epoch(CodeCache::gc_epoch()), _method(method), @@ -1328,14 +1327,17 @@ nmethod::nmethod( _deopt_mh_handler_offset = 0; _unwind_handler_offset = 0; - CHECKED_CAST(_metadata_offset, uint16_t, (align_up(code_buffer->total_oop_size(), oopSize))); - int data_end_offset = _metadata_offset + align_up(code_buffer->total_metadata_size(), wordSize); + int reloc_size = align_up(code_buffer->total_relocation_size(), oopSize); + int oop_size = align_up(code_buffer->total_oop_size(), oopSize); + int metadata_size = align_up(code_buffer->total_metadata_size(), wordSize); + CHECKED_CAST(_metadata_offset, uint16_t, reloc_size + oop_size); + int data_end_offset = _metadata_offset + metadata_size; #if INCLUDE_JVMCI // jvmci_data_size is 0 in native wrapper but we need to set offset // to correctly calculate metadata_end address CHECKED_CAST(_jvmci_data_offset, uint16_t, data_end_offset); #endif - assert((data_offset() + data_end_offset) <= nmethod_size, "wrong nmethod's size: %d < %d", nmethod_size, (data_offset() + data_end_offset)); + assert(data_end_offset <= mutable_data_size, "wrong nmutable_data_size: %d < %d", data_end_offset, mutable_data_size); // native wrapper does not have read-only data but we need unique not null address _immutable_data = blob_end(); @@ -1419,7 +1421,6 @@ nmethod::nmethod( int compile_id, int entry_bci, address immutable_data, - address mutable_data, CodeOffsets* offsets, int orig_pc_offset, DebugInformationRecorder* debug_info, @@ -1438,7 +1439,7 @@ nmethod::nmethod( #endif ) : CodeBlob("nmethod", CodeBlobKind::Nmethod, code_buffer, nmethod_size, sizeof(nmethod), - offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), + offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, mutable_data_size), _deoptimization_generation(0), _gc_epoch(CodeCache::gc_epoch()), _method(method), @@ -1514,9 +1515,9 @@ nmethod::nmethod( CHECKED_CAST(_jvmci_data_offset, uint16_t, _metadata_offset + metadata_size); jvmci_data_size = align_up(compiler->is_jvmci() ? jvmci_data->size() : 0, oopSize); #endif - assert(mutable_data_size == reloc_size + oop_size + metadata_size + jvmci_data_size, + assert(_mutable_data_size == reloc_size + oop_size + metadata_size + jvmci_data_size, "wrong mutable data size: %d != %d + %d + %d + %d", - mutable_data_size, reloc_size, oop_size, metadata_size, jvmci_data_size); + _mutable_data_size, reloc_size, oop_size, metadata_size, jvmci_data_size); assert(nmethod_size == code_end() - header_begin(), "wrong nmethod size: %d != %d", nmethod_size, (int)(code_end() - header_begin())); @@ -1528,14 +1529,6 @@ nmethod::nmethod( // We need unique not null address _immutable_data = blob_end(); } - _mutable_data_size = mutable_data_size; - if (mutable_data_size > 0) { - assert(mutable_data != nullptr, "required"); - _mutable_data = mutable_data; - } else { - // We need unique not null address - _mutable_data = blob_end(); - } CHECKED_CAST(_nul_chk_table_offset, uint16_t, (align_up((int)dependencies->size_in_bytes(), oopSize))); CHECKED_CAST(_handler_table_offset, uint16_t, (_nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize))); _scopes_pcs_offset = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize); diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index bd761d61c3977..d056d044c63a5 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -303,7 +303,8 @@ class nmethod : public CodeBlob { int frame_size, ByteSize basic_lock_owner_sp_offset, /* synchronized natives only */ ByteSize basic_lock_sp_offset, /* synchronized natives only */ - OopMapSet* oop_maps); + OopMapSet* oop_maps, + int mutable_data_size); // For normal JIT compiled code nmethod(Method* method, @@ -314,7 +315,6 @@ class nmethod : public CodeBlob { int compile_id, int entry_bci, address immutable_data, - address mutable_data, CodeOffsets* offsets, int orig_pc_offset, DebugInformationRecorder *recorder, @@ -526,7 +526,7 @@ class nmethod : public CodeBlob { address insts_begin () const { return code_begin() ; } address insts_end () const { return header_begin() + _stub_offset ; } address stub_begin () const { return header_begin() + _stub_offset ; } - address stub_end () const { return data_begin() ; } + address stub_end () const { return code_end() ; } address exception_begin () const { return header_begin() + _exception_offset ; } address deopt_handler_begin () const { return header_begin() + _deopt_handler_offset ; } address deopt_mh_handler_begin() const { return header_begin() + _deopt_mh_handler_offset ; } diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 45db3b6b7f3d9..d6dcc4dae23d5 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -556,7 +556,7 @@ nonstatic_field(CodeBlob, _content_offset, int) \ nonstatic_field(CodeBlob, _code_offset, int) \ nonstatic_field(CodeBlob, _frame_complete_offset, int16_t) \ - nonstatic_field(CodeBlob, _data_offset, int) \ + nonstatic_field(CodeBlob, _code_end_offset, int) \ nonstatic_field(CodeBlob, _frame_size, int) \ nonstatic_field(CodeBlob, _oop_maps, ImmutableOopMapSet*) \ nonstatic_field(CodeBlob, _caller_must_gc_arguments, bool) \ From 0c70bd2d0dcbd5f68fb38da9ec10d4adbc6a4721 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Tue, 19 Nov 2024 00:52:54 +0300 Subject: [PATCH 4/5] update jvm.hotspot.code.CodeBlob class --- src/hotspot/share/runtime/vmStructs.cpp | 4 ++-- .../sun/jvm/hotspot/code/CodeBlob.java | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index d6dcc4dae23d5..8fb77e298acfe 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -560,6 +560,8 @@ nonstatic_field(CodeBlob, _frame_size, int) \ nonstatic_field(CodeBlob, _oop_maps, ImmutableOopMapSet*) \ nonstatic_field(CodeBlob, _caller_must_gc_arguments, bool) \ + nonstatic_field(CodeBlob, _mutable_data, address) \ + nonstatic_field(CodeBlob, _mutable_data_size, int) \ \ nonstatic_field(DeoptimizationBlob, _unpack_offset, int) \ \ @@ -592,8 +594,6 @@ nonstatic_field(nmethod, _osr_entry_point, address) \ nonstatic_field(nmethod, _immutable_data, address) \ nonstatic_field(nmethod, _immutable_data_size, int) \ - nonstatic_field(nmethod, _mutable_data, address) \ - nonstatic_field(nmethod, _mutable_data_size, int) \ nonstatic_field(nmethod, _compile_id, int) \ nonstatic_field(nmethod, _comp_level, CompLevel) \ volatile_nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \ diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java index 90e4b5b98b442..517291f0d0db2 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java @@ -47,10 +47,12 @@ public class CodeBlob extends VMObject { private static CIntField headerSizeField; private static CIntegerField contentOffsetField; private static CIntegerField codeOffsetField; + private static CIntegerField codeEndOffsetField; private static CIntField frameCompleteOffsetField; - private static CIntegerField dataOffsetField; private static CIntegerField frameSizeField; private static AddressField oopMapsField; + private static AddressField mutableDataField; + private static CIntegerField mutableDataSizeField; public CodeBlob(Address addr) { super(addr); @@ -68,9 +70,11 @@ private static void initialize(TypeDataBase db) { contentOffsetField = type.getCIntegerField("_content_offset"); codeOffsetField = type.getCIntegerField("_code_offset"); frameCompleteOffsetField = new CIntField(type.getCIntegerField("_frame_complete_offset"), 0); - dataOffsetField = type.getCIntegerField("_data_offset"); + codeEndOffsetField = type.getCIntegerField("_code_end_offset"); frameSizeField = type.getCIntegerField("_frame_size"); oopMapsField = type.getAddressField("_oop_maps"); + mutableDataField = type.getAddressField("_mutable_data"); + mutableDataSizeField = type.getCIntegerField("_mutable_data_size"); if (VM.getVM().isServerCompiler()) { matcherInterpreterFramePointerReg = @@ -92,15 +96,16 @@ public void update(Observable o, Object data) { public Address contentBegin() { return headerBegin().addOffsetTo(getContentOffset()); } - public Address contentEnd() { return headerBegin().addOffsetTo(getDataOffset()); } + public Address contentEnd() { return headerBegin().addOffsetTo(getCodeEndOffset()); } public Address codeBegin() { return headerBegin().addOffsetTo(getCodeOffset()); } - public Address codeEnd() { return headerBegin().addOffsetTo(getDataOffset()); } + public Address codeEnd() { return headerBegin().addOffsetTo(getCodeEndOffset()); } - public Address dataBegin() { return headerBegin().addOffsetTo(getDataOffset()); } + public Address dataBegin() { return mutableDataField.getValue(addr); } - public Address dataEnd() { return headerBegin().addOffsetTo(getSize()); } + public Address dataEnd() { return (dataBegin() == null) ? dataBegin() : + dataBegin().addOffsetTo(mutableDataSizeField.getValue(addr)); } // Offsets public int getContentOffset() { return (int) contentOffsetField.getValue(addr); } @@ -109,7 +114,7 @@ public void update(Observable o, Object data) { public long getFrameCompleteOffset() { return frameCompleteOffsetField.getValue(addr); } - public int getDataOffset() { return (int) dataOffsetField.getValue(addr); } + public int getCodeEndOffset() { return (int) codeEndOffsetField.getValue(addr); } // Sizes public int getSize() { return (int) sizeField.getValue(addr); } @@ -176,14 +181,15 @@ public NMethod asNMethodOrNull() { public int getDataSize() { return (int) dataEnd() .minus(dataBegin()); } // Containment - public boolean blobContains(Address addr) { return headerBegin() .lessThanOrEqual(addr) && dataEnd() .greaterThan(addr); } + public boolean blobContains(Address addr) { return headerBegin() .lessThanOrEqual(addr) && codeEnd() .greaterThan(addr); } // FIXME: add relocationContains public boolean contentContains(Address addr) { return contentBegin().lessThanOrEqual(addr) && contentEnd().greaterThan(addr); } public boolean codeContains(Address addr) { return codeBegin() .lessThanOrEqual(addr) && codeEnd() .greaterThan(addr); } - public boolean dataContains(Address addr) { return dataBegin() .lessThanOrEqual(addr) && dataEnd() .greaterThan(addr); } + public boolean dataContains(Address addr) { return (dataBegin() == null) ? false : + dataBegin() .lessThanOrEqual(addr) && dataEnd() .greaterThan(addr); } public boolean contains(Address addr) { return contentContains(addr); } From 88e31067761a80e9287f0541538c6b16a7f34be4 Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Tue, 19 Nov 2024 00:54:27 +0300 Subject: [PATCH 5/5] remove _code_end_offset --- src/hotspot/share/code/codeBlob.cpp | 5 ++--- src/hotspot/share/code/codeBlob.hpp | 9 +++------ src/hotspot/share/runtime/vmStructs.cpp | 1 - .../share/classes/sun/jvm/hotspot/code/CodeBlob.java | 1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 4c4e15b7a621d..5606ab142ac18 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -78,7 +78,6 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size _relocation_size(align_up(cb->total_relocation_size(), oopSize)), _content_offset(CodeBlob::align_code_offset(header_size)), _code_offset(_content_offset + cb->total_offset_of(cb->insts())), - _code_end_offset(_content_offset + align_up(cb->total_content_size(), oopSize)), _frame_size(frame_size), S390_ONLY(_ctable_offset(0) COMMA) _header_size(header_size), @@ -91,7 +90,8 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size assert(is_aligned(_size, oopSize), "unaligned size"); assert(is_aligned(header_size, oopSize), "unaligned size"); assert(is_aligned(_relocation_size, oopSize), "unaligned size"); - assert(_code_end_offset <= _size, "codeBlob is too small: %d > %d", _code_end_offset, _size); + int code_end_offset = _content_offset + align_up(cb->total_content_size(), oopSize); + assert(code_end_offset == _size, "wrong codeBlob size: %d != %d", _size, code_end_offset); assert(code_end() == content_end(), "must be the same - see code_end()"); #ifdef COMPILER1 // probably wrong for tiered @@ -119,7 +119,6 @@ CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, int size, uint16_t heade _relocation_size(0), _content_offset(CodeBlob::align_code_offset(header_size)), _code_offset(_content_offset), - _code_end_offset(size), _frame_size(0), S390_ONLY(_ctable_offset(0) COMMA) _header_size(header_size), diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 745637c2eda0d..b0e427806a23d 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -108,7 +108,6 @@ class CodeBlob { int _relocation_size; // size of relocation (could be bigger than 64Kb) int _content_offset; // offset to where content region begins (this includes consts, insts, stubs) int _code_offset; // offset to where instructions region begins (this includes insts, stubs) - int _code_end_offset; // offset to where code region ends int _frame_size; // size of stack frame in words (NOT slots. On x64 these are 64bit words) S390_ONLY(int _ctable_offset;) @@ -183,11 +182,10 @@ class CodeBlob { relocInfo* relocation_begin() const { return (relocInfo*)_mutable_data; } relocInfo* relocation_end() const { return (relocInfo*)((address)relocation_begin() + _relocation_size); } address content_begin() const { return (address) header_begin() + _content_offset; } - address content_end() const { return (address) header_begin() + _code_end_offset; } + address content_end() const { return (address) header_begin() + _size; } address code_begin() const { return (address) header_begin() + _code_offset; } - // code_end == content_end is true for all types of blobs for now, it is also checked in the constructor - address code_end() const { return (address) header_begin() + _code_end_offset; } - address blob_end() const { return (address) header_begin() + _size; } + address code_end() const { return (address) header_begin() + _size; } + address blob_end() const { return (address) header_begin() + _size; } // [relocations, oops, metatada, jvmci_data] stays in _mutable_data address mdata_begin() const { return mutable_data_begin(); } @@ -212,7 +210,6 @@ class CodeBlob { // Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed void adjust_size(size_t used) { _size = (int)used; - _code_end_offset = (int)used; } // Containment diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 8fb77e298acfe..65f392373d726 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -556,7 +556,6 @@ nonstatic_field(CodeBlob, _content_offset, int) \ nonstatic_field(CodeBlob, _code_offset, int) \ nonstatic_field(CodeBlob, _frame_complete_offset, int16_t) \ - nonstatic_field(CodeBlob, _code_end_offset, int) \ nonstatic_field(CodeBlob, _frame_size, int) \ nonstatic_field(CodeBlob, _oop_maps, ImmutableOopMapSet*) \ nonstatic_field(CodeBlob, _caller_must_gc_arguments, bool) \ diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java index 517291f0d0db2..a4cf76f8ee87a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/CodeBlob.java @@ -70,7 +70,6 @@ private static void initialize(TypeDataBase db) { contentOffsetField = type.getCIntegerField("_content_offset"); codeOffsetField = type.getCIntegerField("_code_offset"); frameCompleteOffsetField = new CIntField(type.getCIntegerField("_frame_complete_offset"), 0); - codeEndOffsetField = type.getCIntegerField("_code_end_offset"); frameSizeField = type.getCIntegerField("_frame_size"); oopMapsField = type.getAddressField("_oop_maps"); mutableDataField = type.getAddressField("_mutable_data");