< prev index next >

src/hotspot/share/code/nmethod.cpp

Print this page




 581     _entry_bci               = InvocationEntryBci;
 582     // We have no exception handler or deopt handler make the
 583     // values something that will never match a pc like the nmethod vtable entry
 584     _exception_offset        = 0;
 585     _orig_pc_offset          = 0;
 586 
 587     _consts_offset           = data_offset();
 588     _stub_offset             = data_offset();
 589     _oops_offset             = data_offset();
 590     _metadata_offset         = _oops_offset         + align_up(code_buffer->total_oop_size(), oopSize);
 591     scopes_data_offset       = _metadata_offset     + align_up(code_buffer->total_metadata_size(), wordSize);
 592     _scopes_pcs_offset       = scopes_data_offset;
 593     _dependencies_offset     = _scopes_pcs_offset;
 594     _handler_table_offset    = _dependencies_offset;
 595     _nul_chk_table_offset    = _handler_table_offset;
 596     _nmethod_end_offset      = _nul_chk_table_offset;
 597     _compile_id              = compile_id;
 598     _comp_level              = CompLevel_none;
 599     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
 600     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);

 601     _osr_entry_point         = NULL;
 602     _exception_cache         = NULL;
 603     _pc_desc_container.reset_to(NULL);
 604     _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
 605 
 606     _scopes_data_begin = (address) this + scopes_data_offset;
 607     _deopt_handler_begin = (address) this + deoptimize_offset;
 608     _deopt_mh_handler_begin = (address) this + deoptimize_mh_offset;
 609 
 610     code_buffer->copy_code_and_locs_to(this);
 611     code_buffer->copy_values_to(this);
 612 
 613     clear_unloading_state();
 614     if (ScavengeRootsInCode) {
 615       Universe::heap()->register_nmethod(this);
 616     }
 617     debug_only(Universe::heap()->verify_nmethod(this));
 618     CodeCache::commit(this);
 619   }
 620 


 741     }
 742 #endif
 743     }
 744     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
 745       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
 746     } else {
 747       _unwind_handler_offset = -1;
 748     }
 749 
 750     _oops_offset             = data_offset();
 751     _metadata_offset         = _oops_offset          + align_up(code_buffer->total_oop_size(), oopSize);
 752     int scopes_data_offset   = _metadata_offset      + align_up(code_buffer->total_metadata_size(), wordSize);
 753 
 754     _scopes_pcs_offset       = scopes_data_offset    + align_up(debug_info->data_size       (), oopSize);
 755     _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
 756     _handler_table_offset    = _dependencies_offset  + align_up((int)dependencies->size_in_bytes (), oopSize);
 757     _nul_chk_table_offset    = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);
 758     _nmethod_end_offset      = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
 759     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
 760     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);

 761     _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
 762     _exception_cache         = NULL;
 763 
 764     _scopes_data_begin = (address) this + scopes_data_offset;
 765 
 766     _pc_desc_container.reset_to(scopes_pcs_begin());
 767 
 768     code_buffer->copy_code_and_locs_to(this);
 769     // Copy contents of ScopeDescRecorder to nmethod
 770     code_buffer->copy_values_to(this);
 771     debug_info->copy_to(this);
 772     dependencies->copy_to(this);
 773     clear_unloading_state();
 774     if (ScavengeRootsInCode) {
 775       Universe::heap()->register_nmethod(this);
 776     }
 777     debug_only(Universe::heap()->verify_nmethod(this));
 778 
 779     CodeCache::commit(this);
 780 


