< prev index next >

src/hotspot/cpu/sparc/macroAssembler_sparc.cpp

Print this page
rev 47398 : 8166317: InterpreterCodeSize should be computed
Reviewed-by: kvn, coleenp


3558   __ mov(O7, L4);
3559   __ call_VM_leaf(L5, handle_zero, G2_thread);
3560   __ mov(L0, G1_scratch);
3561   __ mov(L1, G3_scratch);
3562   __ mov(L2, G4);
3563   __ mov(L3, O0);
3564   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3565   __ delayed()->mov(L4, O7);
3566 
3567   if (with_frame) {
3568     satb_log_enqueue_with_frame = start;
3569     satb_log_enqueue_with_frame_end = __ pc();
3570   } else {
3571     satb_log_enqueue_frameless = start;
3572     satb_log_enqueue_frameless_end = __ pc();
3573   }
3574 
3575 #undef __
3576 }
3577 
3578 static inline void generate_satb_log_enqueue_if_necessary(bool with_frame) {
3579   if (with_frame) {
3580     if (satb_log_enqueue_with_frame == 0) {
3581       generate_satb_log_enqueue(with_frame);
3582       assert(satb_log_enqueue_with_frame != 0, "postcondition.");
3583     }
3584   } else {
3585     if (satb_log_enqueue_frameless == 0) {
3586       generate_satb_log_enqueue(with_frame);
3587       assert(satb_log_enqueue_frameless != 0, "postcondition.");
3588     }
3589   }
3590 }
3591 
3592 void MacroAssembler::g1_write_barrier_pre(Register obj,
3593                                           Register index,
3594                                           int offset,
3595                                           Register pre_val,
3596                                           Register tmp,
3597                                           bool preserve_o_regs) {
3598   Label filtered;
3599 
3600   if (obj == noreg) {
3601     // We are not loading the previous value so make
3602     // sure that we don't trash the value in pre_val
3603     // with the code below.
3604     assert_different_registers(pre_val, tmp);
3605   } else {
3606     // We will be loading the previous value
3607     // in this code so...
3608     assert(offset == 0 || index == noreg, "choose one");
3609     assert(pre_val == noreg, "check this code");
3610   }
3611 


3641       load_heap_oop(obj, index, tmp);
3642     }
3643     // Previous value has been loaded into tmp
3644     pre_val = tmp;
3645   }
3646 
3647   assert(pre_val != noreg, "must have a real register");
3648 
3649   // Is the previous value null?
3650   cmp_and_brx_short(pre_val, G0, Assembler::equal, Assembler::pt, filtered);
3651 
3652   // OK, it's not filtered, so we'll need to call enqueue.  In the normal
3653   // case, pre_val will be a scratch G-reg, but there are some cases in
3654   // which it's an O-reg.  In the first case, do a normal call.  In the
3655   // latter, do a save here and call the frameless version.
3656 
3657   guarantee(pre_val->is_global() || pre_val->is_out(),
3658             "Or we need to think harder.");
3659 
3660   if (pre_val->is_global() && !preserve_o_regs) {
3661     generate_satb_log_enqueue_if_necessary(true); // with frame
3662 
3663     call(satb_log_enqueue_with_frame);
3664     delayed()->mov(pre_val, O0);
3665   } else {
3666     generate_satb_log_enqueue_if_necessary(false); // frameless
3667 
3668     save_frame(0);
3669     call(satb_log_enqueue_frameless);
3670     delayed()->mov(pre_val->after_save(), O0);
3671     restore();
3672   }
3673 
3674   bind(filtered);
3675 }
3676 
3677 static address dirty_card_log_enqueue = 0;
3678 static u_char* dirty_card_log_enqueue_end = 0;
3679 
3680 // This gets to assume that o0 contains the object address.
3681 static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
3682   BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
3683   CodeBuffer buf(bb);
3684   MacroAssembler masm(&buf);
3685 #define __ masm.
3686   address start = __ pc();
3687 


