609 //
610 // Input:
611 // from - register containing src address (only needed for spilling)
612 // to - register containing starting address
613 // count - register containing element count
614 // tmp - scratch register
615 //
616 // Kills:
617 // nothing
618 //
619 void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1,
620 Register preserve1 = noreg, Register preserve2 = noreg) {
621 BarrierSet* const bs = Universe::heap()->barrier_set();
622 switch (bs->kind()) {
623 case BarrierSet::G1SATBCTLogging:
624 // With G1, don't generate the call if we statically know that the target in uninitialized
625 if (!dest_uninitialized) {
626 int spill_slots = 3;
627 if (preserve1 != noreg) { spill_slots++; }
628 if (preserve2 != noreg) { spill_slots++; }
629 const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
630 Label filtered;
631
632 // Is marking active?
633 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
634 __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
635 } else {
636 guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
637 __ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
638 }
639 __ cmpdi(CCR0, Rtmp1, 0);
640 __ beq(CCR0, filtered);
641
642 __ save_LR_CR(R0);
643 __ push_frame(frame_size, R0);
644 int slot_nr = 0;
645 __ std(from, frame_size - (++slot_nr) * wordSize, R1_SP);
646 __ std(to, frame_size - (++slot_nr) * wordSize, R1_SP);
647 __ std(count, frame_size - (++slot_nr) * wordSize, R1_SP);
648 if (preserve1 != noreg) { __ std(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
649 if (preserve2 != noreg) { __ std(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
670 ShouldNotReachHere();
671 }
672 }
673
674 // Generate CMS/G1 post-write barrier for array.
675 //
676 // Input:
677 // addr - register containing starting address
678 // count - register containing element count
679 // tmp - scratch register
680 //
681 // The input registers and R0 are overwritten.
682 //
683 void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp, Register preserve = noreg) {
684 BarrierSet* const bs = Universe::heap()->barrier_set();
685
686 switch (bs->kind()) {
687 case BarrierSet::G1SATBCTLogging:
688 {
689 int spill_slots = (preserve != noreg) ? 1 : 0;
690 const int frame_size = align_size_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
691
692 __ save_LR_CR(R0);
693 __ push_frame(frame_size, R0);
694 if (preserve != noreg) { __ std(preserve, frame_size - 1 * wordSize, R1_SP); }
695 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
696 if (preserve != noreg) { __ ld(preserve, frame_size - 1 * wordSize, R1_SP); }
697 __ addi(R1_SP, R1_SP, frame_size); // pop_frame();
698 __ restore_LR_CR(R0);
699 }
700 break;
701 case BarrierSet::CardTableForRS:
702 case BarrierSet::CardTableExtension:
703 {
704 Label Lskip_loop, Lstore_loop;
705 if (UseConcMarkSweepGC) {
706 // TODO PPC port: contribute optimization / requires shared changes
707 __ release();
708 }
709
710 CardTableModRefBS* const ct = barrier_set_cast<CardTableModRefBS>(bs);
|
609 //
610 // Input:
611 // from - register containing src address (only needed for spilling)
612 // to - register containing starting address
613 // count - register containing element count
614 // tmp - scratch register
615 //
616 // Kills:
617 // nothing
618 //
619 void gen_write_ref_array_pre_barrier(Register from, Register to, Register count, bool dest_uninitialized, Register Rtmp1,
620 Register preserve1 = noreg, Register preserve2 = noreg) {
621 BarrierSet* const bs = Universe::heap()->barrier_set();
622 switch (bs->kind()) {
623 case BarrierSet::G1SATBCTLogging:
624 // With G1, don't generate the call if we statically know that the target in uninitialized
625 if (!dest_uninitialized) {
626 int spill_slots = 3;
627 if (preserve1 != noreg) { spill_slots++; }
628 if (preserve2 != noreg) { spill_slots++; }
629 const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
630 Label filtered;
631
632 // Is marking active?
633 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
634 __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
635 } else {
636 guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
637 __ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
638 }
639 __ cmpdi(CCR0, Rtmp1, 0);
640 __ beq(CCR0, filtered);
641
642 __ save_LR_CR(R0);
643 __ push_frame(frame_size, R0);
644 int slot_nr = 0;
645 __ std(from, frame_size - (++slot_nr) * wordSize, R1_SP);
646 __ std(to, frame_size - (++slot_nr) * wordSize, R1_SP);
647 __ std(count, frame_size - (++slot_nr) * wordSize, R1_SP);
648 if (preserve1 != noreg) { __ std(preserve1, frame_size - (++slot_nr) * wordSize, R1_SP); }
649 if (preserve2 != noreg) { __ std(preserve2, frame_size - (++slot_nr) * wordSize, R1_SP); }
670 ShouldNotReachHere();
671 }
672 }
673
674 // Generate CMS/G1 post-write barrier for array.
675 //
676 // Input:
677 // addr - register containing starting address
678 // count - register containing element count
679 // tmp - scratch register
680 //
681 // The input registers and R0 are overwritten.
682 //
683 void gen_write_ref_array_post_barrier(Register addr, Register count, Register tmp, Register preserve = noreg) {
684 BarrierSet* const bs = Universe::heap()->barrier_set();
685
686 switch (bs->kind()) {
687 case BarrierSet::G1SATBCTLogging:
688 {
689 int spill_slots = (preserve != noreg) ? 1 : 0;
690 const int frame_size = align_up(frame::abi_reg_args_size + spill_slots * BytesPerWord, frame::alignment_in_bytes);
691
692 __ save_LR_CR(R0);
693 __ push_frame(frame_size, R0);
694 if (preserve != noreg) { __ std(preserve, frame_size - 1 * wordSize, R1_SP); }
695 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
696 if (preserve != noreg) { __ ld(preserve, frame_size - 1 * wordSize, R1_SP); }
697 __ addi(R1_SP, R1_SP, frame_size); // pop_frame();
698 __ restore_LR_CR(R0);
699 }
700 break;
701 case BarrierSet::CardTableForRS:
702 case BarrierSet::CardTableExtension:
703 {
704 Label Lskip_loop, Lstore_loop;
705 if (UseConcMarkSweepGC) {
706 // TODO PPC port: contribute optimization / requires shared changes
707 __ release();
708 }
709
710 CardTableModRefBS* const ct = barrier_set_cast<CardTableModRefBS>(bs);
|