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+
8492void 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+
385414void 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
0 commit comments