8078438: Interpreter should support conditional card marks (UseCondCardMark) on x86 and aarch64
Add interpreter support for conditional card marks on x86 and aarch64 Reviewed-by: tschatzl, aph
This commit is contained in:
parent
7f027ca123
commit
6cb9f920e1
@ -2888,41 +2888,40 @@ void MacroAssembler::cmpptr(Register src1, Address src2) {
|
||||
cmp(src1, rscratch1);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check(Register obj) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
store_check_part_1(obj);
|
||||
store_check_part_2(obj);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check(Register obj, Address dst) {
|
||||
store_check(obj);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check(Register obj) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
|
||||
// split the store check operation so that other instructions can be scheduled inbetween
|
||||
void MacroAssembler::store_check_part_1(Register obj) {
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
|
||||
lsr(obj, obj, CardTableModRefBS::card_shift);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check_part_2(Register obj) {
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
|
||||
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
||||
CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
// The calculation for byte_map_base is as follows:
|
||||
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
|
||||
// So this essentially converts an address to a displacement and
|
||||
// it will never need to be relocated.
|
||||
lsr(obj, obj, CardTableModRefBS::card_shift);
|
||||
|
||||
// FIXME: It's not likely that disp will fit into an offset so we
|
||||
// don't bother to check, but it could save an instruction.
|
||||
intptr_t disp = (intptr_t) ct->byte_map_base;
|
||||
mov(rscratch1, disp);
|
||||
assert(CardTableModRefBS::dirty_card_val() == 0, "must be");
|
||||
|
||||
{
|
||||
ExternalAddress cardtable((address) ct->byte_map_base);
|
||||
unsigned long offset;
|
||||
adrp(rscratch1, cardtable, offset);
|
||||
assert(offset == 0, "byte_map_base is misaligned");
|
||||
}
|
||||
|
||||
if (UseCondCardMark) {
|
||||
Label L_already_dirty;
|
||||
ldrb(rscratch2, Address(obj, rscratch1));
|
||||
cbz(rscratch2, L_already_dirty);
|
||||
strb(zr, Address(obj, rscratch1));
|
||||
bind(L_already_dirty);
|
||||
} else {
|
||||
strb(zr, Address(obj, rscratch1));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
|
@ -756,10 +756,6 @@ public:
|
||||
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
// split store_check(Register obj) to enhance instruction interleaving
|
||||
void store_check_part_1(Register obj);
|
||||
void store_check_part_2(Register obj);
|
||||
|
||||
// oop manipulations
|
||||
void load_klass(Register dst, Register src);
|
||||
void store_klass(Register dst, Register src);
|
||||
|
@ -4260,31 +4260,24 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void MacroAssembler::store_check(Register obj) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
store_check_part_1(obj);
|
||||
store_check_part_2(obj);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check(Register obj, Address dst) {
|
||||
store_check(obj);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check(Register obj) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
|
||||
// split the store check operation so that other instructions can be scheduled inbetween
|
||||
void MacroAssembler::store_check_part_1(Register obj) {
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
|
||||
shrptr(obj, CardTableModRefBS::card_shift);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_check_part_2(Register obj) {
|
||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
|
||||
CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
shrptr(obj, CardTableModRefBS::card_shift);
|
||||
|
||||
Address card_addr;
|
||||
|
||||
// The calculation for byte_map_base is as follows:
|
||||
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
|
||||
// So this essentially converts an address to a displacement and it will
|
||||
@ -4292,8 +4285,7 @@ void MacroAssembler::store_check_part_2(Register obj) {
|
||||
// large for a 32bit displacement.
|
||||
intptr_t disp = (intptr_t) ct->byte_map_base;
|
||||
if (is_simm32(disp)) {
|
||||
Address cardtable(noreg, obj, Address::times_1, disp);
|
||||
movb(cardtable, 0);
|
||||
card_addr = Address(noreg, obj, Address::times_1, disp);
|
||||
} else {
|
||||
// By doing it as an ExternalAddress 'disp' could be converted to a rip-relative
|
||||
// displacement and done in a single instruction given favorable mapping and a
|
||||
@ -4301,7 +4293,18 @@ void MacroAssembler::store_check_part_2(Register obj) {
|
||||
// entry and that entry is not properly handled by the relocation code.
|
||||
AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
|
||||
Address index(noreg, obj, Address::times_1);
|
||||
movb(as_Address(ArrayAddress(cardtable, index)), 0);
|
||||
card_addr = as_Address(ArrayAddress(cardtable, index));
|
||||
}
|
||||
|
||||
int dirty = CardTableModRefBS::dirty_card_val();
|
||||
if (UseCondCardMark) {
|
||||
Label L_already_dirty;
|
||||
cmpb(card_addr, dirty);
|
||||
jcc(Assembler::equal, L_already_dirty);
|
||||
movb(card_addr, dirty);
|
||||
bind(L_already_dirty);
|
||||
} else {
|
||||
movb(card_addr, dirty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,10 +315,6 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
// split store_check(Register obj) to enhance instruction interleaving
|
||||
void store_check_part_1(Register obj);
|
||||
void store_check_part_2(Register obj);
|
||||
|
||||
// C 'boolean' to Java boolean: x == 0 ? 0 : 1
|
||||
void c2bool(Register x);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user