2498 
2499         default:
2500           break;
2501     }
2502   }
2503   return have_one ? "other" : NULL;
2504 }
2505 
2506 // Return a the last scope in (begin..end]
2507 ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
2508   PcDesc* p = pc_desc_near(begin+1);
2509   if (p != NULL && p->real_pc(this) <= end) {
2510     return new ScopeDesc(this, p->scope_decode_offset(),
2511                          p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(),
2512                          p->return_oop(), p->return_vt());
2513   }
2514   return NULL;
2515 }
2516 
2517 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const {
2518   address low = entry_point();
2519   if (block_begin == low) {
2520     // Print method arguments before the method entry
2521     methodHandle m = method();
2522     if (m.not_null()) {
2523       stream->print("  # ");
2524       m->print_value_on(stream);
2525       stream->cr();
2526     }
2527     if (m.not_null() && !is_osr_method()) {
2528       ResourceMark rm;
2529       int sizeargs = 0;
2530       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
2531       VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, 256);
2532       Symbol* sig = m->signature();
2533       bool has_value_arg = false;
2534       if (ValueTypePassFieldsAsArgs && m->adapter()->get_sig_extended() != NULL) {
2535         // Use extended signature if value type arguments are passed as fields
2536         sig = m->adapter()->get_sig_extended();
2537         has_value_arg = true;
2538       } else if (!m->is_static()) {
2539         sig_bt[sizeargs++] = T_OBJECT; // 'this'
2540       }
2541       for (SignatureStream ss(sig); !ss.at_return_type(); ss.next()) {
2542         BasicType t = ss.type();
2543         if (!ValueTypePassFieldsAsArgs && t == T_VALUETYPE) {
2544           t = T_VALUETYPEPTR; // Pass value types by reference
2545         }
2546         sig_bt[sizeargs++] = t;
2547         if (type2size[t] == 2) {
2548           sig_bt[sizeargs++] = T_VOID;
2549         } else {
2550           assert(type2size[t] == 1, "size is 1 or 2");
2551         }
2552       }
2553       const char* spname = "sp"; // make arch-specific?
2554       intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false);
2555       int stack_slot_offset = this->frame_size() * wordSize;
2556       int tab1 = 14, tab2 = 24;
2557       int sig_index = 0;
2558       int arg_index = ((m->is_static() || has_value_arg) ? 0 : -1);
2559       bool did_old_sp = false;

2560       for (SignatureStream ss(sig); !ss.at_return_type(); ) {
2561         bool at_this = (arg_index == -1);
2562         bool at_old_sp = false;
2563         BasicType t = (at_this ? T_OBJECT : ss.type());
2564         if (!ValueTypePassFieldsAsArgs && t == T_VALUETYPE) {
2565           t = T_VALUETYPEPTR; // Pass value types by reference
2566         }
2567         assert(t == sig_bt[sig_index], "sigs in sync");
2568         if (at_this) {
2569           stream->print("  # this: ");
2570         } else {
2571           stream->print("  # parm%d: ", arg_index);
2572         }
2573         stream->move_to(tab1);
2574         VMReg fst = regs[sig_index].first();
2575         VMReg snd = regs[sig_index].second();
2576         if (fst->is_reg()) {
2577           stream->print("%s", fst->name());
2578           if (snd->is_valid())  {
2579             stream->print(":%s", snd->name());
2580           }
2581         } else if (fst->is_stack()) {
2582           int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
2583           if (offset == stack_slot_offset)  at_old_sp = true;
2584           stream->print("[%s+0x%x]", spname, offset);
2585         } else {
2586           stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
2587         }
2588         stream->print(" ");
2589         stream->move_to(tab2);
2590         stream->print("= ");
2591         if (at_this) {
2592           m->method_holder()->print_value_on(stream);
2593         } else {
2594           bool did_name = false;
2595           if (!at_this && ss.is_object()) {
2596             Symbol* name = ss.as_symbol_or_null();
2597             if (name != NULL) {
2598               name->print_value_on(stream);
2599               did_name = true;
2600             }
2601           }
2602           if (!did_name)
2603             stream->print("%s", type2name(t));
2604         }



2605         if (at_old_sp) {
2606           stream->print("  (%s of caller)", spname);
2607           did_old_sp = true;
2608         }
2609         stream->cr();
2610         sig_index += type2size[t];
2611         arg_index += 1;
2612         if (!at_this)  ss.next();
2613       }
2614       if (!did_old_sp) {
2615         stream->print("  # ");
2616         stream->move_to(tab1);
2617         stream->print("[%s+0x%x]", spname, stack_slot_offset);
2618         stream->print("  (%s of caller)", spname);
2619         stream->cr();
2620       }
2621     }
2622   }
2623 
2624   if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
2625   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");

