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);
|