7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetAssembler.hpp"
29 #include "gc/g1/g1BarrierSetRuntime.hpp"
30 #include "gc/g1/g1CardTable.hpp"
31 #include "gc/g1/g1HeapRegion.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "gc/shared/collectedHeap.hpp"
34 #include "interpreter/interp_masm.hpp"
35 #include "runtime/javaThread.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #ifdef COMPILER1
38 #include "c1/c1_LIRAssembler.hpp"
39 #include "c1/c1_MacroAssembler.hpp"
40 #include "gc/g1/c1/g1BarrierSetC1.hpp"
41 #endif
42
43 #define __ masm->
44
45 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
46 Register addr, Register count, RegSet saved_regs) {
189 Register tmp1,
190 Register tmp2) {
191 assert(thread == rthread, "must be");
192 assert_different_registers(store_addr, new_val, thread, tmp1, tmp2,
193 rscratch1);
194 assert(store_addr != noreg && new_val != noreg && tmp1 != noreg
195 && tmp2 != noreg, "expecting a register");
196
197 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
198 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
199
200 BarrierSet* bs = BarrierSet::barrier_set();
201 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
202 CardTable* ct = ctbs->card_table();
203
204 Label done;
205 Label runtime;
206
207 // Does store cross heap regions?
208
209 __ eor(tmp1, store_addr, new_val);
210 __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes);
211 __ cbz(tmp1, done);
212
213 // crosses regions, storing null?
214
215 __ cbz(new_val, done);
216
217 // storing region crossing non-null, is card already dirty?
218
219 const Register card_addr = tmp1;
220
221 __ lsr(card_addr, store_addr, CardTable::card_shift());
222
223 // get the address of the card
224 __ load_byte_map_base(tmp2);
225 __ add(card_addr, card_addr, tmp2);
226 __ ldrb(tmp2, Address(card_addr));
227 __ cmpw(tmp2, (int)G1CardTable::g1_young_card_val());
228 __ br(Assembler::EQ, done);
229
230 assert((int)CardTable::dirty_card_val() == 0, "must be 0");
231
232 __ membar(Assembler::StoreLoad);
233
234 __ ldrb(tmp2, Address(card_addr));
235 __ cbzw(tmp2, done);
236
237 // storing a region crossing, non-null oop, card is clean.
238 // dirty card and log.
239
240 __ strb(zr, Address(card_addr));
241
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #if INCLUDE_CDS
28 #include "code/SCCache.hpp"
29 #endif
30 #include "gc/g1/g1BarrierSet.hpp"
31 #include "gc/g1/g1BarrierSetAssembler.hpp"
32 #include "gc/g1/g1BarrierSetRuntime.hpp"
33 #include "gc/g1/g1CardTable.hpp"
34 #include "gc/g1/g1HeapRegion.hpp"
35 #include "gc/g1/g1ThreadLocalData.hpp"
36 #include "gc/shared/collectedHeap.hpp"
37 #include "interpreter/interp_masm.hpp"
38 #include "runtime/javaThread.hpp"
39 #include "runtime/sharedRuntime.hpp"
40 #ifdef COMPILER1
41 #include "c1/c1_LIRAssembler.hpp"
42 #include "c1/c1_MacroAssembler.hpp"
43 #include "gc/g1/c1/g1BarrierSetC1.hpp"
44 #endif
45
46 #define __ masm->
47
48 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
49 Register addr, Register count, RegSet saved_regs) {
192 Register tmp1,
193 Register tmp2) {
194 assert(thread == rthread, "must be");
195 assert_different_registers(store_addr, new_val, thread, tmp1, tmp2,
196 rscratch1);
197 assert(store_addr != noreg && new_val != noreg && tmp1 != noreg
198 && tmp2 != noreg, "expecting a register");
199
200 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
201 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
202
203 BarrierSet* bs = BarrierSet::barrier_set();
204 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
205 CardTable* ct = ctbs->card_table();
206
207 Label done;
208 Label runtime;
209
210 // Does store cross heap regions?
211
212 #if INCLUDE_CDS
213 // AOT code needs to load the barrier grain shift from the aot
214 // runtime constants area in the code cache otherwise we can compile
215 // it as an immediate operand
216 if (SCCache::is_on_for_write()) {
217 address grain_shift_address = (address)AOTRuntimeConstants::grain_shift_address();
218 __ eor(tmp1, store_addr, new_val);
219 __ lea(tmp2, ExternalAddress(grain_shift_address));
220 __ ldrb(tmp2, tmp2);
221 __ lsrv(tmp1, tmp1, tmp2);
222 __ cbz(tmp1, done);
223 } else
224 #endif
225 {
226 __ eor(tmp1, store_addr, new_val);
227 __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes);
228 __ cbz(tmp1, done);
229 }
230 // crosses regions, storing null?
231
232 __ cbz(new_val, done);
233
234 // storing region crossing non-null, is card already dirty?
235
236 const Register card_addr = tmp1;
237
238 #if INCLUDE_CDS
239 // AOT code needs to load the barrier card shift from the aot
240 // runtime constants area in the code cache otherwise we can compile
241 // it as an immediate operand
242 if (SCCache::is_on_for_write()) {
243 address card_shift_address = (address)AOTRuntimeConstants::card_shift_address();
244 __ lea(tmp2, ExternalAddress(card_shift_address));
245 __ ldrb(tmp2, tmp2);
246 __ lsrv(card_addr, store_addr, tmp2);
247 } else
248 #endif
249 {
250 __ lsr(card_addr, store_addr, CardTable::card_shift());
251 }
252
253 // get the address of the card
254 __ load_byte_map_base(tmp2);
255 __ add(card_addr, card_addr, tmp2);
256 __ ldrb(tmp2, Address(card_addr));
257 __ cmpw(tmp2, (int)G1CardTable::g1_young_card_val());
258 __ br(Assembler::EQ, done);
259
260 assert((int)CardTable::dirty_card_val() == 0, "must be 0");
261
262 __ membar(Assembler::StoreLoad);
263
264 __ ldrb(tmp2, Address(card_addr));
265 __ cbzw(tmp2, done);
266
267 // storing a region crossing, non-null oop, card is clean.
268 // dirty card and log.
269
270 __ strb(zr, Address(card_addr));
271
|