666 }
667
668 #define __ cgen->assembler()->
669
670 // Shenandoah load reference barrier.
671 //
672 // Input:
673 // r0: OOP to evacuate. Not null.
674 // r1: load address
675 //
676 // Output:
677 // r0: Pointer to evacuated OOP.
678 //
679 // Trash rscratch1, rscratch2. Preserve everything else.
680 address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) {
681
682 __ align(6);
683 StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb");
684 address start = __ pc();
685
686 Label work, done;
687 __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr());
688 __ lsr(rscratch1, r0, ShenandoahHeapRegion::region_size_bytes_shift_jint());
689 __ ldrb(rscratch2, Address(rscratch2, rscratch1));
690 __ tbnz(rscratch2, 0, work);
691 __ ret(lr);
692 __ bind(work);
693
694 Label slow_path;
695 __ ldr(rscratch1, Address(r0, oopDesc::mark_offset_in_bytes()));
696 __ eon(rscratch1, rscratch1, zr);
697 __ ands(zr, rscratch1, markWord::lock_mask_in_place);
698 __ br(Assembler::NE, slow_path);
699
700 // Decode forwarded object.
701 __ orr(rscratch1, rscratch1, markWord::marked_value);
702 __ eon(r0, rscratch1, zr);
703 __ ret(lr);
704
705 __ bind(slow_path);
706 __ enter(); // required for proper stackwalking of RuntimeStub frame
707
708 __ push_call_clobbered_registers();
709
710 if (UseCompressedOops) {
711 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow));
712 } else {
713 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier));
714 }
715 __ blr(lr);
716 __ mov(rscratch1, r0);
717 __ pop_call_clobbered_registers();
718 __ mov(r0, rscratch1);
719
720 __ leave(); // required for proper stackwalking of RuntimeStub frame
721 __ bind(done);
722 __ ret(lr);
723
724 return start;
725 }
726
727 #undef __
728
729 void ShenandoahBarrierSetAssembler::barrier_stubs_init() {
730 if (ShenandoahLoadRefBarrier) {
731 int stub_code_size = 2048;
732 ResourceMark rm;
733 BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size);
734 CodeBuffer buf(bb);
735 StubCodeGenerator cgen(&buf);
736 _shenandoah_lrb = generate_shenandoah_lrb(&cgen);
737 }
738 }
|
666 }
667
668 #define __ cgen->assembler()->
669
670 // Shenandoah load reference barrier.
671 //
672 // Input:
673 // r0: OOP to evacuate. Not null.
674 // r1: load address
675 //
676 // Output:
677 // r0: Pointer to evacuated OOP.
678 //
679 // Trash rscratch1, rscratch2. Preserve everything else.
680 address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) {
681
682 __ align(6);
683 StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb");
684 address start = __ pc();
685
686 Label slow_path;
687 __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr());
688 __ lsr(rscratch1, r0, ShenandoahHeapRegion::region_size_bytes_shift_jint());
689 __ ldrb(rscratch2, Address(rscratch2, rscratch1));
690 __ tbnz(rscratch2, 0, slow_path);
691 __ ret(lr);
692
693 __ bind(slow_path);
694 __ enter(); // required for proper stackwalking of RuntimeStub frame
695
696 __ push_call_clobbered_registers();
697
698 if (UseCompressedOops) {
699 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow));
700 } else {
701 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier));
702 }
703 __ blr(lr);
704 __ mov(rscratch1, r0);
705 __ pop_call_clobbered_registers();
706 __ mov(r0, rscratch1);
707
708 __ leave(); // required for proper stackwalking of RuntimeStub frame
709 __ ret(lr);
710
711 return start;
712 }
713
714 #undef __
715
716 void ShenandoahBarrierSetAssembler::barrier_stubs_init() {
717 if (ShenandoahLoadRefBarrier) {
718 int stub_code_size = 2048;
719 ResourceMark rm;
720 BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size);
721 CodeBuffer buf(bb);
722 StubCodeGenerator cgen(&buf);
723 _shenandoah_lrb = generate_shenandoah_lrb(&cgen);
724 }
725 }
|