3751   __ mov(O3, L6);
3752   // Since the call will overwrite O7, we save and restore that, as well.
3753   __ mov(O7, L4);
3754 
3755   __ call_VM_leaf(L7_thread_cache, handle_zero, G2_thread);
3756   __ mov(L3, G1_scratch);
3757   __ mov(L5, G3_scratch);
3758   __ mov(L6, O3);
3759   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3760   __ delayed()->mov(L4, O7);
3761 
3762   dirty_card_log_enqueue = start;
3763   dirty_card_log_enqueue_end = __ pc();
3764   // XXX Should have a guarantee here about not going off the end!
3765   // Does it already do so?  Do an experiment...
3766 
3767 #undef __
3768 
3769 }
3770 
3771 static inline void
3772 generate_dirty_card_log_enqueue_if_necessary(jbyte* byte_map_base) {
3773   if (dirty_card_log_enqueue == 0) {
3774     generate_dirty_card_log_enqueue(byte_map_base);
3775     assert(dirty_card_log_enqueue != 0, "postcondition.");
3776   }
3777 }
3778 
3779 
3780 void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3781 
3782   Label filtered;
3783   MacroAssembler* post_filter_masm = this;
3784 
3785   if (new_val == G0) return;
3786 
3787   G1SATBCardTableLoggingModRefBS* bs =
3788     barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
3789 
3790   if (G1RSBarrierRegionFilter) {
3791     xor3(store_addr, new_val, tmp);
3792     srlx(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
3793 
3794     // XXX Should I predict this taken or not?  Does it matter?
3795     cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
3796   }
3797 
3798   // If the "store_addr" register is an "in" or "local" register, move it to
3799   // a scratch reg so we can pass it as an argument.
3800   bool use_scr = !(store_addr->is_global() || store_addr->is_out());
3801   // Pick a scratch register different from "tmp".
3802   Register scr = (tmp == G1_scratch ? G3_scratch : G1_scratch);
3803   // Make sure we use up the delay slot!
3804   if (use_scr) {
3805     post_filter_masm->mov(store_addr, scr);
3806   } else {
3807     post_filter_masm->nop();
3808   }
3809   generate_dirty_card_log_enqueue_if_necessary(bs->byte_map_base);
3810   save_frame(0);
3811   call(dirty_card_log_enqueue);
3812   if (use_scr) {
3813     delayed()->mov(scr, O0);
3814   } else {
3815     delayed()->mov(store_addr->after_save(), O0);
3816   }
3817   restore();
3818 
3819   bind(filtered);






















3820 }
3821 
3822 #endif // INCLUDE_ALL_GCS
3823 ///////////////////////////////////////////////////////////////////////////////////
3824 
3825 void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3826   // If we're writing constant NULL, we can skip the write barrier.
3827   if (new_val == G0) return;
3828   CardTableModRefBS* bs =
3829     barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
3830   assert(bs->kind() == BarrierSet::CardTableForRS ||
3831          bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
3832   card_table_write(bs->byte_map_base, tmp, store_addr);
3833 }
3834 
3835 // ((OopHandle)result).resolve();
3836 void MacroAssembler::resolve_oop_handle(Register result) {
3837   // OopHandle::resolve is an indirection.
3838   ld_ptr(result, 0, result);
3839 }




3558   __ mov(O7, L4);
3559   __ call_VM_leaf(L5, handle_zero, G2_thread);
3560   __ mov(L0, G1_scratch);
3561   __ mov(L1, G3_scratch);
3562   __ mov(L2, G4);
3563   __ mov(L3, O0);
3564   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3565   __ delayed()->mov(L4, O7);
3566 
3567   if (with_frame) {
3568     satb_log_enqueue_with_frame = start;
3569     satb_log_enqueue_with_frame_end = __ pc();
3570   } else {
3571     satb_log_enqueue_frameless = start;
3572     satb_log_enqueue_frameless_end = __ pc();
3573   }
3574 
3575 #undef __
3576 }
3577 














3578 void MacroAssembler::g1_write_barrier_pre(Register obj,
3579                                           Register index,
3580                                           int offset,
3581                                           Register pre_val,
3582                                           Register tmp,
3583                                           bool preserve_o_regs) {
3584   Label filtered;
3585 
3586   if (obj == noreg) {
3587     // We are not loading the previous value so make
3588     // sure that we don't trash the value in pre_val
3589     // with the code below.
3590     assert_different_registers(pre_val, tmp);
3591   } else {
3592     // We will be loading the previous value
3593     // in this code so...
3594     assert(offset == 0 || index == noreg, "choose one");
3595     assert(pre_val == noreg, "check this code");
3596   }
3597 


3627       load_heap_oop(obj, index, tmp);
3628     }
3629     // Previous value has been loaded into tmp
3630     pre_val = tmp;
3631   }
3632 
3633   assert(pre_val != noreg, "must have a real register");
3634 
3635   // Is the previous value null?
3636   cmp_and_brx_short(pre_val, G0, Assembler::equal, Assembler::pt, filtered);
3637 
3638   // OK, it's not filtered, so we'll need to call enqueue.  In the normal
3639   // case, pre_val will be a scratch G-reg, but there are some cases in
3640   // which it's an O-reg.  In the first case, do a normal call.  In the
3641   // latter, do a save here and call the frameless version.
3642 
3643   guarantee(pre_val->is_global() || pre_val->is_out(),
3644             "Or we need to think harder.");
3645 
3646   if (pre_val->is_global() && !preserve_o_regs) {


3647     call(satb_log_enqueue_with_frame);
3648     delayed()->mov(pre_val, O0);
3649   } else {


3650     save_frame(0);
3651     call(satb_log_enqueue_frameless);
3652     delayed()->mov(pre_val->after_save(), O0);
3653     restore();
3654   }
3655 
3656   bind(filtered);
3657 }
3658 
3659 static address dirty_card_log_enqueue = 0;
3660 static u_char* dirty_card_log_enqueue_end = 0;
3661 
3662 // This gets to assume that o0 contains the object address.
3663 static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
3664   BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
3665   CodeBuffer buf(bb);
3666   MacroAssembler masm(&buf);
3667 #define __ masm.
3668   address start = __ pc();
3669 


