comparison src/share/vm/code/nmethod.cpp @ 1155:4e6abf09f540

6912062: disassembler plugin needs to produce symbolic information in product mode Summary: More informative disassembly in product mode. Also, a more consistent CompileCommand syntax. Reviewed-by: never
author jrose
date Fri, 08 Jan 2010 13:47:01 -0800
parents b1f619d38249
children ba263cfb7611
comparison
equal deleted inserted replaced
1153:bea7a22a6f79 1155:4e6abf09f540
54 #define DTRACE_METHOD_UNLOAD_PROBE(method) 54 #define DTRACE_METHOD_UNLOAD_PROBE(method)
55 55
56 #endif 56 #endif
57 57
58 bool nmethod::is_compiled_by_c1() const { 58 bool nmethod::is_compiled_by_c1() const {
59 if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
59 if (is_native_method()) return false; 60 if (is_native_method()) return false;
60 assert(compiler() != NULL, "must be");
61 return compiler()->is_c1(); 61 return compiler()->is_c1();
62 } 62 }
63 bool nmethod::is_compiled_by_c2() const { 63 bool nmethod::is_compiled_by_c2() const {
64 if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing
64 if (is_native_method()) return false; 65 if (is_native_method()) return false;
65 assert(compiler() != NULL, "must be");
66 return compiler()->is_c2(); 66 return compiler()->is_c2();
67 } 67 }
68 68
69 69
70 70
2397 p->obj_decode_offset(), p->should_reexecute()); 2397 p->obj_decode_offset(), p->should_reexecute());
2398 } 2398 }
2399 return NULL; 2399 return NULL;
2400 } 2400 }
2401 2401
2402 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) {
2403 if (block_begin == entry_point()) stream->print_cr("[Entry Point]");
2404 if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]");
2405 if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]");
2406 if (block_begin == stub_begin()) stream->print_cr("[Stub Code]");
2407 if (block_begin == consts_begin()) stream->print_cr("[Constants]");
2408 if (block_begin == entry_point()) {
2409 methodHandle m = method();
2410 if (m.not_null()) {
2411 stream->print(" # ");
2412 m->print_value_on(stream);
2413 stream->cr();
2414 }
2415 if (m.not_null() && !is_osr_method()) {
2416 ResourceMark rm;
2417 int sizeargs = m->size_of_parameters();
2418 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
2419 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
2420 {
2421 int sig_index = 0;
2422 if (!m->is_static())
2423 sig_bt[sig_index++] = T_OBJECT; // 'this'
2424 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) {
2425 BasicType t = ss.type();
2426 sig_bt[sig_index++] = t;
2427 if (type2size[t] == 2) {
2428 sig_bt[sig_index++] = T_VOID;
2429 } else {
2430 assert(type2size[t] == 1, "size is 1 or 2");
2431 }
2432 }
2433 assert(sig_index == sizeargs, "");
2434 }
2435 const char* spname = "sp"; // make arch-specific?
2436 intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false);
2437 int stack_slot_offset = this->frame_size() * wordSize;
2438 int tab1 = 14, tab2 = 24;
2439 int sig_index = 0;
2440 int arg_index = (m->is_static() ? 0 : -1);
2441 bool did_old_sp = false;
2442 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) {
2443 bool at_this = (arg_index == -1);
2444 bool at_old_sp = false;
2445 BasicType t = (at_this ? T_OBJECT : ss.type());
2446 assert(t == sig_bt[sig_index], "sigs in sync");
2447 if (at_this)
2448 stream->print(" # this: ");
2449 else
2450 stream->print(" # parm%d: ", arg_index);
2451 stream->move_to(tab1);
2452 VMReg fst = regs[sig_index].first();
2453 VMReg snd = regs[sig_index].second();
2454 if (fst->is_reg()) {
2455 stream->print("%s", fst->name());
2456 if (snd->is_valid()) {
2457 stream->print(":%s", snd->name());
2458 }
2459 } else if (fst->is_stack()) {
2460 int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
2461 if (offset == stack_slot_offset) at_old_sp = true;
2462 stream->print("[%s+0x%x]", spname, offset);
2463 } else {
2464 stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
2465 }
2466 stream->print(" ");
2467 stream->move_to(tab2);
2468 stream->print("= ");
2469 if (at_this) {
2470 m->method_holder()->print_value_on(stream);
2471 } else {
2472 bool did_name = false;
2473 if (!at_this && ss.is_object()) {
2474 symbolOop name = ss.as_symbol_or_null();
2475 if (name != NULL) {
2476 name->print_value_on(stream);
2477 did_name = true;
2478 }
2479 }
2480 if (!did_name)
2481 stream->print("%s", type2name(t));
2482 }
2483 if (at_old_sp) {
2484 stream->print(" (%s of caller)", spname);
2485 did_old_sp = true;
2486 }
2487 stream->cr();
2488 sig_index += type2size[t];
2489 arg_index += 1;
2490 if (!at_this) ss.next();
2491 }
2492 if (!did_old_sp) {
2493 stream->print(" # ");
2494 stream->move_to(tab1);
2495 stream->print("[%s+0x%x]", spname, stack_slot_offset);
2496 stream->print(" (%s of caller)", spname);
2497 stream->cr();
2498 }
2499 }
2500 }
2501 }
2502
2402 void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) { 2503 void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
2403 // First, find an oopmap in (begin, end]. 2504 // First, find an oopmap in (begin, end].
2404 // We use the odd half-closed interval so that oop maps and scope descs 2505 // We use the odd half-closed interval so that oop maps and scope descs
2405 // which are tied to the byte after a call are printed with the call itself. 2506 // which are tied to the byte after a call are printed with the call itself.
2406 address base = instructions_begin(); 2507 address base = instructions_begin();