< prev index next > src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp
Print this page
*
*/
#include "precompiled.hpp"
#include "asm/macroAssembler.inline.hpp"
+ #if INCLUDE_CDS
+ #include "code/SCCache.hpp"
+ #endif
#include "gc/g1/g1BarrierSet.hpp"
#include "gc/g1/g1BarrierSetAssembler.hpp"
#include "gc/g1/g1BarrierSetRuntime.hpp"
#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/g1HeapRegion.hpp"
const Register tmp1,
const Register tmp2,
Label& done,
bool new_val_may_be_null) {
// Does store cross heap regions?
! __ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
! __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
! __ cbz(tmp1, done);
// Crosses regions, storing null?
if (new_val_may_be_null) {
__ cbz(new_val, done);
}
// Storing region crossing non-null, is card young?
! __ lsr(tmp1, store_addr, CardTable::card_shift()); // tmp1 := card address relative to card table base
__ load_byte_map_base(tmp2); // tmp2 := card table base address
__ add(tmp1, tmp1, tmp2); // tmp1 := card address
__ ldrb(tmp2, Address(tmp1)); // tmp2 := card
__ cmpw(tmp2, (int)G1CardTable::g1_young_card_val()); // tmp2 := card == young_card_val?
}
const Register tmp1,
const Register tmp2,
Label& done,
bool new_val_may_be_null) {
// Does store cross heap regions?
! #if INCLUDE_CDS
! // AOT code needs to load the barrier grain shift from the aot
! // runtime constants area in the code cache otherwise we can compile
+ // it as an immediate operand
+ if (SCCache::is_on_for_write()) {
+ address grain_shift_address = (address)AOTRuntimeConstants::grain_shift_address();
+ __ eor(tmp1, store_addr, new_val);
+ __ lea(tmp2, ExternalAddress(grain_shift_address));
+ __ ldrb(tmp2, tmp2);
+ __ lsrv(tmp1, tmp1, tmp2);
+ __ cbz(tmp1, done);
+ } else
+ #endif
+ {
+ __ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
+ __ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
+ __ cbz(tmp1, done);
+ }
+
// Crosses regions, storing null?
if (new_val_may_be_null) {
__ cbz(new_val, done);
}
// Storing region crossing non-null, is card young?
!
+ #if INCLUDE_CDS
+ // AOT code needs to load the barrier card shift from the aot
+ // runtime constants area in the code cache otherwise we can compile
+ // it as an immediate operand
+ if (SCCache::is_on_for_write()) {
+ address card_shift_address = (address)AOTRuntimeConstants::card_shift_address();
+ __ lea(tmp2, ExternalAddress(card_shift_address));
+ __ ldrb(tmp2, tmp2);
+ __ lsrv(tmp1, store_addr, tmp2); // tmp1 := card address relative to card table base
+ } else
+ #endif
+ {
+ __ lsr(tmp1, store_addr, CardTable::card_shift()); // tmp1 := card address relative to card table base
+ }
+
__ load_byte_map_base(tmp2); // tmp2 := card table base address
__ add(tmp1, tmp1, tmp2); // tmp1 := card address
__ ldrb(tmp2, Address(tmp1)); // tmp2 := card
__ cmpw(tmp2, (int)G1CardTable::g1_young_card_val()); // tmp2 := card == young_card_val?
}
SaveLiveRegisters save_registers(masm, stub);
if (c_rarg0 != arg) {
__ mov(c_rarg0, arg);
}
__ mov(c_rarg1, rthread);
! __ mov(rscratch1, runtime_path);
__ blr(rscratch1);
}
void G1BarrierSetAssembler::g1_write_barrier_pre_c2(MacroAssembler* masm,
Register obj,
SaveLiveRegisters save_registers(masm, stub);
if (c_rarg0 != arg) {
__ mov(c_rarg0, arg);
}
__ mov(c_rarg1, rthread);
! __ lea(rscratch1, RuntimeAddress(runtime_path));
__ blr(rscratch1);
}
void G1BarrierSetAssembler::g1_write_barrier_pre_c2(MacroAssembler* masm,
Register obj,
< prev index next >