< prev index next >

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

Print this page
@@ -46,11 +46,11 @@
  
  void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
                                                         Register src, Register dst, Register count, RegSet saved_regs) {
    if (is_oop) {
      bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
-     if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahIUBarrier || ShenandoahLoadRefBarrier) {
+     if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
  
        Label done;
  
        // Avoid calling runtime if count == 0
        __ beqz(count, done);

@@ -79,10 +79,17 @@
        __ bind(done);
      }
    }
  }
  
+ void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
+                                                        Register start, Register count, Register tmp, RegSet saved_regs) {
+   if (ShenandoahCardBarrier && is_oop) {
+     gen_write_ref_array_post_barrier(masm, decorators, start, count, tmp, saved_regs);
+   }
+ }
+ 
  void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
                                                                   Register obj,
                                                                   Register pre_val,
                                                                   Register thread,
                                                                   Register tmp,

@@ -110,22 +117,18 @@
    Label runtime;
  
    assert_different_registers(obj, pre_val, tmp1, tmp2);
    assert(pre_val != noreg && tmp1 != noreg && tmp2 != noreg, "expecting a register");
  
-   Address in_progress(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()));
    Address index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
    Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
  
    // Is marking active?
-   if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
-     __ lwu(tmp1, in_progress);
-   } else {
-     assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
-     __ lbu(tmp1, in_progress);
-   }
-   __ beqz(tmp1, done);
+   Address gc_state(xthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
+   __ lbu(t1, gc_state);
+   __ test_bit(t1, t1, ShenandoahHeap::MARKING_BITPOS);
+   __ beqz(t1, done);
  
    // Do we need to load the previous value?
    if (obj != noreg) {
      __ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW);
    }

@@ -137,11 +140,11 @@
    // Is index == 0?
    // (The index field is typed as size_t.)
    __ ld(tmp1, index);                  // tmp := *index_adr
    __ beqz(tmp1, runtime);              // tmp == 0? If yes, goto runtime
  
-   __ sub(tmp1, tmp1, wordSize);        // tmp := tmp - wordSize
+   __ sub(tmp1, tmp1, wordSize);       // tmp := tmp - wordSize
    __ sd(tmp1, index);                  // *index_adr := tmp
    __ ld(tmp2, buffer);
    __ add(tmp1, tmp1, tmp2);            // tmp := tmp + *buffer_adr
  
    // Record the previous value

@@ -310,20 +313,10 @@
  
    __ bind(heap_stable);
    __ leave();
  }
  
- void ShenandoahBarrierSetAssembler::iu_barrier(MacroAssembler* masm, Register dst, Register tmp) {
-   if (ShenandoahIUBarrier) {
-     __ push_call_clobbered_registers();
- 
-     satb_write_barrier_pre(masm, noreg, dst, xthread, tmp, t0, true, false);
- 
-     __ pop_call_clobbered_registers();
-   }
- }
- 
  //
  // Arguments:
  //
  // Inputs:
  //   src:        oop location to load from, might be clobbered

@@ -394,10 +387,32 @@
      __ pop_call_clobbered_registers();
      __ leave();
    }
  }
  
+ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj) {
+   assert(ShenandoahCardBarrier, "Did you mean to enable ShenandoahCardBarrier?");
+ 
+   __ srli(obj, obj, CardTable::card_shift());
+ 
+   assert(CardTable::dirty_card_val() == 0, "must be");
+ 
+   Address curr_ct_holder_addr(xthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
+   __ ld(t1, curr_ct_holder_addr);
+   __ add(t1, obj, t1);
+ 
+   if (UseCondCardMark) {
+     Label L_already_dirty;
+     __ lbu(t0, Address(t1));
+     __ beqz(t0, L_already_dirty);
+     __ sb(zr, Address(t1));
+     __ bind(L_already_dirty);
+   } else {
+     __ sb(zr, Address(t1));
+   }
+ }
+ 
  void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                               Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
    bool on_oop = is_reference_type(type);
    if (!on_oop) {
      BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);

@@ -419,21 +434,16 @@
                                 xthread /* thread */,
                                 tmp1  /* tmp */,
                                 val != noreg /* tosca_live */,
                                 false /* expand_call */);
  
-   if (val == noreg) {
-     BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), noreg, noreg, noreg, noreg);
-   } else {
-     iu_barrier(masm, val, tmp1);
-     // G1 barrier needs uncompressed oop for region cross check.
-     Register new_val = val;
-     if (UseCompressedOops) {
-       new_val = t1;
-       __ mv(new_val, val);
-     }
-     BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), val, noreg, noreg, noreg);
+   BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp3, 0), val, noreg, noreg, noreg);
+ 
+   bool in_heap = (decorators & IN_HEAP) != 0;
+   bool needs_post_barrier = (val != noreg) && in_heap && ShenandoahCardBarrier;
+   if (needs_post_barrier) {
+     store_check(masm, tmp3);
    }
  }
  
  void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
                                                                    Register obj, Register tmp, Label& slowpath) {

@@ -537,10 +547,42 @@
    }
  
    __ bind(done);
  }
  
+ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
+                                                                      Register start, Register count, Register tmp, RegSet saved_regs) {
+   assert(ShenandoahCardBarrier, "Did you mean to enable ShenandoahCardBarrier?");
+ 
+   Label L_loop, L_done;
+   const Register end = count;
+ 
+   // Zero count? Nothing to do.
+   __ beqz(count, L_done);
+ 
+   // end = start + count << LogBytesPerHeapOop
+   // last element address to make inclusive
+   __ shadd(end, count, start, tmp, LogBytesPerHeapOop);
+   __ sub(end, end, BytesPerHeapOop);
+   __ srli(start, start, CardTable::card_shift());
+   __ srli(end, end, CardTable::card_shift());
+ 
+   // number of bytes to copy
+   __ sub(count, end, start);
+ 
+   Address curr_ct_holder_addr(xthread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
+   __ ld(tmp, curr_ct_holder_addr);
+   __ add(start, start, tmp);
+ 
+   __ bind(L_loop);
+   __ add(tmp, start, count);
+   __ sb(zr, Address(tmp));
+   __ sub(count, count, 1);
+   __ bgez(count, L_loop);
+   __ bind(L_done);
+ }
+ 
  #undef __
  
  #ifdef COMPILER1
  
  #define __ ce->masm()->
< prev index next >