diff -r b1a394e15ae9 -r 0d7877278adf src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Wed Sep 18 20:56:18 2019 +0200 +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Wed Sep 18 20:56:19 2019 +0200 @@ -47,35 +47,28 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) { - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; - bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops); bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0; if (type == T_OBJECT || type == T_ARRAY) { + + if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) { #ifdef _LP64 - if (!checkcast) { - if (!obj_int) { - // Save count for barrier - __ movptr(r11, count); - } else if (disjoint) { - // Save dst in r11 in the disjoint case - __ movq(r11, dst); + Register thread = r15_thread; +#else + Register thread = rax; + if (thread == src || thread == dst || thread == count) { + thread = rbx; } - } -#else - if (disjoint) { - __ mov(rdx, dst); // save 'to' - } -#endif - - if (ShenandoahSATBBarrier && !dest_uninitialized) { - Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); - assert_different_registers(dst, count, thread); // we don't care about src here? -#ifndef _LP64 + if (thread == src || thread == dst || thread == count) { + thread = rcx; + } + if (thread == src || thread == dst || thread == count) { + thread = rdx; + } __ push(thread); __ get_thread(thread); #endif + assert_different_registers(src, dst, count, thread); Label done; // Short-circuit if count == 0. @@ -84,32 +77,33 @@ // Avoid runtime call when not marking. Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); - __ testb(gc_state, ShenandoahHeap::MARKING); + int flags = ShenandoahHeap::HAS_FORWARDED; + if (!dest_uninitialized) { + flags |= ShenandoahHeap::MARKING; + } + __ testb(gc_state, flags); __ jcc(Assembler::zero, done); __ pusha(); // push registers #ifdef _LP64 - if (count == c_rarg0) { - if (dst == c_rarg1) { - // exactly backwards!! - __ xchgptr(c_rarg1, c_rarg0); + assert(src == rdi, "expected"); + assert(dst == rsi, "expected"); + assert(count == rdx, "expected"); + if (UseCompressedOops) { + if (dest_uninitialized) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count); } else { - __ movptr(c_rarg1, count); - __ movptr(c_rarg0, dst); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count); } - } else { - __ movptr(c_rarg0, dst); - __ movptr(c_rarg1, count); + } else +#endif + { + if (dest_uninitialized) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count); + } else { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count); + } } - if (UseCompressedOops) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), 2); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), 2); - } -#else - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), - dst, count); -#endif __ popa(); __ bind(done); NOT_LP64(__ pop(thread);) @@ -118,73 +112,6 @@ } -void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, - Register src, Register dst, Register count) { - bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0; - bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0; - bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops); - Register tmp = rax; - - if (type == T_OBJECT || type == T_ARRAY) { -#ifdef _LP64 - if (!checkcast) { - if (!obj_int) { - // Save count for barrier - count = r11; - } else if (disjoint && obj_int) { - // Use the saved dst in the disjoint case - dst = r11; - } - } else { - tmp = rscratch1; - } -#else - if (disjoint) { - __ mov(dst, rdx); // restore 'to' - } -#endif - - Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); - assert_different_registers(dst, thread); // do we care about src at all here? - -#ifndef _LP64 - __ push(thread); - __ get_thread(thread); -#endif - - // Short-circuit if count == 0. - Label done; - __ testptr(count, count); - __ jcc(Assembler::zero, done); - - // Skip runtime call if no forwarded objects. - Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); - __ testb(gc_state, ShenandoahHeap::UPDATEREFS); - __ jcc(Assembler::zero, done); - - __ pusha(); // push registers (overkill) -#ifdef _LP64 - if (c_rarg0 == count) { // On win64 c_rarg0 == rcx - assert_different_registers(c_rarg1, dst); - __ mov(c_rarg1, count); - __ mov(c_rarg0, dst); - } else { - assert_different_registers(c_rarg0, count); - __ mov(c_rarg0, dst); - __ mov(c_rarg1, count); - } - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_post_entry), 2); -#else - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_post_entry), - dst, count); -#endif - __ popa(); - - __ bind(done); - NOT_LP64(__ pop(thread);) - } -} - void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm, Register obj, Register pre_val,