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