< prev index next > src/hotspot/share/code/nmethod.cpp
Print this page
Method* callee = attached_method_before_pc(pc);
if (callee != nullptr) {
has_receiver = !(callee->access_flags().is_static());
has_appendix = false;
signature = callee->signature();
+
+ // If inline types are passed as fields, use the extended signature
+ // which contains the types of all (oop) fields of the inline type.
+ if (is_compiled_by_c2() && callee->has_scalarized_args()) {
+ const GrowableArray<SigEntry>* sig = callee->adapter()->get_sig_cc();
+ assert(sig != nullptr, "sig should never be null");
+ TempNewSymbol tmp_sig = SigEntry::create_symbol(sig);
+ has_receiver = false; // The extended signature contains the receiver type
+ fr.oops_compiled_arguments_do(tmp_sig, has_receiver, has_appendix, reg_map, f);
+ return;
+ }
} else {
SimpleScopeDesc ssd(this, pc);
Bytecode_invoke call(methodHandle(Thread::current(), ssd.method()), ssd.bci());
has_receiver = call.has_receiver();
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
CHECKED_CAST(_entry_offset, uint16_t, (offsets->value(CodeOffsets::Entry)));
CHECKED_CAST(_verified_entry_offset, uint16_t, (offsets->value(CodeOffsets::Verified_Entry)));
+ _inline_entry_point = entry_point();
+ _verified_inline_entry_point = verified_entry_point();
+ _verified_inline_ro_entry_point = verified_entry_point();
+
_skipped_instructions_size = code_buffer->total_skipped_instructions_size();
}
// Post initialization
void nmethod::post_init() {
_native_basic_lock_sp_offset(basic_lock_sp_offset)
{
{
debug_only(NoSafepointVerifier nsv;)
assert_locked_or_safepoint(CodeCache_lock);
!
init_defaults(code_buffer, offsets);
_osr_entry_point = nullptr;
_pc_desc_container = nullptr;
_entry_bci = InvocationEntryBci;
_native_basic_lock_sp_offset(basic_lock_sp_offset)
{
{
debug_only(NoSafepointVerifier nsv;)
assert_locked_or_safepoint(CodeCache_lock);
! assert(!method->has_scalarized_args(), "scalarized native wrappers not supported yet");
init_defaults(code_buffer, offsets);
_osr_entry_point = nullptr;
_pc_desc_container = nullptr;
_entry_bci = InvocationEntryBci;
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; )
#endif
+ _inline_entry_point = code_begin() + offsets->value(CodeOffsets::Inline_Entry);
+ _verified_inline_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Inline_Entry);
+ _verified_inline_ro_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Inline_Entry_RO);
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) {
const char* nmethod::nmethod_section_label(address pos) const {
const char* label = nullptr;
if (pos == code_begin()) label = "[Instructions begin]";
if (pos == entry_point()) label = "[Entry Point]";
if (pos == verified_entry_point()) label = "[Verified Entry Point]";
if (has_method_handle_invokes() && (pos == deopt_mh_handler_begin())) label = "[Deopt MH Handler Code]";
if (pos == consts_begin() && pos != insts_begin()) label = "[Constants]";
// Check stub_code before checking exception_handler or deopt_handler.
if (pos == this->stub_begin()) label = "[Stub Code]";
if (JVMCI_ONLY(_exception_offset >= 0 &&) pos == exception_begin()) label = "[Exception Handler]";
if (JVMCI_ONLY(_deopt_handler_offset != -1 &&) pos == deopt_handler_begin()) label = "[Deopt Handler Code]";
return label;
}
void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels) const {
if (print_section_labels) {
! const char* label = nmethod_section_label(block_begin);
! if (label != nullptr) {
! stream->bol();
! stream->print_cr("%s", label);
! }
! }
!
! if (block_begin == entry_point()) {
! Method* m = method();
! if (m != nullptr) {
! stream->print(" # ");
! m->print_value_on(stream);
- stream->cr();
- }
- if (m != nullptr && !is_osr_method()) {
- ResourceMark rm;
- int sizeargs = m->size_of_parameters();
- BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
- VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
- {
- int sig_index = 0;
- if (!m->is_static())
- sig_bt[sig_index++] = T_OBJECT; // 'this'
- for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) {
- BasicType t = ss.type();
- sig_bt[sig_index++] = t;
- if (type2size[t] == 2) {
- sig_bt[sig_index++] = T_VOID;
- } else {
- assert(type2size[t] == 1, "size is 1 or 2");
- }
- }
- assert(sig_index == sizeargs, "");
}
! const char* spname = "sp"; // make arch-specific?
! SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
! int stack_slot_offset = this->frame_size() * wordSize;
! int tab1 = 14, tab2 = 24;
! int sig_index = 0;
! int arg_index = (m->is_static() ? 0 : -1);
! bool did_old_sp = false;
! for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) {
! bool at_this = (arg_index == -1);
! bool at_old_sp = false;
! BasicType t = (at_this ? T_OBJECT : ss.type());
! assert(t == sig_bt[sig_index], "sigs in sync");
! if (at_this)
! stream->print(" # this: ");
! else
! stream->print(" # parm%d: ", arg_index);
! stream->move_to(tab1);
! VMReg fst = regs[sig_index].first();
! VMReg snd = regs[sig_index].second();
! if (fst->is_reg()) {
! stream->print("%s", fst->name());
! if (snd->is_valid()) {
! stream->print(":%s", snd->name());
! }
! } else if (fst->is_stack()) {
! int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
! if (offset == stack_slot_offset) at_old_sp = true;
! stream->print("[%s+0x%x]", spname, offset);
! } else {
! stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
! }
! stream->print(" ");
! stream->move_to(tab2);
! stream->print("= ");
! if (at_this) {
! m->method_holder()->print_value_on(stream);
! } else {
! bool did_name = false;
! if (!at_this && ss.is_reference()) {
! Symbol* name = ss.as_symbol();
! name->print_value_on(stream);
! did_name = true;
! }
! if (!did_name)
! stream->print("%s", type2name(t));
! }
! if (at_old_sp) {
! stream->print(" (%s of caller)", spname);
! did_old_sp = true;
! }
! stream->cr();
! sig_index += type2size[t];
! arg_index += 1;
! if (!at_this) ss.next();
}
! if (!did_old_sp) {
! stream->print(" # ");
! stream->move_to(tab1);
! stream->print("[%s+0x%x]", spname, stack_slot_offset);
! stream->print(" (%s of caller)", spname);
! stream->cr();
}
}
}
}
// Returns whether this nmethod has code comments.
bool nmethod::has_code_comment(address begin, address end) {
const char* nmethod::nmethod_section_label(address pos) const {
const char* label = nullptr;
if (pos == code_begin()) label = "[Instructions begin]";
if (pos == entry_point()) label = "[Entry Point]";
+ if (pos == inline_entry_point()) label = "[Inline Entry Point]";
if (pos == verified_entry_point()) label = "[Verified Entry Point]";
+ if (pos == verified_inline_entry_point()) label = "[Verified Inline Entry Point]";
+ if (pos == verified_inline_ro_entry_point()) label = "[Verified Inline Entry Point (RO)]";
if (has_method_handle_invokes() && (pos == deopt_mh_handler_begin())) label = "[Deopt MH Handler Code]";
if (pos == consts_begin() && pos != insts_begin()) label = "[Constants]";
// Check stub_code before checking exception_handler or deopt_handler.
if (pos == this->stub_begin()) label = "[Stub Code]";
if (JVMCI_ONLY(_exception_offset >= 0 &&) pos == exception_begin()) label = "[Exception Handler]";
if (JVMCI_ONLY(_deopt_handler_offset != -1 &&) pos == deopt_handler_begin()) label = "[Deopt Handler Code]";
return label;
}
+ static int maybe_print_entry_label(outputStream* stream, address pos, address entry, const char* label) {
+ if (pos == entry) {
+ stream->bol();
+ stream->print_cr("%s", label);
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels) const {
if (print_section_labels) {
! int n = 0;
! // Multiple entry points may be at the same position. Print them all.
! n += maybe_print_entry_label(stream, block_begin, entry_point(), "[Entry Point]");
! n += maybe_print_entry_label(stream, block_begin, inline_entry_point(), "[Inline Entry Point]");
! n += maybe_print_entry_label(stream, block_begin, verified_entry_point(), "[Verified Entry Point]");
! n += maybe_print_entry_label(stream, block_begin, verified_inline_entry_point(), "[Verified Inline Entry Point]");
! n += maybe_print_entry_label(stream, block_begin, verified_inline_ro_entry_point(), "[Verified Inline Entry Point (RO)]");
! if (n == 0) {
! const char* label = nmethod_section_label(block_begin);
! if (label != nullptr) {
! stream->bol();
! stream->print_cr("%s", label);
}
! }
! }
!
! Method* m = method();
! if (m == nullptr || is_osr_method()) {
! return;
! }
!
! // Print the name of the method (only once)
! address low = MIN4(entry_point(), verified_entry_point(), verified_inline_entry_point(), verified_inline_ro_entry_point());
! low = MIN2(low, inline_entry_point());
! assert(low != 0, "sanity");
! if (block_begin == low) {
! stream->print(" # ");
! m->print_value_on(stream);
! stream->cr();
! }
!
! // Print the arguments for the 3 types of verified entry points
! CompiledEntrySignature ces(m);
! ces.compute_calling_conventions(false);
! const GrowableArray<SigEntry>* sig_cc;
! const VMRegPair* regs;
! if (block_begin == verified_entry_point()) {
! sig_cc = ces.sig_cc();
! regs = ces.regs_cc();
! } else if (block_begin == verified_inline_entry_point()) {
! sig_cc = ces.sig();
! regs = ces.regs();
! } else if (block_begin == verified_inline_ro_entry_point()) {
! sig_cc = ces.sig_cc_ro();
! regs = ces.regs_cc_ro();
! } else {
! return;
! }
!
! bool has_this = !m->is_static();
! if (ces.has_inline_recv() && block_begin == verified_entry_point()) {
! // <this> argument is scalarized for verified_entry_point()
! has_this = false;
! }
! const char* spname = "sp"; // make arch-specific?
! int stack_slot_offset = this->frame_size() * wordSize;
! int tab1 = 14, tab2 = 24;
! int sig_index = 0;
! int arg_index = has_this ? -1 : 0;
! bool did_old_sp = false;
! for (ExtendedSignature sig = ExtendedSignature(sig_cc, SigEntryFilter()); !sig.at_end(); ++sig) {
! bool at_this = (arg_index == -1);
! bool at_old_sp = false;
! BasicType t = (*sig)._bt;
! if (at_this) {
! stream->print(" # this: ");
! } else {
+ stream->print(" # parm%d: ", arg_index);
+ }
+ stream->move_to(tab1);
+ VMReg fst = regs[sig_index].first();
+ VMReg snd = regs[sig_index].second();
+ if (fst->is_reg()) {
+ stream->print("%s", fst->name());
+ if (snd->is_valid()) {
+ stream->print(":%s", snd->name());
}
! } else if (fst->is_stack()) {
! int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
! if (offset == stack_slot_offset) at_old_sp = true;
! stream->print("[%s+0x%x]", spname, offset);
! } else {
! stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
+ }
+ stream->print(" ");
+ stream->move_to(tab2);
+ stream->print("= ");
+ if (at_this) {
+ m->method_holder()->print_value_on(stream);
+ } else {
+ bool did_name = false;
+ if (is_reference_type(t)) {
+ Symbol* name = (*sig)._symbol;
+ name->print_value_on(stream);
+ did_name = true;
}
+ if (!did_name)
+ stream->print("%s", type2name(t));
}
+ if (at_old_sp) {
+ stream->print(" (%s of caller)", spname);
+ did_old_sp = true;
+ }
+ stream->cr();
+ sig_index += type2size[t];
+ arg_index += 1;
+ }
+ if (!did_old_sp) {
+ stream->print(" # ");
+ stream->move_to(tab1);
+ stream->print("[%s+0x%x]", spname, stack_slot_offset);
+ stream->print(" (%s of caller)", spname);
+ stream->cr();
}
}
// Returns whether this nmethod has code comments.
bool nmethod::has_code_comment(address begin, address end) {
}
default:
break;
}
}
! st->print(" {reexecute=%d rethrow=%d return_oop=%d}", sd->should_reexecute(), sd->rethrow_exception(), sd->return_oop());
}
// Print all scopes
for (;sd != nullptr; sd = sd->sender()) {
st->move_to(column, 6, 0);
}
default:
break;
}
}
! st->print(" {reexecute=%d rethrow=%d return_oop=%d return_scalarized=%d}", sd->should_reexecute(), sd->rethrow_exception(), sd->return_oop(), sd->return_scalarized());
}
// Print all scopes
for (;sd != nullptr; sd = sd->sender()) {
st->move_to(column, 6, 0);
< prev index next >