RFR 8232992: Shenandoah: Implement self-fixing interpreter LRB

Zhengyu Gu zgu at redhat.com
Thu Oct 31 18:09:09 UTC 2019


Hi Andrew,

Thanks for the suggestions. Filed JDK-8233337 to clean this up.

-Zhengyu

On 10/31/19 12:50 PM, Andrew Haley wrote:
> On 10/25/19 3:29 PM, Zhengyu Gu wrote:
>> Test:
>>     hotspot_gc_shenandoah (fastdebug and release)
>>     x86_64 and x86_32 on Linux
>>     aarch64 Linux
>>     Windows x86_64
> 
> I didn't see this because I don't read all the Shenandoah and GC
> messages.
> 
> The AArch64 code is unidiomatic and cumbersome in places, not to
> mention extremely confusing, and I can help with that.
> 
>   236 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr) {
>   237   assert(ShenandoahLoadRefBarrier, "Should be enabled");
>   238   assert(dst != rscratch2, "need rscratch2");
>   239   assert_different_registers(load_addr.base(), load_addr.index(), rscratch1);
>   240   assert_different_registers(load_addr.base(), load_addr.index(), rscratch2);
>   241
>   242   Label done;
>   243   __ enter();
>   244   Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
>   245   __ ldrb(rscratch2, gc_state);
>   246
>   247   // Check for heap stability
>   248   __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done);
>   249
>   250   // use r1 for load address
>   251   Register result_dst = dst;
>   252   if (dst == r1) {
>   253     __ mov(rscratch1, dst);
> 
> This is pointless. On AArch64 mov(Rn, Rm) generates no code if Rn == Rm.
> 
>   254     dst = rscratch1;
>   255   }
>   256
>   257   RegSet to_save_r1 = RegSet::of(r1);
>   258   // If outgoing register is r1, we can clobber it
>   259   if (result_dst != r1) {
>   260     __ push(to_save_r1, sp);
>   261   }
> 
> On AArch64 registers are always saved in pairs, so it makes sense to push
> individual registers. You might as well push both if either is to be saved.
> 
>   262   __ lea(r1, load_addr);
>   263
>   264   RegSet to_save_r0 = RegSet::of(r0);
>   265   if (dst != r0) {
>   266     __ push(to_save_r0, sp);
>   267     __ mov(r0, dst);
>   268   }
>   269
>   270   __ far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb())));
>   271
>   272   if (result_dst != r0) {
>   273     __ mov(result_dst, r0);
>   274   }
>   275
>   276   if (dst != r0) {
>   277     __ pop(to_save_r0, sp);
>   278   }
>   279
>   280   if (result_dst != r1) {
>   281     __ pop(to_save_r1, sp);
>   282   }
>   283
>   284   __ bind(done);
>   285   __ leave();
>   286 }
> 
> So, you want to save r1 and r0, but if either of those is the destination you
> don't want to save it. The code at ShenandoahBarrierSetAssembler::shenandoah_lrb()
> preserves everything but r1 and r0.
> 
> I believe this is what you want:
> 
> void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr) {
>    assert(ShenandoahLoadRefBarrier, "Should be enabled");
>    assert(dst != rscratch2, "need rscratch2");
>    assert_different_registers(load_addr.base(), load_addr.index(), rscratch1, rscratch2);
> 
>    Label done;
>    __ enter();
>    Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
>    __ ldrb(rscratch2, gc_state);
> 
>    // Check for heap stability
>    __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done);
> 
>    // use r1 for load address
>    Register result_dst = dst;
>    if (dst == r1) {
>      __ mov(rscratch1, dst);
>      dst = rscratch1;
>    }
> 
>    RegSet to_save = RegSet::of(r0, r1) - result_dst;
>    __ push(to_save, sp);
>    __ lea(r1, load_addr);
>    __ mov(r0, dst);
> 
>    __ far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb())));
> 
>    __ mov(result_dst, r0);
>    __ pop(to_save, sp);
> 
>    __ bind(done);
>    __ leave();
> }
> 
> 
> Please forward any patches which contain AArch64 assembly code to the
> aarch64-port-dev at openjdk.java.net list.
> 
> I don't mean any criticism of you personally, but the AArch64 code in
> the Shenandoah GC barriers is gnarly and some of the most difficult to
> read in the whole port, probably because its authors, while
> undoubtedly brilliant, were not experienced AArch64 programmers. Let
> me help.  :-)
> 



More information about the hotspot-gc-dev mailing list