Skip to content

Commit d1bc34f

Browse files
RealFYangWilliam Kemper
authored andcommitted
8339643: Port JEP 404 to RISC-V
Reviewed-by: wkemper, kdnilsen
1 parent e11a68f commit d1bc34f

File tree

4 files changed

+84
-11
lines changed

4 files changed

+84
-11
lines changed

src/hotspot/cpu/riscv/gc/shenandoah/c1/shenandoahBarrierSetC1_riscv.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LI
7878
LIR_Opr result = gen->new_register(T_INT);
7979

8080
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), tmp1, tmp2, result));
81+
82+
if (ShenandoahCardBarrier) {
83+
post_barrier(access, access.resolved_addr(), new_value.result());
84+
}
8185
return result;
8286
}
8387
}
88+
8489
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
8590
}
8691

@@ -105,6 +110,9 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRIt
105110
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
106111
result /* pre_val */);
107112
}
113+
if (ShenandoahCardBarrier) {
114+
post_barrier(access, access.resolved_addr(), result);
115+
}
108116
}
109117

110118
return result;

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

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "gc/shenandoah/shenandoahRuntime.hpp"
3333
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
3434
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
35+
#include "gc/shenandoah/mode/shenandoahMode.hpp"
3536
#include "interpreter/interpreter.hpp"
3637
#include "interpreter/interp_masm.hpp"
3738
#include "runtime/javaThread.hpp"
@@ -81,6 +82,13 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
8182
}
8283
}
8384

85+
void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
86+
Register start, Register count, Register tmp, RegSet saved_regs) {
87+
if (ShenandoahCardBarrier && is_oop) {
88+
gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs);
89+
}
90+
}
91+
8492
void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
8593
Register obj,
8694
Register pre_val,
@@ -382,6 +390,27 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm,
382390
}
383391
}
384392

393+
void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj) {
394+
assert(ShenandoahCardBarrier, "Did you mean to enable ShenandoahCardBarrier?");
395+
396+
__ srli(obj, obj, CardTable::card_shift());
397+
398+
assert(CardTable::dirty_card_val() == 0, "must be");
399+
400+
__ load_byte_map_base(t1);
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+
385414
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
386415
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
387416
bool on_oop = is_reference_type(type);
@@ -407,16 +436,12 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet
407436
val != noreg /* tosca_live */,
408437
false /* expand_call */);
409438

410-
if (val == noreg) {
411-
BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), noreg, noreg, noreg, noreg);
412-
} else {
413-
// Barrier needs uncompressed oop for region cross check.
414-
Register new_val = val;
415-
if (UseCompressedOops) {
416-
new_val = t1;
417-
__ mv(new_val, val);
418-
}
419-
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);
420445
}
421446
}
422447

@@ -524,6 +549,37 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
524549
__ bind(done);
525550
}
526551

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+
__ load_byte_map_base(tmp);
573+
__ add(start, start, tmp);
574+
575+
__ bind(L_loop);
576+
__ add(tmp, start, count);
577+
__ sb(zr, Address(tmp));
578+
__ sub(count, count, 1);
579+
__ bgez(count, L_loop);
580+
__ bind(L_done);
581+
}
582+
527583
#undef __
528584

529585
#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/share/gc/shenandoah/mode/shenandoahGenerationalMode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
void ShenandoahGenerationalMode::initialize_flags() const {
3434

35-
#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64)
35+
#if !(defined AARCH64 || defined AMD64 || defined IA32 || defined PPC64 || defined RISCV64)
3636
vm_exit_during_initialization("Shenandoah Generational GC is not supported on this platform.");
3737
#endif
3838

0 commit comments

Comments
 (0)