8331087: Move immutable nmethod data from CodeCache

Reviewed-by: thartmann, dlong, dnsimon
This commit is contained in:
Vladimir Kozlov 2024-04-29 15:58:03 +00:00
parent 8b8fb6427e
commit bdcc2400db
5 changed files with 267 additions and 146 deletions

View File

@ -110,6 +110,11 @@
#endif
// Cast from int value to narrow type
#define CHECKED_CAST(result, T, thing) \
result = static_cast<T>(thing); \
assert(static_cast<int>(result) == thing, "failed: %d != %d", static_cast<int>(result), thing);
//---------------------------------------------------------------------------------
// NMethod statistics
// They are printed under various flags, including:
@ -121,26 +126,28 @@
// and make it simpler to print from the debugger.
struct java_nmethod_stats_struct {
uint nmethod_count;
uint total_size;
uint total_nm_size;
uint total_immut_size;
uint relocation_size;
uint consts_size;
uint insts_size;
uint stub_size;
uint scopes_data_size;
uint scopes_pcs_size;
uint oops_size;
uint metadata_size;
uint dependencies_size;
uint handler_table_size;
uint nul_chk_table_size;
uint handler_table_size;
uint scopes_pcs_size;
uint scopes_data_size;
#if INCLUDE_JVMCI
uint speculations_size;
uint jvmci_data_size;
#endif
uint oops_size;
uint metadata_size;
void note_nmethod(nmethod* nm) {
nmethod_count += 1;
total_size += nm->size();
total_nm_size += nm->size();
total_immut_size += nm->immutable_data_size();
relocation_size += nm->relocation_size();
consts_size += nm->consts_size();
insts_size += nm->insts_size();
@ -160,23 +167,60 @@ 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);
if (total_size != 0) tty->print_cr(" total in heap = %u (100%%)", total_size);
uint total_size = total_nm_size + total_immut_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);
}
uint header_size = (uint)(nmethod_count * sizeof(nmethod));
if (nmethod_count != 0) tty->print_cr(" header = %u (%f%%)", header_size, (header_size * 100.0f)/total_size);
if (relocation_size != 0) tty->print_cr(" relocation = %u (%f%%)", relocation_size, (relocation_size * 100.0f)/total_size);
if (consts_size != 0) tty->print_cr(" constants = %u (%f%%)", consts_size, (consts_size * 100.0f)/total_size);
if (insts_size != 0) tty->print_cr(" main code = %u (%f%%)", insts_size, (insts_size * 100.0f)/total_size);
if (stub_size != 0) tty->print_cr(" stub code = %u (%f%%)", stub_size, (stub_size * 100.0f)/total_size);
if (oops_size != 0) tty->print_cr(" oops = %u (%f%%)", oops_size, (oops_size * 100.0f)/total_size);
if (metadata_size != 0) tty->print_cr(" metadata = %u (%f%%)", metadata_size, (metadata_size * 100.0f)/total_size);
if (scopes_data_size != 0) tty->print_cr(" scopes data = %u (%f%%)", scopes_data_size, (scopes_data_size * 100.0f)/total_size);
if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %u (%f%%)", scopes_pcs_size, (scopes_pcs_size * 100.0f)/total_size);
if (dependencies_size != 0) tty->print_cr(" dependencies = %u (%f%%)", dependencies_size, (dependencies_size * 100.0f)/total_size);
if (handler_table_size != 0) tty->print_cr(" handler table = %u (%f%%)", handler_table_size, (handler_table_size * 100.0f)/total_size);
if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %u (%f%%)", nul_chk_table_size, (nul_chk_table_size * 100.0f)/total_size);
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);
}
if (insts_size != 0) {
tty->print_cr(" main code = %u (%f%%)", insts_size, (insts_size * 100.0f)/total_nm_size);
}
if (stub_size != 0) {
tty->print_cr(" stub code = %u (%f%%)", stub_size, (stub_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);
}
if (metadata_size != 0) {
tty->print_cr(" metadata = %u (%f%%)", metadata_size, (metadata_size * 100.0f)/total_nm_size);
}
#if INCLUDE_JVMCI
if (speculations_size != 0) tty->print_cr(" speculations = %u (%f%%)", speculations_size, (speculations_size * 100.0f)/total_size);
if (jvmci_data_size != 0) tty->print_cr(" JVMCI data = %u (%f%%)", jvmci_data_size, (jvmci_data_size * 100.0f)/total_size);
if (jvmci_data_size != 0) {
tty->print_cr(" JVMCI data = %u (%f%%)", jvmci_data_size, (jvmci_data_size * 100.0f)/total_nm_size);
}
#endif
if (total_immut_size != 0) {
tty->print_cr(" immutable data = %u (%f%%)", total_immut_size, (total_immut_size * 100.0f)/total_size);
}
if (dependencies_size != 0) {
tty->print_cr(" dependencies = %u (%f%%)", dependencies_size, (dependencies_size * 100.0f)/total_immut_size);
}
if (nul_chk_table_size != 0) {
tty->print_cr(" nul chk table = %u (%f%%)", nul_chk_table_size, (nul_chk_table_size * 100.0f)/total_immut_size);
}
if (handler_table_size != 0) {
tty->print_cr(" handler table = %u (%f%%)", handler_table_size, (handler_table_size * 100.0f)/total_immut_size);
}
if (scopes_pcs_size != 0) {
tty->print_cr(" scopes pcs = %u (%f%%)", scopes_pcs_size, (scopes_pcs_size * 100.0f)/total_immut_size);
}
if (scopes_data_size != 0) {
tty->print_cr(" scopes data = %u (%f%%)", scopes_data_size, (scopes_data_size * 100.0f)/total_immut_size);
}
#if INCLUDE_JVMCI
if (speculations_size != 0) {
tty->print_cr(" speculations = %u (%f%%)", speculations_size, (speculations_size * 100.0f)/total_immut_size);
}
#endif
}
};
@ -1101,31 +1145,40 @@ 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
int jvmci_data_size = compiler->is_jvmci() ? jvmci_data->size() : 0;
if (compiler->is_jvmci()) {
nmethod_size += align_up(jvmci_data->size(), oopSize);
}
#endif
int nmethod_size =
CodeBlob::allocation_size(code_buffer, sizeof(nmethod))
+ adjust_pcs_size(debug_info->pcs_size())
int immutable_data_size =
adjust_pcs_size(debug_info->pcs_size())
+ align_up((int)dependencies->size_in_bytes(), oopSize)
+ align_up(handler_table->size_in_bytes() , oopSize)
+ align_up(nul_chk_table->size_in_bytes() , oopSize)
#if INCLUDE_JVMCI
+ align_up(speculations_len , oopSize)
+ align_up(jvmci_data_size , oopSize)
#endif
+ align_up(debug_info->data_size() , oopSize);
// First, allocate space for immutable data in C heap.
address immutable_data = nullptr;
if (immutable_data_size > 0) {
immutable_data = (address)os::malloc(immutable_data_size, mtCode);
if (immutable_data == nullptr) {
vm_exit_out_of_memory(immutable_data_size, OOM_MALLOC_ERROR, "nmethod: no space for immutable data");
return nullptr;
}
}
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
nm = new (nmethod_size, comp_level)
nmethod(method(), compiler->type(), nmethod_size, compile_id, entry_bci, offsets,
orig_pc_offset, debug_info, dependencies, code_buffer, frame_size,
oop_maps,
handler_table,
nul_chk_table,
compiler,
comp_level
nmethod(method(), compiler->type(), nmethod_size, immutable_data_size,
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
, speculations,
speculations_len,
@ -1196,11 +1249,11 @@ void nmethod::init_defaults(CodeBuffer *code_buffer, CodeOffsets* offsets) {
int consts_offset = code_buffer->total_offset_of(code_buffer->consts());
assert(consts_offset == 0, "const_offset: %d", consts_offset);
_entry_offset = checked_cast<uint16_t>(offsets->value(CodeOffsets::Entry));
_verified_entry_offset = checked_cast<uint16_t>(offsets->value(CodeOffsets::Verified_Entry));
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
_skipped_instructions_size = checked_cast<uint16_t>(code_buffer->total_skipped_instructions_size());
CHECKED_CAST(_entry_offset, uint16_t, (offsets->value(CodeOffsets::Entry)));
CHECKED_CAST(_verified_entry_offset, uint16_t, (offsets->value(CodeOffsets::Verified_Entry)));
CHECKED_CAST(_skipped_instructions_size, uint16_t, (code_buffer->total_skipped_instructions_size()));
}
// Post initialization
@ -1262,21 +1315,26 @@ nmethod::nmethod(
_deopt_mh_handler_offset = 0;
_unwind_handler_offset = 0;
_metadata_offset = checked_cast<uint16_t>(align_up(code_buffer->total_oop_size(), oopSize));
_dependencies_offset = checked_cast<uint16_t>(_metadata_offset + align_up(code_buffer->total_metadata_size(), wordSize));
_scopes_pcs_offset = _dependencies_offset;
_scopes_data_offset = _scopes_pcs_offset;
_handler_table_offset = _scopes_data_offset;
_nul_chk_table_offset = _handler_table_offset;
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);
#if INCLUDE_JVMCI
_speculations_offset = _nul_chk_table_offset;
_jvmci_data_offset = _speculations_offset;
DEBUG_ONLY( int data_end_offset = _jvmci_data_offset; )
#else
DEBUG_ONLY( int data_end_offset = _nul_chk_table_offset; )
// 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));
// native wrapper does not have read-only data but we need unique not null address
_immutable_data = data_end();
_immutable_data_size = 0;
_nul_chk_table_offset = 0;
_handler_table_offset = 0;
_scopes_pcs_offset = 0;
_scopes_data_offset = 0;
#if INCLUDE_JVMCI
_speculations_offset = 0;
#endif
code_buffer->copy_code_and_locs_to(this);
code_buffer->copy_values_to(this);
@ -1343,8 +1401,10 @@ nmethod::nmethod(
Method* method,
CompilerType type,
int nmethod_size,
int immutable_data_size,
int compile_id,
int entry_bci,
address immutable_data,
CodeOffsets* offsets,
int orig_pc_offset,
DebugInformationRecorder* debug_info,
@ -1421,25 +1481,48 @@ nmethod::nmethod(
}
}
if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
_unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler);
// C1 generates UnwindHandler at the end of instructions section.
// Calculate positive offset as distance between the start of stubs section
// (which is also the end of instructions section) and the start of the handler.
int unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler);
CHECKED_CAST(_unwind_handler_offset, int16_t, (_stub_offset - unwind_handler_offset));
} else {
_unwind_handler_offset = -1;
}
_metadata_offset = checked_cast<uint16_t>(align_up(code_buffer->total_oop_size(), oopSize));
_dependencies_offset = checked_cast<uint16_t>(_metadata_offset + align_up(code_buffer->total_metadata_size(), wordSize));
_scopes_pcs_offset = checked_cast<uint16_t>(_dependencies_offset + align_up((int)dependencies->size_in_bytes(), oopSize));
_scopes_data_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size());
_handler_table_offset = _scopes_data_offset + align_up(debug_info->data_size (), oopSize);
_nul_chk_table_offset = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);
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);
#if INCLUDE_JVMCI
_speculations_offset = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
_jvmci_data_offset = _speculations_offset + align_up(speculations_len, oopSize);
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); )
DEBUG_ONLY( int data_end_offset = _jvmci_data_offset + align_up(jvmci_data_size, oopSize); )
#else
DEBUG_ONLY( int data_end_offset = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize); )
DEBUG_ONLY( int data_end_offset = metadata_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_offset() + data_end_offset) <= nmethod_size, "wrong nmethod's size: %d > %d",
(data_offset() + data_end_offset), nmethod_size);
_immutable_data_size = immutable_data_size;
if (immutable_data_size > 0) {
assert(immutable_data != nullptr, "required");
_immutable_data = immutable_data;
} else {
// We need unique not null address
_immutable_data = data_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);
_scopes_data_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size());
#if INCLUDE_JVMCI
_speculations_offset = _scopes_data_offset + align_up(debug_info->data_size(), oopSize);
DEBUG_ONLY( int immutable_data_end_offset = _speculations_offset + align_up(speculations_len, oopSize); )
#else
DEBUG_ONLY( int immutable_data_end_offset = _scopes_data_offset + align_up(debug_info->data_size(), oopSize); )
#endif
assert(immutable_data_end_offset <= immutable_data_size, "wrong read-only data size: %d > %d",
immutable_data_end_offset, immutable_data_size);
// Copy code and relocation info
code_buffer->copy_code_and_locs_to(this);
@ -2047,6 +2130,10 @@ void nmethod::purge(bool unregister_nmethod) {
}
delete[] _compiled_ic_data;
if (_immutable_data != data_end()) {
os::free(_immutable_data);
_immutable_data = data_end(); // Valid not null address
}
if (unregister_nmethod) {
Universe::heap()->unregister_nmethod(this);
}
@ -2679,7 +2766,7 @@ PcDesc* PcDescContainer::find_pc_desc_internal(address pc, bool approximate, add
// Find the last pc_offset less than the given offset.
// The successor must be the required match, if there is a match at all.
// (Use a fixed radix to avoid expensive affine pointer arithmetic.)
PcDesc* lower = lower_incl; // this is initial sentiel
PcDesc* lower = lower_incl; // this is initial sentinel
PcDesc* upper = upper_incl - 1; // exclude final sentinel
if (lower >= upper) return nullptr; // no PcDescs at all
@ -3002,35 +3089,41 @@ void nmethod::print(outputStream* st) const {
p2i(metadata_begin()),
p2i(metadata_end()),
metadata_size());
if (scopes_data_size () > 0) st->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(scopes_data_begin()),
p2i(scopes_data_end()),
scopes_data_size());
if (scopes_pcs_size () > 0) st->print_cr(" scopes pcs [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(scopes_pcs_begin()),
p2i(scopes_pcs_end()),
scopes_pcs_size());
#if INCLUDE_JVMCI
if (jvmci_data_size () > 0) st->print_cr(" JVMCI data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(jvmci_data_begin()),
p2i(jvmci_data_end()),
jvmci_data_size());
#endif
if (immutable_data_size() > 0) st->print_cr(" immutable data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(immutable_data_begin()),
p2i(immutable_data_end()),
immutable_data_size());
if (dependencies_size () > 0) st->print_cr(" dependencies [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(dependencies_begin()),
p2i(dependencies_end()),
dependencies_size());
if (handler_table_size() > 0) st->print_cr(" handler table [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(handler_table_begin()),
p2i(handler_table_end()),
handler_table_size());
if (nul_chk_table_size() > 0) st->print_cr(" nul chk table [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(nul_chk_table_begin()),
p2i(nul_chk_table_end()),
nul_chk_table_size());
if (handler_table_size() > 0) st->print_cr(" handler table [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(handler_table_begin()),
p2i(handler_table_end()),
handler_table_size());
if (scopes_pcs_size () > 0) st->print_cr(" scopes pcs [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(scopes_pcs_begin()),
p2i(scopes_pcs_end()),
scopes_pcs_size());
if (scopes_data_size () > 0) st->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(scopes_data_begin()),
p2i(scopes_data_end()),
scopes_data_size());
#if INCLUDE_JVMCI
if (speculations_size () > 0) st->print_cr(" speculations [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(speculations_begin()),
p2i(speculations_end()),
speculations_size());
if (jvmci_data_size () > 0) st->print_cr(" JVMCI data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(jvmci_data_begin()),
p2i(jvmci_data_end()),
jvmci_data_size());
#endif
}