3733   __ mov(O3, L6);
3734   // Since the call will overwrite O7, we save and restore that, as well.
3735   __ mov(O7, L4);
3736 
3737   __ call_VM_leaf(L7_thread_cache, handle_zero, G2_thread);
3738   __ mov(L3, G1_scratch);
3739   __ mov(L5, G3_scratch);
3740   __ mov(L6, O3);
3741   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3742   __ delayed()->mov(L4, O7);
3743 
3744   dirty_card_log_enqueue = start;
3745   dirty_card_log_enqueue_end = __ pc();
3746   // XXX Should have a guarantee here about not going off the end!
3747   // Does it already do so?  Do an experiment...
3748 
3749 #undef __
3750 
3751 }
3752 









3753 void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3754 
3755   Label filtered;
3756   MacroAssembler* post_filter_masm = this;
3757 
3758   if (new_val == G0) return;
3759 
3760   G1SATBCardTableLoggingModRefBS* bs =
3761     barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
3762 
3763   if (G1RSBarrierRegionFilter) {
3764     xor3(store_addr, new_val, tmp);
3765     srlx(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
3766 
3767     // XXX Should I predict this taken or not?  Does it matter?
3768     cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
3769   }
3770 
3771   // If the "store_addr" register is an "in" or "local" register, move it to
3772   // a scratch reg so we can pass it as an argument.
3773   bool use_scr = !(store_addr->is_global() || store_addr->is_out());
3774   // Pick a scratch register different from "tmp".
3775   Register scr = (tmp == G1_scratch ? G3_scratch : G1_scratch);
3776   // Make sure we use up the delay slot!
3777   if (use_scr) {
3778     post_filter_masm->mov(store_addr, scr);
3779   } else {
3780     post_filter_masm->nop();
3781   }

3782   save_frame(0);
3783   call(dirty_card_log_enqueue);
3784   if (use_scr) {
3785     delayed()->mov(scr, O0);
3786   } else {
3787     delayed()->mov(store_addr->after_save(), O0);
3788   }
3789   restore();
3790 
3791   bind(filtered);
3792 }
3793 
3794 // Called from init_globals() after universe_init() and before interpreter_init()
3795 void g1_barrier_stubs_init() {
3796   CollectedHeap* heap = Universe::heap();
3797   if (heap->kind() == CollectedHeap::G1CollectedHeap) {
3798     // Only needed for G1
3799     if (dirty_card_log_enqueue == 0) {
3800       G1SATBCardTableLoggingModRefBS* bs =
3801         barrier_set_cast<G1SATBCardTableLoggingModRefBS>(heap->barrier_set());
3802       generate_dirty_card_log_enqueue(bs->byte_map_base);
3803       assert(dirty_card_log_enqueue != 0, "postcondition.");
3804     }
3805     if (satb_log_enqueue_with_frame == 0) {
3806       generate_satb_log_enqueue(true);
3807       assert(satb_log_enqueue_with_frame != 0, "postcondition.");
3808     }
3809     if (satb_log_enqueue_frameless == 0) {
3810       generate_satb_log_enqueue(false);
3811       assert(satb_log_enqueue_frameless != 0, "postcondition.");
3812     }
3813   }
3814 }
3815 
3816 #endif // INCLUDE_ALL_GCS
3817 ///////////////////////////////////////////////////////////////////////////////////
3818 
3819 void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3820   // If we're writing constant NULL, we can skip the write barrier.
3821   if (new_val == G0) return;
3822   CardTableModRefBS* bs =
3823     barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
3824   assert(bs->kind() == BarrierSet::CardTableForRS ||
3825          bs->kind() == BarrierSet::CardTableExtension, "wrong barrier");
3826   card_table_write(bs->byte_map_base, tmp, store_addr);
3827 }
3828 
3829 // ((OopHandle)result).resolve();
3830 void MacroAssembler::resolve_oop_handle(Register result) {
3831   // OopHandle::resolve is an indirection.
3832   ld_ptr(result, 0, result);
3833 }


< prev index next >