2626   if (JVMCI_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
2627   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
2628   if (JVMCI_ONLY(_deopt_handler_begin != NULL &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
2629 
2630   if (has_method_handle_invokes())
2631     if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
2632 
2633   if (block_begin == consts_begin() && consts_begin() != low) stream->print_cr("[Constants]");
2634 }
2635 
2636 void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
2637   // First, find an oopmap in (begin, end].
2638   // We use the odd half-closed interval so that oop maps and scope descs
2639   // which are tied to the byte after a call are printed with the call itself.
2640   address base = code_begin();
2641   ImmutableOopMapSet* oms = oop_maps();
2642   if (oms != NULL) {
2643     for (int i = 0, imax = oms->count(); i < imax; i++) {
2644       const ImmutableOopMapPair* pair = oms->pair_at(i);
2645       const ImmutableOopMap* om = pair->get_from(oms);




 581     _entry_bci               = InvocationEntryBci;
 582     // We have no exception handler or deopt handler make the
 583     // values something that will never match a pc like the nmethod vtable entry
 584     _exception_offset        = 0;
 585     _orig_pc_offset          = 0;
 586 
 587     _consts_offset           = data_offset();
 588     _stub_offset             = data_offset();
 589     _oops_offset             = data_offset();
 590     _metadata_offset         = _oops_offset         + align_up(code_buffer->total_oop_size(), oopSize);
 591     scopes_data_offset       = _metadata_offset     + align_up(code_buffer->total_metadata_size(), wordSize);
 592     _scopes_pcs_offset       = scopes_data_offset;
 593     _dependencies_offset     = _scopes_pcs_offset;
 594     _handler_table_offset    = _dependencies_offset;
 595     _nul_chk_table_offset    = _handler_table_offset;
 596     _nmethod_end_offset      = _nul_chk_table_offset;
 597     _compile_id              = compile_id;
 598     _comp_level              = CompLevel_none;
 599     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
 600     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
 601     _verified_value_entry_point = _verified_entry_point;
 602     _osr_entry_point         = NULL;
 603     _exception_cache         = NULL;
 604     _pc_desc_container.reset_to(NULL);
 605     _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
 606 
 607     _scopes_data_begin = (address) this + scopes_data_offset;
 608     _deopt_handler_begin = (address) this + deoptimize_offset;
 609     _deopt_mh_handler_begin = (address) this + deoptimize_mh_offset;
 610 
 611     code_buffer->copy_code_and_locs_to(this);
 612     code_buffer->copy_values_to(this);
 613 
 614     clear_unloading_state();
 615     if (ScavengeRootsInCode) {
 616       Universe::heap()->register_nmethod(this);
 617     }
 618     debug_only(Universe::heap()->verify_nmethod(this));
 619     CodeCache::commit(this);
 620   }
 621 


 742     }
 743 #endif
 744     }
 745     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
 746       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
 747     } else {
 748       _unwind_handler_offset = -1;
 749     }
 750 
 751     _oops_offset             = data_offset();
 752     _metadata_offset         = _oops_offset          + align_up(code_buffer->total_oop_size(), oopSize);
 753     int scopes_data_offset   = _metadata_offset      + align_up(code_buffer->total_metadata_size(), wordSize);
 754 
 755     _scopes_pcs_offset       = scopes_data_offset    + align_up(debug_info->data_size       (), oopSize);
 756     _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
 757     _handler_table_offset    = _dependencies_offset  + align_up((int)dependencies->size_in_bytes (), oopSize);
 758     _nul_chk_table_offset    = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);
 759     _nmethod_end_offset      = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
 760     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
 761     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
 762     _verified_value_entry_point = code_begin()       + offsets->value(CodeOffsets::Verified_Value_Entry);
 763     _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
 764     _exception_cache         = NULL;
 765 
 766     _scopes_data_begin = (address) this + scopes_data_offset;
 767 
 768     _pc_desc_container.reset_to(scopes_pcs_begin());
 769 
 770     code_buffer->copy_code_and_locs_to(this);
 771     // Copy contents of ScopeDescRecorder to nmethod
 772     code_buffer->copy_values_to(this);
 773     debug_info->copy_to(this);
 774     dependencies->copy_to(this);
 775     clear_unloading_state();
 776     if (ScavengeRootsInCode) {
 777       Universe::heap()->register_nmethod(this);
 778     }
 779     debug_only(Universe::heap()->verify_nmethod(this));
 780 
 781     CodeCache::commit(this);
 782 


