src/share/vm/code/nmethod.cpp

changeset 1590
4e6abf09f540
parent 1576
b1f619d38249
child 1635
ba263cfb7611
     1.1 --- a/src/share/vm/code/nmethod.cpp	Fri Jan 08 09:42:31 2010 -0800
     1.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Jan 08 13:47:01 2010 -0800
     1.3 @@ -56,13 +56,13 @@
     1.4  #endif
     1.5  
     1.6  bool nmethod::is_compiled_by_c1() const {
     1.7 +  if (compiler() == NULL || method() == NULL)  return false;  // can happen during debug printing
     1.8    if (is_native_method()) return false;
     1.9 -  assert(compiler() != NULL, "must be");
    1.10    return compiler()->is_c1();
    1.11  }
    1.12  bool nmethod::is_compiled_by_c2() const {
    1.13 +  if (compiler() == NULL || method() == NULL)  return false;  // can happen during debug printing
    1.14    if (is_native_method()) return false;
    1.15 -  assert(compiler() != NULL, "must be");
    1.16    return compiler()->is_c2();
    1.17  }
    1.18  
    1.19 @@ -2399,6 +2399,107 @@
    1.20    return NULL;
    1.21  }
    1.22  
    1.23 +void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) {
    1.24 +  if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
    1.25 +  if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
    1.26 +  if (block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
    1.27 +  if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
    1.28 +  if (block_begin == consts_begin())            stream->print_cr("[Constants]");
    1.29 +  if (block_begin == entry_point()) {
    1.30 +    methodHandle m = method();
    1.31 +    if (m.not_null()) {
    1.32 +      stream->print("  # ");
    1.33 +      m->print_value_on(stream);
    1.34 +      stream->cr();
    1.35 +    }
    1.36 +    if (m.not_null() && !is_osr_method()) {
    1.37 +      ResourceMark rm;
    1.38 +      int sizeargs = m->size_of_parameters();
    1.39 +      BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
    1.40 +      VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
    1.41 +      {
    1.42 +        int sig_index = 0;
    1.43 +        if (!m->is_static())
    1.44 +          sig_bt[sig_index++] = T_OBJECT; // 'this'
    1.45 +        for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) {
    1.46 +          BasicType t = ss.type();
    1.47 +          sig_bt[sig_index++] = t;
    1.48 +          if (type2size[t] == 2) {
    1.49 +            sig_bt[sig_index++] = T_VOID;
    1.50 +          } else {
    1.51 +            assert(type2size[t] == 1, "size is 1 or 2");
    1.52 +          }
    1.53 +        }
    1.54 +        assert(sig_index == sizeargs, "");
    1.55 +      }
    1.56 +      const char* spname = "sp"; // make arch-specific?
    1.57 +      intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false);
    1.58 +      int stack_slot_offset = this->frame_size() * wordSize;
    1.59 +      int tab1 = 14, tab2 = 24;
    1.60 +      int sig_index = 0;
    1.61 +      int arg_index = (m->is_static() ? 0 : -1);
    1.62 +      bool did_old_sp = false;
    1.63 +      for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) {
    1.64 +        bool at_this = (arg_index == -1);
    1.65 +        bool at_old_sp = false;
    1.66 +        BasicType t = (at_this ? T_OBJECT : ss.type());
    1.67 +        assert(t == sig_bt[sig_index], "sigs in sync");
    1.68 +        if (at_this)
    1.69 +          stream->print("  # this: ");
    1.70 +        else
    1.71 +          stream->print("  # parm%d: ", arg_index);
    1.72 +        stream->move_to(tab1);
    1.73 +        VMReg fst = regs[sig_index].first();
    1.74 +        VMReg snd = regs[sig_index].second();
    1.75 +        if (fst->is_reg()) {
    1.76 +          stream->print("%s", fst->name());
    1.77 +          if (snd->is_valid())  {
    1.78 +            stream->print(":%s", snd->name());
    1.79 +          }
    1.80 +        } else if (fst->is_stack()) {
    1.81 +          int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
    1.82 +          if (offset == stack_slot_offset)  at_old_sp = true;
    1.83 +          stream->print("[%s+0x%x]", spname, offset);
    1.84 +        } else {
    1.85 +          stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
    1.86 +        }
    1.87 +        stream->print(" ");
    1.88 +        stream->move_to(tab2);
    1.89 +        stream->print("= ");
    1.90 +        if (at_this) {
    1.91 +          m->method_holder()->print_value_on(stream);
    1.92 +        } else {
    1.93 +          bool did_name = false;
    1.94 +          if (!at_this && ss.is_object()) {
    1.95 +            symbolOop name = ss.as_symbol_or_null();
    1.96 +            if (name != NULL) {
    1.97 +              name->print_value_on(stream);
    1.98 +              did_name = true;
    1.99 +            }
   1.100 +          }
   1.101 +          if (!did_name)
   1.102 +            stream->print("%s", type2name(t));
   1.103 +        }
   1.104 +        if (at_old_sp) {
   1.105 +          stream->print("  (%s of caller)", spname);
   1.106 +          did_old_sp = true;
   1.107 +        }
   1.108 +        stream->cr();
   1.109 +        sig_index += type2size[t];
   1.110 +        arg_index += 1;
   1.111 +        if (!at_this)  ss.next();
   1.112 +      }
   1.113 +      if (!did_old_sp) {
   1.114 +        stream->print("  # ");
   1.115 +        stream->move_to(tab1);
   1.116 +        stream->print("[%s+0x%x]", spname, stack_slot_offset);
   1.117 +        stream->print("  (%s of caller)", spname);
   1.118 +        stream->cr();
   1.119 +      }
   1.120 +    }
   1.121 +  }
   1.122 +}
   1.123 +
   1.124  void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
   1.125    // First, find an oopmap in (begin, end].
   1.126    // We use the odd half-closed interval so that oop maps and scope descs

mercurial