Skip to content

Commit ef9d467

Browse files
author
William Kemper
committed
8343468: GenShen: Enable relocation of remembered set card tables
8351456: Build failure with --disable-jvm-feature-shenandoahgc after 8343468 Reviewed-by: kdnilsen, ysr Backport-of: 4e1367e
1 parent 9fafafa commit ef9d467

26 files changed

+261
-156
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4694,6 +4694,7 @@ operand immByteMapBase()
46944694
%{
46954695
// Get base of card map
46964696
predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
4697+
SHENANDOAHGC_ONLY(!BarrierSet::barrier_set()->is_a(BarrierSet::ShenandoahBarrierSet) &&)
46974698
(CardTable::CardValue*)n->get_ptr() == ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base());
46984699
match(ConP);
46994700

src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register o
383383

384384
assert(CardTable::dirty_card_val() == 0, "must be");
385385

386-
__ load_byte_map_base(rscratch1);
386+
Address curr_ct_holder_addr(rthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
387+
__ ldr(rscratch1, curr_ct_holder_addr);
387388

388389
if (UseCondCardMark) {
389390
Label L_already_dirty;
@@ -638,7 +639,8 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
638639
// number of bytes to copy
639640
__ sub(count, end, start);
640641

641-
__ load_byte_map_base(scratch);
642+
Address curr_ct_holder_addr(rthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
643+
__ ldr(scratch, curr_ct_holder_addr);
642644
__ add(start, start, scratch);
643645
__ bind(L_loop);
644646
__ strb(zr, Address(start, count));

src/hotspot/cpu/ppc/gc/shenandoah/shenandoahBarrierSetAssembler_ppc.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,6 @@ void ShenandoahBarrierSetAssembler::load_at(
588588

589589
void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register base, RegisterOrConstant ind_or_offs, Register tmp) {
590590
assert(ShenandoahCardBarrier, "Should have been checked by caller");
591-
592-
ShenandoahBarrierSet* ctbs = ShenandoahBarrierSet::barrier_set();
593-
CardTable* ct = ctbs->card_table();
594591
assert_different_registers(base, tmp, R0);
595592

596593
if (ind_or_offs.is_constant()) {
@@ -599,7 +596,7 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register b
599596
__ add(base, ind_or_offs.as_register(), base);
600597
}
601598

602-
__ load_const_optimized(tmp, (address)ct->byte_map_base(), R0);
599+
__ ld(tmp, in_bytes(ShenandoahThreadLocalData::card_table_offset()), R16_thread); /* tmp = *[R16_thread + card_table_offset] */
603600
__ srdi(base, base, CardTable::card_shift());
604601
__ li(R0, CardTable::dirty_card_val());
605602
__ stbx(R0, tmp, base);
@@ -798,7 +795,8 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
798795
__ srdi(addr, addr, CardTable::card_shift());
799796
__ srdi(count, count, CardTable::card_shift());
800797
__ subf(count, addr, count);
801-
__ add_const_optimized(addr, addr, (address)ct->byte_map_base(), R0);
798+
__ ld(R0, in_bytes(ShenandoahThreadLocalData::card_table_offset()), R16_thread);
799+
__ add(addr, addr, R0);
802800
__ addi(count, count, 1);
803801
__ li(R0, 0);
804802
__ mtctr(count);

src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
8181
}
8282
}
8383

84+
void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
85+
Register start, Register count, Register tmp, RegSet saved_regs) {
86+
if (ShenandoahCardBarrier && is_oop) {
87+
gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs);
88+
}
89+
}
90+
8491
void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
8592
Register obj,
8693
Register pre_val,
@@ -112,18 +119,14 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
112119
assert_different_registers(obj, pre_val, tmp1, tmp2);
113120
assert(pre_val != noreg && tmp1 != noreg && tmp2 != noreg, "expecting a register");
114121

115-
Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()));
116122
Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
117123
Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
118124

