diff a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp
--- a/src/hotspot/share/code/nmethod.cpp
+++ b/src/hotspot/share/code/nmethod.cpp
@@ -680,10 +680,16 @@
     _nmethod_end_offset      = _nul_chk_table_offset;
 #endif
     _compile_id              = compile_id;
     _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         = nullptr;
     _exception_cache         = nullptr;
     _pc_desc_container.reset_to(nullptr);
 
     _exception_offset        = code_offset()         + offsets->value(CodeOffsets::Exceptions);
@@ -865,10 +871,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         = nullptr;
     _scopes_data_begin       = (address) this + scopes_data_offset;
 
     _pc_desc_container.reset_to(scopes_pcs_begin());
@@ -2968,119 +2977,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_begin != nullptr &&) 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?
-      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();
+    }
+  }
+
+  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) {
@@ -3200,11 +3238,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);
