713 ShenandoahBarrierSetC1* bs = (ShenandoahBarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); |
713 ShenandoahBarrierSetC1* bs = (ShenandoahBarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1(); |
714 __ bind(*stub->entry()); |
714 __ bind(*stub->entry()); |
715 |
715 |
716 Register obj = stub->obj()->as_register(); |
716 Register obj = stub->obj()->as_register(); |
717 Register res = stub->result()->as_register(); |
717 Register res = stub->result()->as_register(); |
|
718 Register addr = stub->addr()->as_register(); |
718 Register tmp1 = stub->tmp1()->as_register(); |
719 Register tmp1 = stub->tmp1()->as_register(); |
719 Register tmp2 = stub->tmp2()->as_register(); |
720 Register tmp2 = stub->tmp2()->as_register(); |
|
721 assert_different_registers(obj, res, addr, tmp1, tmp2); |
720 |
722 |
721 Label slow_path; |
723 Label slow_path; |
722 |
724 |
723 assert(res == rax, "result must arrive in rax"); |
725 assert(res == rax, "result must arrive in rax"); |
724 |
726 |
743 __ movptr(tmp2, Address(tmp2, tmp1, Address::times_1)); |
745 __ movptr(tmp2, Address(tmp2, tmp1, Address::times_1)); |
744 __ testptr(tmp2, 0xFF); |
746 __ testptr(tmp2, 0xFF); |
745 #endif |
747 #endif |
746 __ jcc(Assembler::zero, *stub->continuation()); |
748 __ jcc(Assembler::zero, *stub->continuation()); |
747 |
749 |
748 // Test if object is resolved. |
|
749 __ movptr(tmp1, Address(res, oopDesc::mark_offset_in_bytes())); |
|
750 // Test if both lowest bits are set. We trick it by negating the bits |
|
751 // then test for both bits clear. |
|
752 __ notptr(tmp1); |
|
753 #ifdef _LP64 |
|
754 __ testb(tmp1, markWord::marked_value); |
|
755 #else |
|
756 // On x86_32, C1 register allocator can give us the register without 8-bit support. |
|
757 // Do the full-register access and test to avoid compilation failures. |
|
758 __ testptr(tmp1, markWord::marked_value); |
|
759 #endif |
|
760 __ jccb(Assembler::notZero, slow_path); |
|
761 // Clear both lower bits. It's still inverted, so set them, and then invert back. |
|
762 __ orptr(tmp1, markWord::marked_value); |
|
763 __ notptr(tmp1); |
|
764 // At this point, tmp1 contains the decoded forwarding pointer. |
|
765 __ mov(res, tmp1); |
|
766 |
|
767 __ jmp(*stub->continuation()); |
|
768 |
|
769 __ bind(slow_path); |
750 __ bind(slow_path); |
770 ce->store_parameter(res, 0); |
751 ce->store_parameter(res, 0); |
|
752 ce->store_parameter(addr, 1); |
771 __ call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin())); |
753 __ call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin())); |
772 |
754 |
773 __ jmp(*stub->continuation()); |
755 __ jmp(*stub->continuation()); |
774 } |
756 } |
775 |
757 |
836 void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm) { |
818 void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm) { |
837 __ prologue("shenandoah_load_reference_barrier", false); |
819 __ prologue("shenandoah_load_reference_barrier", false); |
838 // arg0 : object to be resolved |
820 // arg0 : object to be resolved |
839 |
821 |
840 __ save_live_registers_no_oop_map(true); |
822 __ save_live_registers_no_oop_map(true); |
841 __ load_parameter(0, LP64_ONLY(c_rarg0) NOT_LP64(rax)); |
823 |
842 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), LP64_ONLY(c_rarg0) NOT_LP64(rax)); |
824 #ifdef _LP64 |
|
825 __ load_parameter(0, c_rarg0); |
|
826 __ load_parameter(1, c_rarg1); |
|
827 if (UseCompressedOops) { |
|
828 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup_narrow), c_rarg0, c_rarg1); |
|
829 } else { |
|
830 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup), c_rarg0, c_rarg1); |
|
831 } |
|
832 #else |
|
833 __ load_parameter(0, rax); |
|
834 __ load_parameter(1, rbx); |
|
835 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup), rax, rbx); |
|
836 #endif |
|
837 |
843 __ restore_live_registers_except_rax(true); |
838 __ restore_live_registers_except_rax(true); |
844 |
839 |
845 __ epilogue(); |
840 __ epilogue(); |
846 } |
841 } |
847 |
842 |