119125
// Is marking active?
120-
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
121-
__ lwu(tmp1, in_progress);
122-
} else {
123-
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
124-
__ lbu(tmp1, in_progress);
125-
}
126-
__ beqz(tmp1, done);
126+
Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
127+
__ lbu(t1, gc_state);
128+
__ test_bit(t1, t1, ShenandoahHeap::MARKING_BITPOS);
129+
__ beqz(t1, done);
127130

128131
// Do we need to load the previous value?
129132
if (obj != noreg) {
@@ -139,7 +142,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
139142
__ ld(tmp1, index); // tmp := *index_adr
140143
__ beqz(tmp1, runtime); // tmp == 0? If yes, goto runtime
141144

142-
__ sub(tmp1, tmp1, wordSize); // tmp := tmp - wordSize
145+
__ sub(tmp1, tmp1, wordSize); // tmp := tmp - wordSize
143146
__ sd(tmp1, index); // *index_adr := tmp
144147
__ ld(tmp2, buffer);
145148
__ add(tmp1, tmp1, tmp2); // tmp := tmp + *buffer_adr
@@ -386,6 +389,28 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm,
386389
}
387390
}
388391

392+
void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj) {
393+
assert(ShenandoahCardBarrier, "Did you mean to enable ShenandoahCardBarrier?");
394+
395+
__ srli(obj, obj, CardTable::card_shift());
396+
397+
assert(CardTable::dirty_card_val() == 0, "must be");
398+
399+
Address curr_ct_holder_addr(xthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
400+
__ ld(t1, curr_ct_holder_addr);
401+
__ add(t1, obj, t1);
402+
403+
if (UseCondCardMark) {
404+
Label L_already_dirty;
405+
__ lbu(t0, Address(t1));
406+
__ beqz(t0, L_already_dirty);
407+
__ sb(zr, Address(t1));
408+
__ bind(L_already_dirty);
409+
} else {
410+
__ sb(zr, Address(t1));
411+
}
412+
}
413+
389414
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
390415
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
391416
bool on_oop = is_reference_type(type);
@@ -411,16 +436,12 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet
411436
val != noreg /* tosca_live */,
412437
false /* expand_call */);
413438

414-
if (val == noreg) {
415-
BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), noreg, noreg, noreg, noreg);
416-
} else {
417-
// Barrier needs uncompressed oop for region cross check.
418-
Register new_val = val;
419-
if (UseCompressedOops) {
420-
new_val = t1;
421-
__ mv(new_val, val);
422-
}
423-
BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), val, noreg, noreg, noreg);
439+
BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), val, noreg, noreg, noreg);
440+
441+
bool in_heap = (decorators & IN_HEAP) != 0;
442+
bool needs_post_barrier = (val != noreg) && in_heap && ShenandoahCardBarrier;
443+
if (needs_post_barrier) {
444+
store_check(masm, tmp3);
424445
}
425446
}
426447

@@ -528,6 +549,38 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
528549
__ bind(done);
529550
}
530551

552+
void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
553+
Register start, Register count, Register tmp, RegSet saved_regs) {
554+
assert(ShenandoahCardBarrier, "Did you mean to enable ShenandoahCardBarrier?");
555+
556+
Label L_loop, L_done;
557+
const Register end = count;
558+
559+
// Zero count? Nothing to do.
560+
__ beqz(count, L_done);
561+
562+
// end = start + count << LogBytesPerHeapOop
563+
// last element address to make inclusive
564+
__ shadd(end, count, start, tmp, LogBytesPerHeapOop);
565+
__ sub(end, end, BytesPerHeapOop);
566+
__ srli(start, start, CardTable::card_shift());
567+
__ srli(end, end, CardTable::card_shift());
568+
569+
// number of bytes to copy
570+
__ sub(count, end, start);
571+
572+
Address curr_ct_holder_addr(xthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
573+
__ ld(tmp, curr_ct_holder_addr);
574+
__ add(start, start, tmp);
575+
576+
__ bind(L_loop);
577+
__ add(tmp, start, count);
578+
__ sb(zr, Address(tmp));
579+
__ sub(count, count, 1);
580+
__ bgez(count, L_loop);
581+
__ bind(L_done);
582+
}
583+
531584
#undef __
532585

533586
#ifdef COMPILER1

src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,16 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler {
5757
bool tosca_live,
5858
bool expand_call);
5959

60+
void store_check(MacroAssembler* masm, Register obj);
61+
6062
void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg);
6163
void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg);
6264
void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr, DecoratorSet decorators);
6365