2500 
2501         default:
2502           break;
2503     }
2504   }
2505   return have_one ? "other" : NULL;
2506 }
2507 
2508 // Return a the last scope in (begin..end]
2509 ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
2510   PcDesc* p = pc_desc_near(begin+1);
2511   if (p != NULL && p->real_pc(this) <= end) {
2512     return new ScopeDesc(this, p->scope_decode_offset(),
2513                          p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(),
2514                          p->return_oop(), p->return_vt());
2515   }
2516   return NULL;
2517 }
2518 
2519 void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const {
2520   address low = verified_value_entry_point() != NULL ? verified_value_entry_point() : entry_point();
2521   if (block_begin == low) {
2522     // Print method arguments before the method entry
2523     methodHandle m = method();
2524     if (m.not_null()) {
2525       stream->print("  # ");
2526       m->print_value_on(stream);
2527       stream->cr();
2528     }
2529     if (m.not_null() && !is_osr_method()) {
2530       ResourceMark rm;
2531       int sizeargs = 0;
2532       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
2533       VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, 256);
2534       Symbol* sig = m->signature();
2535       bool has_value_arg = false;
2536       if (m->has_scalarized_args()) {
2537         // Use extended signature if value type arguments are passed as fields
2538         sig = SigEntry::create_symbol(m->adapter()->get_sig_cc());
2539         has_value_arg = true;
2540       } else if (!m->is_static()) {
2541         sig_bt[sizeargs++] = T_OBJECT; // 'this'
2542       }
2543       for (SignatureStream ss(sig); !ss.at_return_type(); ss.next()) {
2544         BasicType t = ss.type();



2545         sig_bt[sizeargs++] = t;
2546         if (type2size[t] == 2) {
2547           sig_bt[sizeargs++] = T_VOID;
2548         } else {
2549           assert(type2size[t] == 1, "size is 1 or 2");
2550         }
2551       }
2552       const char* spname = "sp"; // make arch-specific?
2553       intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false);
2554       int stack_slot_offset = this->frame_size() * wordSize;
2555       int tab1 = 14, tab2 = 24;
2556       int sig_index = 0;
2557       int arg_index = ((m->is_static() || has_value_arg) ? 0 : -1);
2558       bool did_old_sp = false;
2559       SigEntry res_entry = m->get_res_entry();
2560       for (SignatureStream ss(sig); !ss.at_return_type(); ) {
2561         bool at_this = (arg_index == -1);
2562         bool at_old_sp = false;
2563         BasicType t = (at_this ? T_OBJECT : ss.type());



2564         assert(t == sig_bt[sig_index], "sigs in sync");
2565         if (at_this) {
2566           stream->print("  # this: ");
2567         } else {
2568           stream->print("  # parm%d: ", arg_index);
2569         }
2570         stream->move_to(tab1);
2571         VMReg fst = regs[sig_index].first();
2572         VMReg snd = regs[sig_index].second();
2573         if (fst->is_reg()) {
2574           stream->print("%s", fst->name());
2575           if (snd->is_valid())  {
2576             stream->print(":%s", snd->name());
2577           }
2578         } else if (fst->is_stack()) {
2579           int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset;
2580           if (offset == stack_slot_offset)  at_old_sp = true;
2581           stream->print("[%s+0x%x]", spname, offset);
2582         } else {
2583           stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd);
2584         }
2585         stream->print(" ");
2586         stream->move_to(tab2);
2587         stream->print("= ");
2588         if (at_this) {
2589           m->method_holder()->print_value_on(stream);
2590         } else {
2591           bool did_name = false;
2592           if (!at_this && ss.is_object()) {
2593             Symbol* name = ss.as_symbol_or_null();
2594             if (name != NULL) {
2595               name->print_value_on(stream);
2596               did_name = true;
2597             }
2598           }
2599           if (!did_name)
2600             stream->print("%s", type2name(t));
2601         }
2602         if (sig_index == res_entry._offset) {
2603           stream->print(" [RESERVED] ");
2604         }
2605         if (at_old_sp) {
2606           stream->print("  (%s of caller)", spname);
2607           did_old_sp = true;
2608         }
2609         stream->cr();
2610         sig_index += type2size[t];
2611         arg_index += 1;
2612         if (!at_this)  ss.next();
2613       }
2614       if (!did_old_sp) {
2615         stream->print("  # ");
2616         stream->move_to(tab1);
2617         stream->print("[%s+0x%x]", spname, stack_slot_offset);
2618         stream->print("  (%s of caller)", spname);
2619         stream->cr();
2620       }
2621     }
2622   }
2623 
2624   if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
2625   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
2626   if (block_begin == verified_value_entry_point()) stream->print_cr("[Verified Value Entry Point]");
2627   if (JVMCI_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
2628   if (block_begin == stub_begin())              stream->print_cr("[Stub Code]");
2629   if (JVMCI_ONLY(_deopt_handler_begin != NULL &&) block_begin == deopt_handler_begin())     stream->print_cr("[Deopt Handler Code]");
2630 
2631   if (has_method_handle_invokes())
2632     if (block_begin == deopt_mh_handler_begin())  stream->print_cr("[Deopt MH Handler Code]");
2633 
2634   if (block_begin == consts_begin() && consts_begin() != low) stream->print_cr("[Constants]");
2635 }
2636 
2637 void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
2638   // First, find an oopmap in (begin, end].
2639   // We use the odd half-closed interval so that oop maps and scope descs
2640   // which are tied to the byte after a call are printed with the call itself.
2641   address base = code_begin();
2642   ImmutableOopMapSet* oms = oop_maps();
2643   if (oms != NULL) {
2644     for (int i = 0, imax = oms->count(); i < imax; i++) {
2645       const ImmutableOopMapPair* pair = oms->pair_at(i);
2646       const ImmutableOopMap* om = pair->get_from(oms);


< prev index next >