706 // __ ret(); |
701 // __ ret(); |
707 // __ delayed()->restore(); |
702 // __ delayed()->restore(); |
708 } |
703 } |
709 break; |
704 break; |
710 |
705 |
711 #if INCLUDE_ALL_GCS |
|
712 case g1_pre_barrier_slow_id: |
|
713 { |
|
714 BarrierSet* bs = BarrierSet::barrier_set(); |
|
715 if (bs->kind() != BarrierSet::G1BarrierSet) { |
|
716 goto unimplemented_entry; |
|
717 } |
|
718 |
|
719 __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments); |
|
720 |
|
721 // Using stack slots: pre_val (pre-pushed), spill tmp, spill tmp2. |
|
722 const int stack_slots = 3; |
|
723 Register pre_val = R0; // previous value of memory |
|
724 Register tmp = R14; |
|
725 Register tmp2 = R15; |
|
726 |
|
727 Label refill, restart, marking_not_active; |
|
728 int satb_q_active_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()); |
|
729 int satb_q_index_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()); |
|
730 int satb_q_buf_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()); |
|
731 |
|
732 // Spill |
|
733 __ std(tmp, -16, R1_SP); |
|
734 __ std(tmp2, -24, R1_SP); |
|
735 |
|
736 // Is marking still active? |
|
737 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { |
|
738 __ lwz(tmp, satb_q_active_byte_offset, R16_thread); |
|
739 } else { |
|
740 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); |
|
741 __ lbz(tmp, satb_q_active_byte_offset, R16_thread); |
|
742 } |
|
743 __ cmpdi(CCR0, tmp, 0); |
|
744 __ beq(CCR0, marking_not_active); |
|
745 |
|
746 __ bind(restart); |
|
747 // Load the index into the SATB buffer. SATBMarkQueue::_index is a |
|
748 // size_t so ld_ptr is appropriate. |
|
749 __ ld(tmp, satb_q_index_byte_offset, R16_thread); |
|
750 |
|
751 // index == 0? |
|
752 __ cmpdi(CCR0, tmp, 0); |
|
753 __ beq(CCR0, refill); |
|
754 |
|
755 __ ld(tmp2, satb_q_buf_byte_offset, R16_thread); |
|
756 __ ld(pre_val, -8, R1_SP); // Load from stack. |
|
757 __ addi(tmp, tmp, -oopSize); |
|
758 |
|
759 __ std(tmp, satb_q_index_byte_offset, R16_thread); |
|
760 __ stdx(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card> |
|
761 |
|
762 __ bind(marking_not_active); |
|
763 // Restore temp registers and return-from-leaf. |
|
764 __ ld(tmp2, -24, R1_SP); |
|
765 __ ld(tmp, -16, R1_SP); |
|
766 __ blr(); |
|
767 |
|
768 __ bind(refill); |
|
769 const int nbytes_save = (MacroAssembler::num_volatile_regs + stack_slots) * BytesPerWord; |
|
770 __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0 |
|
771 __ mflr(R0); |
|
772 __ std(R0, _abi(lr), R1_SP); |
|
773 __ push_frame_reg_args(nbytes_save, R0); // dummy frame for C call |
|
774 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SATBMarkQueueSet::handle_zero_index_for_thread), R16_thread); |
|
775 __ pop_frame(); |
|
776 __ ld(R0, _abi(lr), R1_SP); |
|
777 __ mtlr(R0); |
|
778 __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 |
|
779 __ b(restart); |
|
780 } |
|
781 break; |
|
782 |
|
783 case g1_post_barrier_slow_id: |
|
784 { |
|
785 BarrierSet* bs = BarrierSet::barrier_set(); |
|
786 if (bs->kind() != BarrierSet::G1BarrierSet) { |
|
787 goto unimplemented_entry; |
|
788 } |
|
789 |
|
790 __ set_info("g1_post_barrier_slow_id", dont_gc_arguments); |
|
791 |
|
792 // Using stack slots: spill addr, spill tmp2 |
|
793 const int stack_slots = 2; |
|
794 Register tmp = R0; |
|
795 Register addr = R14; |
|
796 Register tmp2 = R15; |
|
797 jbyte* byte_map_base = ci_card_table_address(); |
|
798 |
|
799 Label restart, refill, ret; |
|
800 |
|
801 // Spill |
|
802 __ std(addr, -8, R1_SP); |
|
803 __ std(tmp2, -16, R1_SP); |
|
804 |
|
805 __ srdi(addr, R0, CardTable::card_shift); // Addr is passed in R0. |
|
806 __ load_const_optimized(/*cardtable*/ tmp2, byte_map_base, tmp); |
|
807 __ add(addr, tmp2, addr); |
|
808 __ lbz(tmp, 0, addr); // tmp := [addr + cardtable] |
|
809 |
|
810 // Return if young card. |
|
811 __ cmpwi(CCR0, tmp, G1CardTable::g1_young_card_val()); |
|
812 __ beq(CCR0, ret); |
|
813 |
|
814 // Return if sequential consistent value is already dirty. |
|
815 __ membar(Assembler::StoreLoad); |
|
816 __ lbz(tmp, 0, addr); // tmp := [addr + cardtable] |
|
817 |
|
818 __ cmpwi(CCR0, tmp, G1CardTable::dirty_card_val()); |
|
819 __ beq(CCR0, ret); |
|
820 |
|
821 // Not dirty. |
|
822 |
|
823 // First, dirty it. |
|
824 __ li(tmp, G1CardTable::dirty_card_val()); |
|
825 __ stb(tmp, 0, addr); |
|
826 |
|
827 int dirty_card_q_index_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()); |
|
828 int dirty_card_q_buf_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()); |
|
829 |
|
830 __ bind(restart); |
|
831 |
|
832 // Get the index into the update buffer. DirtyCardQueue::_index is |
|
833 // a size_t so ld_ptr is appropriate here. |
|
834 __ ld(tmp2, dirty_card_q_index_byte_offset, R16_thread); |
|
835 |
|
836 // index == 0? |
|
837 __ cmpdi(CCR0, tmp2, 0); |
|
838 __ beq(CCR0, refill); |
|
839 |
|
840 __ ld(tmp, dirty_card_q_buf_byte_offset, R16_thread); |
|
841 __ addi(tmp2, tmp2, -oopSize); |
|
842 |
|
843 __ std(tmp2, dirty_card_q_index_byte_offset, R16_thread); |
|
844 __ add(tmp2, tmp, tmp2); |
|
845 __ std(addr, 0, tmp2); // [_buf + index] := <address_of_card> |
|
846 |
|
847 // Restore temp registers and return-from-leaf. |
|
848 __ bind(ret); |
|
849 __ ld(tmp2, -16, R1_SP); |
|
850 __ ld(addr, -8, R1_SP); |
|
851 __ blr(); |
|
852 |
|
853 __ bind(refill); |
|
854 const int nbytes_save = (MacroAssembler::num_volatile_regs + stack_slots) * BytesPerWord; |
|
855 __ save_volatile_gprs(R1_SP, -nbytes_save); // except R0 |
|
856 __ mflr(R0); |
|
857 __ std(R0, _abi(lr), R1_SP); |
|
858 __ push_frame_reg_args(nbytes_save, R0); // dummy frame for C call |
|
859 __ call_VM_leaf(CAST_FROM_FN_PTR(address, DirtyCardQueueSet::handle_zero_index_for_thread), R16_thread); |
|
860 __ pop_frame(); |
|
861 __ ld(R0, _abi(lr), R1_SP); |
|
862 __ mtlr(R0); |
|
863 __ restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 |
|
864 __ b(restart); |
|
865 } |
|
866 break; |
|
867 #endif // INCLUDE_ALL_GCS |
|
868 |
|
869 case predicate_failed_trap_id: |
706 case predicate_failed_trap_id: |
870 { |
707 { |
871 __ set_info("predicate_failed_trap", dont_gc_arguments); |
708 __ set_info("predicate_failed_trap", dont_gc_arguments); |
872 OopMap* oop_map = save_live_registers(sasm); |
709 OopMap* oop_map = save_live_registers(sasm); |
873 |
710 |