< prev index next >

src/hotspot/share/code/nmethod.cpp

Print this page
@@ -641,10 +641,16 @@
  #endif
      _compile_id              = compile_id;
      _comp_level              = CompLevel_none;
      _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
      _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
+ 
+     assert(!method->has_scalarized_args(), "scalarized native wrappers not supported yet"); // for the next 3 fields
+     _inline_entry_point       = _entry_point;
+     _verified_inline_entry_point = _verified_entry_point;
+     _verified_inline_ro_entry_point = _verified_entry_point;
+ 
      _osr_entry_point         = NULL;
      _exception_cache         = NULL;
      _pc_desc_container.reset_to(NULL);
      _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
  

@@ -814,10 +820,13 @@
  #else
      _nmethod_end_offset      = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
  #endif
      _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
      _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
+     _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);
      _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
      _exception_cache         = NULL;
      _scopes_data_begin       = (address) this + scopes_data_offset;
  
      _pc_desc_container.reset_to(scopes_pcs_begin());

@@ -933,14 +942,26 @@
    if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
      print_nmethod(printnmethods);
    }
  }
  
+ static nmethod* _nmethod_to_print = NULL;
+ static const CompiledEntrySignature* _nmethod_to_print_ces = NULL;
+ 
  void nmethod::print_nmethod(bool printmethod) {
    run_nmethod_entry_barrier(); // ensure all embedded OOPs are valid before printing
  
+   ResourceMark rm;
+   CompiledEntrySignature ces(method());
+   ces.compute_calling_conventions();
+   // ces.compute_calling_conventions() needs to grab the ProtectionDomainSet_lock, so we
+   // can't do that (inside nmethod::print_entry_parameters) while holding the ttyLocker.
+   // Hence we have do compute it here and pass via a global. Yuck.
    ttyLocker ttyl;  // keep the following output all in one block
+   assert(_nmethod_to_print == NULL && _nmethod_to_print_ces == NULL, "no nesting");
+   _nmethod_to_print = this;
+   _nmethod_to_print_ces = &ces;
    if (xtty != NULL) {
      xtty->begin_head("print_nmethod");
      log_identity(xtty);
      xtty->stamp();
      xtty->end_head();

@@ -1016,10 +1037,13 @@
  #endif
  
    if (xtty != NULL) {
      xtty->tail("print_nmethod");
    }
+ 
+   _nmethod_to_print = NULL;
+   _nmethod_to_print_ces = NULL;
  }
  
  
  // Promote one word from an assembly-time handle to a live embedded oop.
  inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) {

@@ -3134,119 +3158,150 @@
  
  const char* nmethod::nmethod_section_label(address pos) const {
    const char* label = NULL;
    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_begin != NULL &&) 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 != NULL) {
-       stream->bol();
-       stream->print_cr("%s", label);
-     }
-   }
- 
-   if (block_begin == entry_point()) {
-     Method* m = method();
-     if (m != NULL) {
-       stream->print("  # ");
-       m->print_value_on(stream);
-       stream->cr();
-     }
-     if (m != NULL && !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 != NULL) {
+         stream->bol();
+         stream->print_cr("%s", label);
        }
-       const char* spname = "sp"; // make arch-specific?
-       intptr_t out_preserve = 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 (_nmethod_to_print != this) {
+     return;
+   }
+   Method* m = method();
+   if (m == NULL || 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
+   const CompiledEntrySignature* ces = _nmethod_to_print_ces;
+   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) {

@@ -3366,11 +3421,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 != NULL; sd = sd->sender()) {
        st->move_to(column, 6, 0);
< prev index next >