66+
void gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
67+
Register start, Register count,
68+
Register tmp, RegSet saved_regs);
69+
6470
public:
6571

6672
virtual NMethodPatchingType nmethod_patching_type() { return NMethodPatchingType::conc_data_patch; }
@@ -75,6 +81,9 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler {
7581
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
7682
Register src, Register dst, Register count, RegSet saved_regs);
7783

84+
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
85+
Register start, Register count, Register tmp, RegSet saved_regs);
86+
7887
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
7988
Register dst, Address src, Register tmp1, Register tmp2);
8089
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,

src/hotspot/cpu/riscv/riscv.ad

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,6 +2875,7 @@ operand immByteMapBase()
28752875
%{
28762876
// Get base of card map
28772877
predicate(BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) &&
2878+
SHENANDOAHGC_ONLY(!BarrierSet::barrier_set()->is_a(BarrierSet::ShenandoahBarrierSet) &&)
28782879
(CardTable::CardValue*)n->get_ptr() ==
28792880
((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base());
28802881
match(ConP);

src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
4848
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
4949
CardTable* ct = ctbs->card_table();
5050
intptr_t disp = (intptr_t) ct->byte_map_base();
51+
SHENANDOAHGC_ONLY(assert(!UseShenandoahGC, "Shenandoah byte_map_base is not constant.");)
5152

5253
Label L_loop, L_done;
5354
const Register end = count;

src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -615,32 +615,32 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register o
615615

616616
// Does a store check for the oop in register obj. The content of
617617
// register obj is destroyed afterwards.
618-
619-
ShenandoahBarrierSet* ctbs = ShenandoahBarrierSet::barrier_set();
620-
CardTable* ct = ctbs->card_table();
621-
622618
__ shrptr(obj, CardTable::card_shift());
623619

624-
Address card_addr;
620+
// We'll use this register as the TLS base address and also later on
621+
// to hold the byte_map_base.
622+
Register thread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
623+
Register tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx);
625624

626-
// The calculation for byte_map_base is as follows:
627-
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
628-
// So this essentially converts an address to a displacement and it will
629-
// never need to be relocated. On 64-bit however the value may be too
630-
// large for a 32-bit displacement.
631-
intptr_t byte_map_base = (intptr_t)ct->byte_map_base();
632-
if (__ is_simm32(byte_map_base)) {
633-
card_addr = Address(noreg, obj, Address::times_1, byte_map_base);
634-
} else {
635-
// By doing it as an ExternalAddress 'byte_map_base' could be converted to a rip-relative
636-
// displacement and done in a single instruction given favorable mapping and a
637-
// smarter version of as_Address. However, 'ExternalAddress' generates a relocation
638-
// entry and that entry is not properly handled by the relocation code.
639-
AddressLiteral cardtable((address)byte_map_base, relocInfo::none);
640-
Address index(noreg, obj, Address::times_1);
641-
card_addr = __ as_Address(ArrayAddress(cardtable, index), rscratch1);
625+
#ifndef _LP64
626+
// The next two ifs are just to get temporary registers to use for TLS and card table base.
627+
if (thread == obj) {
628+
thread = rdx;
629+
tmp = rsi;
630+
}
631+
if (tmp == obj) {
632+
tmp = rsi;
642633
}
643634

635+
__ push(thread);
636+
__ push(tmp);
637+
__ get_thread(thread);
638+
#endif
639+
640+
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
641+
__ movptr(tmp, curr_ct_holder_addr);
642+
Address card_addr(tmp, obj, Address::times_1);
643+
644644
int dirty = CardTable::dirty_card_val();
645645
if (UseCondCardMark) {
646646
Label L_already_dirty;
@@ -651,6 +651,11 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register o
651651
} else {
652652
__ movb(card_addr, dirty);
653653
}
654+
655+
#ifndef _LP64
656+
__ pop(tmp);
657+
__ pop(thread);
658+
#endif
654659
}
655660

656661
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
@@ -906,10 +911,6 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
906911
Register tmp) {
907912
assert(ShenandoahCardBarrier, "Should have been checked by caller");
908913

909-
ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
910-
CardTable* ct = bs->card_table();
911-
intptr_t disp = (intptr_t) ct->byte_map_base();
912-
913914
Label L_loop, L_done;
914915
const Register end = count;
915916
assert_different_registers(addr, end);
@@ -919,27 +920,38 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
919920
__ jccb(Assembler::zero, L_done);
920921

921922
#ifdef _LP64
923+
const Register thread = r15_thread;
924+
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
925+
__ movptr(tmp, curr_ct_holder_addr);
926+
922927
__ leaq(end, Address(addr, count, TIMES_OOP, 0)); // end == addr+count*oop_size
923928
__ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
924929
__ shrptr(addr, CardTable::card_shift());
925930
__ shrptr(end, CardTable::card_shift());
926931
__ subptr(end, addr); // end --> cards count
927932

928-
__ mov64(tmp, disp);
929933
__ addptr(addr, tmp);
930934

931935
__ BIND(L_loop);
932936
__ movb(Address(addr, count, Address::times_1), 0);
933937
__ decrement(count);
934938
__ jccb(Assembler::greaterEqual, L_loop);
935939
#else
940+
const Register thread = tmp;
941+
__ get_thread(thread);
942+
943+
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
944+
__ movptr(tmp, curr_ct_holder_addr);
945+
936946
__ lea(end, Address(addr, count, Address::times_ptr, -wordSize));
937947
__ shrptr(addr, CardTable::card_shift());
938948
__ shrptr(end, CardTable::card_shift());
939949
__ subptr(end, addr); // end --> count
940950

951+
__ addptr(addr, tmp);
952+
941953
__ BIND(L_loop);
942-
Address cardtable(addr, count, Address::times_1, disp);
954+
Address cardtable(addr, count, Address::times_1, 0);
943955
__ movb(cardtable, 0);
944956
__ decrement(count);
945957
__ jccb(Assembler::greaterEqual, L_loop);

src/hotspot/share/ci/ciUtilities.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "gc/shared/cardTableBarrierSet.hpp"
2828
#include "gc/shared/cardTable.hpp"
2929
#include "gc/shared/collectedHeap.hpp"
30+
#include "gc/shared/gc_globals.hpp"
3031

3132
// ciUtilities
3233
//
@@ -46,5 +47,6 @@ CardTable::CardValue* ci_card_table_address() {
4647
BarrierSet* bs = BarrierSet::barrier_set();
4748
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
4849
CardTable* ct = ctbs->card_table();
50+
assert(!UseShenandoahGC, "Shenandoah byte_map_base is not constant.");
4951
return ct->byte_map_base();
5052
}

src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Op
4747
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
4848
CardTable* ct = ctbs->card_table();
4949
LIR_Const* card_table_base = new LIR_Const(ct->byte_map_base());
50+
SHENANDOAHGC_ONLY(assert(!UseShenandoahGC, "Shenandoah byte_map_base is not constant.");)
51+
5052
if (addr->is_address()) {
5153
LIR_Address* address = addr->as_address_ptr();
5254
// ptr cannot be an object because we use this barrier for array card marks

0 commit comments

Comments
 (0)