44 if (!G1PreBarrierStubC2::needs_barrier(node)) {
45 return;
46 }
47 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
48 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
49 G1PreBarrierStubC2* const stub = G1PreBarrierStubC2::create(node);
50 for (RegSetIterator<Register> reg = preserve.begin(); *reg != noreg; ++reg) {
51 stub->preserve(*reg);
52 }
53 for (RegSetIterator<Register> reg = no_preserve.begin(); *reg != noreg; ++reg) {
54 stub->dont_preserve(*reg);
55 }
56 g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, rthread, tmp1, tmp2, stub);
57 }
58
59 static void write_barrier_post(MacroAssembler* masm,
60 const MachNode* node,
61 Register store_addr,
62 Register new_val,
63 Register tmp1,
64 Register tmp2) {
65 if (!G1PostBarrierStubC2::needs_barrier(node)) {
66 return;
67 }
68 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
69 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
70 G1PostBarrierStubC2* const stub = G1PostBarrierStubC2::create(node);
71 g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, stub);
72 }
73
74 %}
75
76 // BEGIN This section of the file is automatically generated. Do not edit --------------
77
78 // This section is generated from g1_aarch64.m4
79
80
81 // This pattern is generated automatically from g1_aarch64.m4.
82 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
83 instruct g1StoreP(indirect mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
84 %{
85 predicate(UseG1GC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
86 match(Set mem (StoreP mem src));
87 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
88 ins_cost(INSN_COST);
89 format %{ "str $src, $mem\t# ptr" %}
90 ins_encode %{
91 write_barrier_pre(masm, this,
92 $mem$$Register /* obj */,
93 $tmp1$$Register /* pre_val */,
94 $tmp2$$Register /* tmp1 */,
95 $tmp3$$Register /* tmp2 */,
|
44 if (!G1PreBarrierStubC2::needs_barrier(node)) {
45 return;
46 }
47 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
48 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
49 G1PreBarrierStubC2* const stub = G1PreBarrierStubC2::create(node);
50 for (RegSetIterator<Register> reg = preserve.begin(); *reg != noreg; ++reg) {
51 stub->preserve(*reg);
52 }
53 for (RegSetIterator<Register> reg = no_preserve.begin(); *reg != noreg; ++reg) {
54 stub->dont_preserve(*reg);
55 }
56 g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, rthread, tmp1, tmp2, stub);
57 }
58
59 static void write_barrier_post(MacroAssembler* masm,
60 const MachNode* node,
61 Register store_addr,
62 Register new_val,
63 Register tmp1,
64 Register tmp2,
65 RegSet preserve = RegSet()) {
66 if (!G1PostBarrierStubC2::needs_barrier(node)) {
67 return;
68 }
69 Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
70 G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
71 G1PostBarrierStubC2* const stub = G1PostBarrierStubC2::create(node);
72 for (RegSetIterator<Register> reg = preserve.begin(); *reg != noreg; ++reg) {
73 stub->preserve(*reg);
74 }
75 g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, stub);
76 }
77
78 %}
79
80 // TODO 8350865 (same applies to g1StoreLSpecialTwoOops)
81 // - Can we use an unbound register for src?
82 // - Do no set/overwrite barrier data here, also handle G1C2BarrierPostNotNull
83 // - Is the zero-extend really required in all the places?
84 // - Move this into the .m4?
85 instruct g1StoreLSpecialOneOop(indirect mem, iRegL_R11 src, immI off, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
86 %{
87 predicate(UseG1GC);
88 match(Set mem (StoreLSpecial mem (Binary src off)));
89 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, KILL cr);
90 ins_cost(INSN_COST);
91 format %{ "str $src, $mem\t# g1StoreLSpecialOneOop" %}
92 ins_encode %{
93 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
94
95 // Adjust address to point to narrow oop
96 __ add($tmp4$$Register, $mem$$Register, $off$$constant);
97 write_barrier_pre(masm, this,
98 $tmp4$$Register /* obj */,
99 $tmp1$$Register /* pre_val */,
100 $tmp2$$Register /* tmp1 */,
101 $tmp3$$Register /* tmp2 */,
102 RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
103
104 __ str($src$$Register, $mem$$Register);
105
106 // Shift long value to extract the narrow oop field value and zero-extend it
107 __ lsr($src$$Register, $src$$Register, $off$$constant << LogBitsPerByte);
108 __ ubfm($src$$Register, $src$$Register, 0, 31);
109
110 write_barrier_post(masm, this,
111 $tmp4$$Register /* store_addr */,
112 $src$$Register /* new_val */,
113 $tmp2$$Register /* tmp1 */,
114 $tmp3$$Register /* tmp2 */);
115 %}
116 ins_pipe(istore_reg_mem);
117 %}
118
119 instruct g1StoreLSpecialTwoOops(indirect mem, iRegL_R11 src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, iRegPNoSp tmp4, rFlagsReg cr)
120 %{
121 predicate(UseG1GC);
122 match(Set mem (StoreLSpecial mem src));
123 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, KILL cr);
124 ins_cost(INSN_COST);
125 format %{ "str $src, $mem\t# g1StoreLSpecialTwoOops" %}
126 ins_encode %{
127 ((MachNode*)this)->set_barrier_data(G1C2BarrierPre | G1C2BarrierPost);
128
129 write_barrier_pre(masm, this,
130 $mem$$Register /* obj */,
131 $tmp1$$Register /* pre_val */,
132 $tmp2$$Register /* tmp1 */,
133 $tmp3$$Register /* tmp2 */,
134 RegSet::of($mem$$Register, $src$$Register) /* preserve */);
135 // Adjust address to point to the second narrow oop in the long value
136 __ add($tmp4$$Register, $mem$$Register, 4);
137 write_barrier_pre(masm, this,
138 $tmp4$$Register /* obj */,
139 $tmp1$$Register /* pre_val */,
140 $tmp2$$Register /* tmp1 */,
141 $tmp3$$Register /* tmp2 */,
142 RegSet::of($mem$$Register, $src$$Register, $tmp4$$Register) /* preserve */);
143
144 __ str($src$$Register, $mem$$Register);
145
146 // Zero-extend first narrow oop to long
147 __ ubfm($tmp1$$Register, $src$$Register, 0, 31);
148
149 // Shift long value to extract the second narrow oop field value
150 __ lsr($src$$Register, $src$$Register, 32);
151
152 write_barrier_post(masm, this,
153 $mem$$Register /* store_addr */,
154 $tmp1$$Register /* new_val */,
155 $tmp2$$Register /* tmp1 */,
156 $tmp3$$Register /* tmp2 */,
157 RegSet::of($tmp1$$Register, $tmp4$$Register) /* preserve */);
158 write_barrier_post(masm, this,
159 $tmp4$$Register /* store_addr */,
160 $src$$Register /* new_val */,
161 $tmp2$$Register /* tmp1 */,
162 $tmp3$$Register /* tmp2 */);
163 %}
164 ins_pipe(istore_reg_mem);
165 %}
166
167
168 // BEGIN This section of the file is automatically generated. Do not edit --------------
169
170 // This section is generated from g1_aarch64.m4
171
172
173 // This pattern is generated automatically from g1_aarch64.m4.
174 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
175 instruct g1StoreP(indirect mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, iRegPNoSp tmp3, rFlagsReg cr)
176 %{
177 predicate(UseG1GC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
178 match(Set mem (StoreP mem src));
179 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
180 ins_cost(INSN_COST);
181 format %{ "str $src, $mem\t# ptr" %}
182 ins_encode %{
183 write_barrier_pre(masm, this,
184 $mem$$Register /* obj */,
185 $tmp1$$Register /* pre_val */,
186 $tmp2$$Register /* tmp1 */,
187 $tmp3$$Register /* tmp2 */,
|