diff a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp @@ -25,10 +25,11 @@ #include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/barrierSetRuntime.hpp" #include "gc/shared/collectedHeap.hpp" #include "interpreter/interp_masm.hpp" #include "memory/universe.hpp" #include "runtime/javaThread.hpp" #include "runtime/jniHandles.hpp" @@ -82,26 +83,39 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) { bool in_heap = (decorators & IN_HEAP) != 0; bool in_native = (decorators & IN_NATIVE) != 0; + bool is_not_null = (decorators & IS_NOT_NULL) != 0; + switch (type) { case T_OBJECT: // fall through case T_ARRAY: { - val = val == noreg ? zr : val; if (in_heap) { - if (UseCompressedOops) { - assert(!dst.uses(val), "not enough registers"); - if (val != zr) { - __ encode_heap_oop(val); + if (val == noreg) { + assert(!is_not_null, "inconsistent access"); + if (UseCompressedOops) { + __ sw(zr, dst); + } else { + __ sd(zr, dst); } - __ sw(val, dst); } else { - __ sd(val, dst); + if (UseCompressedOops) { + assert(!dst.uses(val), "not enough registers"); + if (is_not_null) { + __ encode_heap_oop_not_null(val); + } else { + __ encode_heap_oop(val); + } + __ sw(val, dst); + } else { + __ sd(val, dst); + } } } else { assert(in_native, "why else?"); + assert(val != noreg, "not supported"); __ sd(val, dst); } break; } case T_BOOLEAN: @@ -119,10 +133,23 @@ default: Unimplemented(); } } +void BarrierSetAssembler::flat_field_copy(MacroAssembler* masm, DecoratorSet decorators, + Register src, Register dst, Register inline_layout_info) { + // flat_field_copy implementation is fairly complex, and there are not any + // "short-cuts" to be made from asm. What there is, appears to have the same + // cost in C++, so just "call_VM_leaf" for now rather than maintain hundreds + // of hand-rolled instructions... + if (decorators & IS_DEST_UNINITIALIZED) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy_is_dest_uninitialized), src, dst, inline_layout_info); + } else { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetRuntime::value_copy), src, dst, inline_layout_info); + } +} + void BarrierSetAssembler::copy_load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, size_t bytes, Register dst, @@ -290,13 +317,13 @@ ShouldNotReachHere(); } Label& barrier_target = slow_path == nullptr ? skip_barrier : *slow_path; if (slow_path == nullptr) { - __ beq(t0, t1, barrier_target, true /* is_far */); + __ beq(t0, t1, barrier_target, /* is_far */ true); } else { - __ bne(t0, t1, barrier_target, true /* is_far */); + __ bne(t0, t1, barrier_target, /* is_far */ true); } if (slow_path == nullptr) { __ rt_call(StubRoutines::method_entry_barrier()); __ j(skip_barrier);