< prev index next >

src/hotspot/share/code/nmethod.cpp

Print this page
@@ -722,10 +722,21 @@
      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();

@@ -1248,10 +1259,14 @@
    _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() {

@@ -1286,11 +1301,11 @@
    _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;

@@ -1494,10 +1509,13 @@
      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) {

@@ -3669,119 +3687,148 @@
  
  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) {
-     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, "");
+     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);
        }
-       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();
+     }
+   }
+ 
+   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());
        }
-       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();
+     } 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) {

@@ -3901,11 +3948,11 @@
            }
          default:
            break;
          }
        }
-       st->print(" {reexecute=%d rethrow=%d return_oop=%d}", sd->should_reexecute(), sd->rethrow_exception(), sd->return_oop());
+       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 >