diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 72b69d16943..9c3bd93f8a6 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -87,21 +87,31 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm } } -void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, - Register start, Register count, Register tmp, RegSet saved_regs) { +void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, + DecoratorSet decorators, + Register start, + Register count, + Register tmp, + RegSet saved_regs) { + assert_different_registers(start, count, tmp); + Label loop, next, done; - const Register end = count; // Zero count? Nothing to do. __ beqz(count, done); - __ shadd(end, count, start, tmp, LogBytesPerHeapOop); // end = start + count << LogBytesPerHeapOop - __ subi(end, end, BytesPerHeapOop); // last element address to make inclusive + // Calculate the number of card marks to set. Since the object might start and + // end within a card, we need to calculate this via the card table indexes of + // the actual start and last addresses covered by the object. + // Temporarily use the count register for the last element address. + __ shadd(count, count, start, tmp, LogBytesPerHeapOop); // end = start + count << LogBytesPerHeapOop + __ subi(count, count, BytesPerHeapOop); // Use last element address for end. __ srli(start, start, CardTable::card_shift()); - __ srli(end, end, CardTable::card_shift()); - __ sub(count, end, start); // Number of bytes to mark - 1 + __ srli(count, count, CardTable::card_shift()); + __ sub(count, count, start); // Number of bytes to mark - 1. + // Add card table base offset to start. Address card_table_address(xthread, G1ThreadLocalData::card_table_base_offset()); __ ld(tmp, card_table_address); __ add(start, start, tmp); @@ -109,14 +119,15 @@ void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* mas __ bind(loop); if (UseCondCardMark) { __ add(tmp, start, count); - static_assert((uint)G1CardTable::clean_card_val() == 0xff, "must be"); __ lbu(tmp, Address(tmp, 0)); - __ subi(tmp, tmp, G1CardTable::clean_card_val()); // Convert to clean_card_value() to a comparison - // against zero to avoid use of an extra temp. + static_assert((uint)G1CardTable::clean_card_val() == 0xff, "must be"); + __ subi(tmp, tmp, G1CardTable::clean_card_val()); // Convert to clean_card_value() to a comparison + // against zero to avoid use of an extra temp. __ bnez(tmp, next); } - static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zr"); + __ add(tmp, start, count); + static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zr"); __ sb(zr, Address(tmp, 0)); __ bind(next);