889 }
890 }
891
892 ShenandoahBarrierStubC2* ShenandoahBarrierStubC2::create(const MachNode* node, Register obj, Address addr, Register tmp1, Register tmp2, bool narrow, bool do_load) {
893 auto* stub = new (Compile::current()->comp_arena()) ShenandoahBarrierStubC2(node, obj, addr, tmp1, tmp2, narrow, do_load);
894 register_stub(stub);
895 return stub;
896 }
897
898 void ShenandoahBarrierStubC2::load_post(MacroAssembler* masm, const MachNode* node, Register obj, Address addr, Register tmp1, Register tmp2, bool narrow) {
899 // Load post-barrier:
900 // a. Satisfies the need for LRB for normal loads
901 // b. Passes a weak load through LRB-weak
902 // c. Keep-alives a weak load
903 if (needs_slow_barrier(node)) {
904 ShenandoahBarrierStubC2* const stub = create(node, obj, addr, tmp1, tmp2, narrow, /* do_load = */ false);
905 char check = 0;
906 check |= needs_keep_alive_barrier(node) ? ShenandoahHeap::MARKING : 0;
907 check |= needs_load_ref_barrier(node) ? ShenandoahHeap::HAS_FORWARDED : 0;
908 check |= needs_load_ref_barrier_weak(node) ? ShenandoahHeap::WEAK_ROOTS : 0;
909 stub->enter_if_gc_state(*masm, check, tmp1);
910 }
911 }
912
913 void ShenandoahBarrierStubC2::store_pre(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2, Register tmp3, bool narrow) {
914 // Store pre-barrier: SATB, keep-alive the current memory value.
915 if (needs_slow_barrier(node)) {
916 assert(!needs_load_ref_barrier(node), "Should not be required for stores");
917 ShenandoahBarrierStubC2* const stub = create(node, tmp1, addr, tmp2, tmp3, narrow, /* do_load = */ true);
918 stub->enter_if_gc_state(*masm, ShenandoahHeap::MARKING, tmp1);
919 }
920 }
921
922 void ShenandoahBarrierStubC2::load_store_pre(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2, Register tmp3, bool narrow) {
923 // Load/Store pre-barrier:
924 // a. Avoids false positives from CAS encountering to-space memory values.
925 // b. Satisfies the need for LRB for the CAE result.
926 // c. Records old value for the sake of SATB.
927 //
928 // (a) and (b) are covered because load barrier does memory location fixup.
929 // (c) is covered by KA on the current memory value.
930 if (needs_slow_barrier(node)) {
931 ShenandoahBarrierStubC2* const stub = create(node, tmp1, addr, tmp2, tmp3, narrow, /* do_load = */ true);
932 char check = 0;
933 check |= needs_keep_alive_barrier(node) ? ShenandoahHeap::MARKING : 0;
934 check |= needs_load_ref_barrier(node) ? ShenandoahHeap::HAS_FORWARDED : 0;
935 assert(!needs_load_ref_barrier_weak(node), "Not supported for Load/Stores");
936 stub->enter_if_gc_state(*masm, check, tmp1);
937 }
938 }
939
940 void ShenandoahBarrierStubC2::store_post(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2) {
941 if (needs_card_barrier(node)) {
942 cardtable(*masm, addr, tmp1, tmp2);
943 }
944 }
945
946 void ShenandoahBarrierStubC2::load_store_post(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2) {
947 store_post(masm, node, addr, tmp1, tmp2);
948 }
949
950 bool ShenandoahBarrierStubC2::is_live_register(Register reg) {
951 return preserve_set().member(OptoReg::as_OptoReg(reg->as_VMReg()));
952 }
953
954 Register ShenandoahBarrierStubC2::select_temp_register(bool& selected_live, Register skip_reg1, Register skip_reg2) {
955 Register tmp = noreg;
956 Register fallback_live = noreg;
|
889 }
890 }
891
892 ShenandoahBarrierStubC2* ShenandoahBarrierStubC2::create(const MachNode* node, Register obj, Address addr, Register tmp1, Register tmp2, bool narrow, bool do_load) {
893 auto* stub = new (Compile::current()->comp_arena()) ShenandoahBarrierStubC2(node, obj, addr, tmp1, tmp2, narrow, do_load);
894 register_stub(stub);
895 return stub;
896 }
897
898 void ShenandoahBarrierStubC2::load_post(MacroAssembler* masm, const MachNode* node, Register obj, Address addr, Register tmp1, Register tmp2, bool narrow) {
899 // Load post-barrier:
900 // a. Satisfies the need for LRB for normal loads
901 // b. Passes a weak load through LRB-weak
902 // c. Keep-alives a weak load
903 if (needs_slow_barrier(node)) {
904 ShenandoahBarrierStubC2* const stub = create(node, obj, addr, tmp1, tmp2, narrow, /* do_load = */ false);
905 char check = 0;
906 check |= needs_keep_alive_barrier(node) ? ShenandoahHeap::MARKING : 0;
907 check |= needs_load_ref_barrier(node) ? ShenandoahHeap::HAS_FORWARDED : 0;
908 check |= needs_load_ref_barrier_weak(node) ? ShenandoahHeap::WEAK_ROOTS : 0;
909 stub->enter_if_gc_state(*masm, check);
910 }
911 }
912
913 void ShenandoahBarrierStubC2::store_pre(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2, Register tmp3, bool narrow) {
914 // Store pre-barrier: SATB, keep-alive the current memory value.
915 if (needs_slow_barrier(node)) {
916 assert(!needs_load_ref_barrier(node), "Should not be required for stores");
917 ShenandoahBarrierStubC2* const stub = create(node, tmp1, addr, tmp2, tmp3, narrow, /* do_load = */ true);
918 stub->enter_if_gc_state(*masm, ShenandoahHeap::MARKING);
919 }
920 }
921
922 void ShenandoahBarrierStubC2::load_store_pre(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2, Register tmp3, bool narrow) {
923 // Load/Store pre-barrier:
924 // a. Avoids false positives from CAS encountering to-space memory values.
925 // b. Satisfies the need for LRB for the CAE result.
926 // c. Records old value for the sake of SATB.
927 //
928 // (a) and (b) are covered because load barrier does memory location fixup.
929 // (c) is covered by KA on the current memory value.
930 if (needs_slow_barrier(node)) {
931 ShenandoahBarrierStubC2* const stub = create(node, tmp1, addr, tmp2, tmp3, narrow, /* do_load = */ true);
932 char check = 0;
933 check |= needs_keep_alive_barrier(node) ? ShenandoahHeap::MARKING : 0;
934 check |= needs_load_ref_barrier(node) ? ShenandoahHeap::HAS_FORWARDED : 0;
935 assert(!needs_load_ref_barrier_weak(node), "Not supported for Load/Stores");
936 stub->enter_if_gc_state(*masm, check);
937 }
938 }
939
940 void ShenandoahBarrierStubC2::store_post(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2) {
941 if (needs_card_barrier(node)) {
942 cardtable(*masm, addr, tmp1, tmp2);
943 }
944 }
945
946 void ShenandoahBarrierStubC2::load_store_post(MacroAssembler* masm, const MachNode* node, Address addr, Register tmp1, Register tmp2) {
947 store_post(masm, node, addr, tmp1, tmp2);
948 }
949
950 bool ShenandoahBarrierStubC2::is_live_register(Register reg) {
951 return preserve_set().member(OptoReg::as_OptoReg(reg->as_VMReg()));
952 }
953
954 Register ShenandoahBarrierStubC2::select_temp_register(bool& selected_live, Register skip_reg1, Register skip_reg2) {
955 Register tmp = noreg;
956 Register fallback_live = noreg;
|