|
1 | 1 | /* |
2 | | - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * Copyright (c) 2018, 2024 SAP SE. All rights reserved. |
4 | 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 | 5 | * |
@@ -129,6 +129,57 @@ void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* mas |
129 | 129 | } |
130 | 130 | } |
131 | 131 |
|
| 132 | +static void generate_post_barrier(MacroAssembler* masm, |
| 133 | + const Register store_addr, |
| 134 | + const Register new_val, |
| 135 | + const Register thread, |
| 136 | + const Register tmp1, |
| 137 | + const Register tmp2, |
| 138 | + Label& done, |
| 139 | + bool new_val_may_be_null) { |
| 140 | + |
| 141 | + __ block_comment("generate_post_barrier {"); |
| 142 | + |
| 143 | + assert(thread == Z_thread, "must be"); |
| 144 | + assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg); |
| 145 | + |
| 146 | + // Does store cross heap regions? |
| 147 | + if (VM_Version::has_DistinctOpnds()) { |
| 148 | + __ z_xgrk(tmp1, store_addr, new_val); // tmp1 := store address ^ new value |
| 149 | + } else { |
| 150 | + __ z_lgr(tmp1, store_addr); |
| 151 | + __ z_xgr(tmp1, new_val); |
| 152 | + } |
| 153 | + __ z_srag(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes) |
| 154 | + __ branch_optimized(Assembler::bcondEqual, done); |
| 155 | + |
| 156 | + // Crosses regions, storing null? |
| 157 | + if (new_val_may_be_null) { |
| 158 | + __ z_ltgr(new_val, new_val); |
| 159 | + __ z_bre(done); |
| 160 | + } else { |
| 161 | +#ifdef ASSERT |
| 162 | + __ z_ltgr(new_val, new_val); |
| 163 | + __ asm_assert(Assembler::bcondNotZero, "null oop not allowed (G1 post)", 0x322); // Checked by caller. |
| 164 | +#endif |
| 165 | + } |
| 166 | + |
| 167 | + __ z_srag(tmp1, store_addr, CardTable::card_shift()); |
| 168 | + |
| 169 | + Address card_table_addr(thread, in_bytes(G1ThreadLocalData::card_table_base_offset())); |
| 170 | + __ z_alg(tmp1, card_table_addr); // tmp1 := card address |
| 171 | + |
| 172 | + if(UseCondCardMark) { |
| 173 | + __ z_cli(0, tmp1, G1CardTable::clean_card_val()); |
| 174 | + __ branch_optimized(Assembler::bcondNotEqual, done); |
| 175 | + } |
| 176 | + |
| 177 | + static_assert(G1CardTable::dirty_card_val() == 0, "must be to use z_mvi"); |
| 178 | + __ z_mvi(0, tmp1, G1CardTable::dirty_card_val()); // *(card address) := dirty_card_val |
| 179 | + |
| 180 | + __ block_comment("} generate_post_barrier"); |
| 181 | +} |
| 182 | + |
132 | 183 | #if defined(COMPILER2) |
133 | 184 |
|
134 | 185 | #undef __ |
@@ -204,57 +255,6 @@ void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm, |
204 | 255 | BLOCK_COMMENT("} generate_c2_pre_barrier_stub"); |
205 | 256 | } |
206 | 257 |
|
207 | | -static void generate_post_barrier(MacroAssembler* masm, |
208 | | - const Register store_addr, |
209 | | - const Register new_val, |
210 | | - const Register thread, |
211 | | - const Register tmp1, |
212 | | - const Register tmp2, |
213 | | - Label& done, |
214 | | - bool new_val_may_be_null) { |
215 | | - |
216 | | - __ block_comment("generate_post_barrier {"); |
217 | | - |
218 | | - assert(thread == Z_thread, "must be"); |
219 | | - assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg); |
220 | | - |
221 | | - // Does store cross heap regions? |
222 | | - if (VM_Version::has_DistinctOpnds()) { |
223 | | - __ z_xgrk(tmp1, store_addr, new_val); // tmp1 := store address ^ new value |
224 | | - } else { |
225 | | - __ z_lgr(tmp1, store_addr); |
226 | | - __ z_xgr(tmp1, new_val); |
227 | | - } |
228 | | - __ z_srag(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes) |
229 | | - __ branch_optimized(Assembler::bcondEqual, done); |
230 | | - |
231 | | - // Crosses regions, storing null? |
232 | | - if (new_val_may_be_null) { |
233 | | - __ z_ltgr(new_val, new_val); |
234 | | - __ z_bre(done); |
235 | | - } else { |
236 | | -#ifdef ASSERT |
237 | | - __ z_ltgr(new_val, new_val); |
238 | | - __ asm_assert(Assembler::bcondNotZero, "null oop not allowed (G1 post)", 0x322); // Checked by caller. |
239 | | -#endif |
240 | | - } |
241 | | - |
242 | | - __ z_srag(tmp1, store_addr, CardTable::card_shift()); |
243 | | - |
244 | | - Address card_table_addr(thread, in_bytes(G1ThreadLocalData::card_table_base_offset())); |
245 | | - __ z_alg(tmp1, card_table_addr); // tmp1 := card address |
246 | | - |
247 | | - if(UseCondCardMark) { |
248 | | - __ z_cli(0, tmp1, G1CardTable::clean_card_val()); |
249 | | - __ branch_optimized(Assembler::bcondNotEqual, done); |
250 | | - } |
251 | | - |
252 | | - static_assert(G1CardTable::dirty_card_val() == 0, "must be to use z_mvi"); |
253 | | - __ z_mvi(0, tmp1, G1CardTable::dirty_card_val()); // *(card address) := dirty_card_val |
254 | | - |
255 | | - __ block_comment("} generate_post_barrier"); |
256 | | -} |
257 | | - |
258 | 258 | void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm, |
259 | 259 | Register store_addr, |
260 | 260 | Register new_val, |
|
0 commit comments