View File

@ -195,6 +195,9 @@ class nmethod : public CodeBlob {
};
};
// nmethod's read-only data
address _immutable_data;
PcDescContainer* _pc_desc_container;
ExceptionCache* volatile _exception_cache;
@ -211,6 +214,7 @@ class nmethod : public CodeBlob {
uint16_t _entry_offset; // entry point with class check
uint16_t _verified_entry_offset; // entry point without class check
int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method
int _immutable_data_size;
// _consts_offset == _content_offset because SECT_CONSTS is first in code buffer
@ -224,21 +228,27 @@ class nmethod : public CodeBlob {
// All deoptee's at a MethodHandle call site will resume execution
// at this location described by this offset.
int _deopt_mh_handler_offset;
// Offset of the unwind handler if it exists
int _unwind_handler_offset;
// Offset (from insts_end) of the unwind handler if it exists
int16_t _unwind_handler_offset;
// Number of arguments passed on the stack
uint16_t _num_stack_arg_slots;
uint16_t _skipped_instructions_size;
// Offsets in mutable data section
// _oops_offset == _data_offset, offset where embedded oop table begins (inside data)
uint16_t _metadata_offset; // embedded meta data table
uint16_t _dependencies_offset;
uint16_t _scopes_pcs_offset;
#if INCLUDE_JVMCI
uint16_t _jvmci_data_offset;
#endif
// Offset in immutable data section
// _dependencies_offset == 0
uint16_t _nul_chk_table_offset;
uint16_t _handler_table_offset; // This table could be big in C1 code
int _scopes_pcs_offset;
int _scopes_data_offset;
int _handler_table_offset;
int _nul_chk_table_offset;
#if INCLUDE_JVMCI
int _speculations_offset;
int _jvmci_data_offset;
#endif
// location in frame (offset for sp) that deopt can store the original
@ -249,8 +259,6 @@ class nmethod : public CodeBlob {
CompLevel _comp_level; // compilation level (s1)
CompilerType _compiler_type; // which compiler made this nmethod (u1)
uint16_t _num_stack_arg_slots; // Number of arguments passed on the stack
#if INCLUDE_RTM_OPT
// RTM state at compile time. Used during deoptimization to decide
// whether to restart collecting RTM locking abort statistic again.
@ -307,8 +315,10 @@ class nmethod : public CodeBlob {
nmethod(Method* method,
CompilerType type,
int nmethod_size,
int immutable_data_size,
int compile_id,
int entry_bci,
address immutable_data,
CodeOffsets* offsets,
int orig_pc_offset,
DebugInformationRecorder *recorder,
@ -524,48 +534,56 @@ public:
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 ; }
address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : nullptr; }
oop* oops_begin () const { return (oop*) data_begin(); }
oop* oops_end () const { return (oop*) (data_begin() + _metadata_offset) ; }
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) ; }
Metadata** metadata_end () const { return (Metadata**) (data_begin() + _dependencies_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(); }
#else
Metadata** metadata_end () const { return (Metadata**) data_end(); }
#endif
address dependencies_begin () const { return data_begin() + _dependencies_offset ; }
address dependencies_end () const { return data_begin() + _scopes_pcs_offset ; }
PcDesc* scopes_pcs_begin () const { return (PcDesc*)(data_begin() + _scopes_pcs_offset) ; }
PcDesc* scopes_pcs_end () const { return (PcDesc*)(data_begin() + _scopes_data_offset) ; }
address scopes_data_begin () const { return data_begin() + _scopes_data_offset ; }
address scopes_data_end () const { return data_begin() + _handler_table_offset ; }
address handler_table_begin () const { return data_begin() + _handler_table_offset ; }
address handler_table_end () const { return data_begin() + _nul_chk_table_offset ; }
address nul_chk_table_begin () const { return data_begin() + _nul_chk_table_offset ; }
// immutable data
address immutable_data_begin () const { return _immutable_data; }
address immutable_data_end () const { return _immutable_data + _immutable_data_size ; }
address dependencies_begin () const { return _immutable_data; }
address dependencies_end () const { return _immutable_data + _nul_chk_table_offset; }
address nul_chk_table_begin () const { return _immutable_data + _nul_chk_table_offset; }
address nul_chk_table_end () const { return _immutable_data + _handler_table_offset; }
address handler_table_begin () const { return _immutable_data + _handler_table_offset; }
address handler_table_end () const { return _immutable_data + _scopes_pcs_offset ; }
PcDesc* scopes_pcs_begin () const { return (PcDesc*)(_immutable_data + _scopes_pcs_offset) ; }
PcDesc* scopes_pcs_end () const { return (PcDesc*)(_immutable_data + _scopes_data_offset) ; }
address scopes_data_begin () const { return _immutable_data + _scopes_data_offset ; }
#if INCLUDE_JVMCI
address nul_chk_table_end () const { return data_begin() + _speculations_offset ; }
address speculations_begin () const { return data_begin() + _speculations_offset ; }
address speculations_end () const { return data_begin() + _jvmci_data_offset ; }
address jvmci_data_begin () const { return data_begin() + _jvmci_data_offset ; }
address jvmci_data_end () const { return data_end(); }
address scopes_data_end () const { return _immutable_data + _speculations_offset ; }
address speculations_begin () const { return _immutable_data + _speculations_offset ; }
address speculations_end () const { return immutable_data_end(); }
#else
address nul_chk_table_end () const { return data_end(); }
address scopes_data_end () const { return immutable_data_end(); }
#endif
// Sizes
int consts_size () const { return int( consts_end () - consts_begin ()); }
int insts_size () const { return int( insts_end () - insts_begin ()); }
int stub_size () const { return int( stub_end () - stub_begin ()); }
int oops_size () const { return int((address) oops_end () - (address) oops_begin ()); }
int metadata_size () const { return int((address) metadata_end () - (address) metadata_begin ()); }
int scopes_data_size () const { return int( scopes_data_end () - scopes_data_begin ()); }
int scopes_pcs_size () const { return int((intptr_t)scopes_pcs_end () - (intptr_t)scopes_pcs_begin ()); }
int dependencies_size () const { return int( dependencies_end () - dependencies_begin ()); }
int handler_table_size() const { return int( handler_table_end() - handler_table_begin()); }
int nul_chk_table_size() const { return int( nul_chk_table_end() - nul_chk_table_begin()); }
int immutable_data_size() const { return _immutable_data_size; }
int consts_size () const { return int( consts_end () - consts_begin ()); }
int insts_size () const { return int( insts_end () - insts_begin ()); }
int stub_size () const { return int( stub_end () - stub_begin ()); }
int oops_size () const { return int((address) oops_end () - (address) oops_begin ()); }
int metadata_size () const { return int((address) metadata_end () - (address) metadata_begin ()); }
int scopes_data_size () const { return int( scopes_data_end () - scopes_data_begin ()); }
int scopes_pcs_size () const { return int((intptr_t)scopes_pcs_end () - (intptr_t)scopes_pcs_begin ()); }
int dependencies_size () const { return int( dependencies_end () - dependencies_begin ()); }
int handler_table_size () const { return int( handler_table_end() - handler_table_begin()); }
int nul_chk_table_size () const { return int( nul_chk_table_end() - nul_chk_table_begin()); }
#if INCLUDE_JVMCI
int speculations_size () const { return int( speculations_end () - speculations_begin ()); }
int jvmci_data_size () const { return int( jvmci_data_end () - jvmci_data_begin ()); }
int speculations_size () const { return int( speculations_end () - speculations_begin ()); }
int jvmci_data_size () const { return int( jvmci_data_end () - jvmci_data_begin ()); }
#endif
int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; }

View File

@ -576,14 +576,15 @@
nonstatic_field(nmethod, _orig_pc_offset, int) \
nonstatic_field(nmethod, _stub_offset, int) \
nonstatic_field(nmethod, _metadata_offset, u2) \
nonstatic_field(nmethod, _scopes_pcs_offset, u2) \
nonstatic_field(nmethod, _scopes_pcs_offset, int) \
nonstatic_field(nmethod, _scopes_data_offset, int) \
nonstatic_field(nmethod, _dependencies_offset, u2) \
nonstatic_field(nmethod, _handler_table_offset, int) \
nonstatic_field(nmethod, _nul_chk_table_offset, int) \
nonstatic_field(nmethod, _handler_table_offset, u2) \
nonstatic_field(nmethod, _nul_chk_table_offset, u2) \
nonstatic_field(nmethod, _entry_offset, u2) \
nonstatic_field(nmethod, _verified_entry_offset, u2) \
nonstatic_field(nmethod, _osr_entry_point, address) \
nonstatic_field(nmethod, _immutable_data, address) \
nonstatic_field(nmethod, _immutable_data_size, int) \
nonstatic_field(nmethod, _compile_id, int) \
nonstatic_field(nmethod, _comp_level, CompLevel) \
volatile_nonstatic_field(nmethod, _exception_cache, ExceptionCache*) \

View File

@ -42,6 +42,8 @@ public class NMethod extends CodeBlob {
private static CIntegerField entryBCIField;
/** To support simple linked-list chaining of nmethods */
private static AddressField osrLinkField;
private static AddressField immutableDataField;
private static CIntegerField immutableDataSizeField;
/** Offsets for different nmethod parts */
private static CIntegerField exceptionOffsetField;
@ -50,11 +52,10 @@ public class NMethod extends CodeBlob {
private static CIntegerField origPCOffsetField;
private static CIntegerField stubOffsetField;
private static CIntField metadataOffsetField;
private static CIntField dependenciesOffsetField;
private static CIntField scopesPCsOffsetField;
private static CIntField handlerTableOffsetField;
private static CIntField nulChkTableOffsetField;
private static CIntegerField scopesPCsOffsetField;
private static CIntegerField scopesDataOffsetField;
private static CIntegerField handlerTableOffsetField;
private static CIntegerField nulChkTableOffsetField;
/** Offsets for entry points */
/** Entry point with class check */
@ -82,6 +83,8 @@ public class NMethod extends CodeBlob {
methodField = type.getAddressField("_method");
entryBCIField = type.getCIntegerField("_entry_bci");
osrLinkField = type.getAddressField("_osr_link");
immutableDataField = type.getAddressField("_immutable_data");
immutableDataSizeField = type.getCIntegerField("_immutable_data_size");
exceptionOffsetField = type.getCIntegerField("_exception_offset");
deoptHandlerOffsetField = type.getCIntegerField("_deopt_handler_offset");
@ -89,11 +92,10 @@ public class NMethod extends CodeBlob {
origPCOffsetField = type.getCIntegerField("_orig_pc_offset");
stubOffsetField = type.getCIntegerField("_stub_offset");
metadataOffsetField = new CIntField(type.getCIntegerField("_metadata_offset"), 0);
dependenciesOffsetField = new CIntField(type.getCIntegerField("_dependencies_offset"), 0);
scopesPCsOffsetField = new CIntField(type.getCIntegerField("_scopes_pcs_offset"), 0);
scopesPCsOffsetField = type.getCIntegerField("_scopes_pcs_offset");
scopesDataOffsetField = type.getCIntegerField("_scopes_data_offset");
handlerTableOffsetField = type.getCIntegerField("_handler_table_offset");
nulChkTableOffsetField = type.getCIntegerField("_nul_chk_table_offset");
handlerTableOffsetField = new CIntField(type.getCIntegerField("_handler_table_offset"), 0);
nulChkTableOffsetField = new CIntField(type.getCIntegerField("_nul_chk_table_offset"), 0);
entryOffsetField = new CIntField(type.getCIntegerField("_entry_offset"), 0);
verifiedEntryOffsetField = new CIntField(type.getCIntegerField("_verified_entry_offset"), 0);
osrEntryPointField = type.getAddressField("_osr_entry_point");
@ -133,18 +135,22 @@ public class NMethod extends CodeBlob {
public Address oopsBegin() { return dataBegin(); }
public Address oopsEnd() { return dataBegin().addOffsetTo(getMetadataOffset()); }
public Address metadataBegin() { return dataBegin().addOffsetTo(getMetadataOffset()); }
public Address metadataEnd() { return dataBegin().addOffsetTo(getDependenciesOffset()); }
public Address dependenciesBegin() { return dataBegin().addOffsetTo(getDependenciesOffset()); }
public Address dependenciesEnd() { return dataBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataBegin() { return dataBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataEnd() { return dataBegin().addOffsetTo(getScopesPCsOffset()); }
public Address scopesPCsBegin() { return dataBegin().addOffsetTo(getScopesPCsOffset()); }
public Address scopesPCsEnd() { return dataBegin().addOffsetTo(getHandlerTableOffset()); }
public Address handlerTableBegin() { return dataBegin().addOffsetTo(getHandlerTableOffset()); }
public Address handlerTableEnd() { return dataBegin().addOffsetTo(getNulChkTableOffset()); }
public Address nulChkTableBegin() { return dataBegin().addOffsetTo(getNulChkTableOffset()); }
public Address nulChkTableEnd() { return dataEnd(); }
public Address metadataEnd() { return dataEnd(); }
public Address immutableDataBegin() { return immutableDataField.getValue(addr); }
public Address immutableDataEnd() { return immutableDataBegin().addOffsetTo(getImmutableDataSize()); }
public Address dependenciesBegin() { return immutableDataBegin(); }
public Address dependenciesEnd() { return immutableDataBegin().addOffsetTo(getHandlerTableOffset()); }
public Address handlerTableBegin() { return immutableDataBegin().addOffsetTo(getHandlerTableOffset()); }
public Address handlerTableEnd() { return immutableDataBegin().addOffsetTo(getNulChkTableOffset()); }
public Address nulChkTableBegin() { return immutableDataBegin().addOffsetTo(getNulChkTableOffset()); }
public Address nulChkTableEnd() { return immutableDataBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataBegin() { return immutableDataBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataEnd() { return immutableDataBegin().addOffsetTo(getScopesPCsOffset()); }
public Address scopesPCsBegin() { return immutableDataBegin().addOffsetTo(getScopesPCsOffset()); }
public Address scopesPCsEnd() { return immutableDataEnd(); }
public int getImmutableDataSize() { return (int) immutableDataSizeField.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()); }
@ -161,7 +167,10 @@ public class NMethod extends CodeBlob {
return
constantsSize() +
instsSize() +
stubSize() +
stubSize();
}
public int immutableDataSize() {
return
scopesDataSize() +
scopesPCsSize() +
dependenciesSize() +
@ -516,7 +525,6 @@ public class NMethod extends CodeBlob {
private int getMetadataOffset() { return (int) metadataOffsetField .getValue(addr); }
private int getScopesDataOffset() { return (int) scopesDataOffsetField .getValue(addr); }
private int getScopesPCsOffset() { return (int) scopesPCsOffsetField .getValue(addr); }
private int getDependenciesOffset() { return (int) dependenciesOffsetField.getValue(addr); }
private int getHandlerTableOffset() { return (int) handlerTableOffsetField.getValue(addr); }
private int getNulChkTableOffset() { return (int) nulChkTableOffsetField .getValue(addr); }
private int getCompLevel() { return (int) compLevelField .getValue(addr); }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
* @bug 8207355
* @compile TestLinearScanOrder.jasm
* @run main/othervm -Xcomp -XX:+TieredCompilation -XX:TieredStopAtLevel=1
* -XX:+IgnoreUnrecognizedVMOptions -XX:NMethodSizeLimit=655360
* -XX:CompileCommand=compileonly,compiler.c1.TestLinearScanOrder::test
* compiler.c1.TestLinearScanOrderMain
*/