786 __ jcc(Assembler::equal, ok_ret);
787
788 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
789
790 __ ldmxcsr(mxcsr_std);
791
792 __ bind(ok_ret);
793 __ addptr(rsp, wordSize);
794 __ pop(rax);
795 }
796
797 __ ret(0);
798
799 return start;
800 }
801
802 address generate_shenandoah_wb(bool c_abi, bool do_cset_test) {
803 StubCodeMark mark(this, "StubRoutines", "shenandoah_wb");
804 address start = __ pc();
805
806 Label not_done, done, slow_case, not_an_instance, is_array;
807
808 // We use RDI, which also serves as argument register for slow call.
809 // RAX always holds the src object ptr, except after the slow call and
810 // the cmpxchg, then it holds the result.
811 // R8 and RCX are used as temporary registers.
812 if (!c_abi) {
813 __ push(rdi);
814 __ push(r8);
815 }
816
817 // Check for object beeing in the collection set.
818 // TODO: Can we use only 1 register here?
819 // The source object arrives here in rax.
820 // live: rax
821 // live: rdi
822 if (!c_abi) {
823 __ mov(rdi, rax);
824 } else {
825 if (rax != c_rarg0) {
826 __ mov(rax, c_rarg0);
830 __ shrptr(rdi, ShenandoahHeapRegion::region_size_bytes_shift_jint());
831 // live: r8
832 __ movptr(r8, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
833 __ movbool(r8, Address(r8, rdi, Address::times_1));
834 // unlive: rdi
835 __ testbool(r8);
836 // unlive: r8
837 __ jccb(Assembler::notZero, not_done);
838
839 if (!c_abi) {
840 __ pop(r8);
841 __ pop(rdi);
842 }
843 __ ret(0);
844
845 __ bind(not_done);
846 }
847
848 if (!c_abi) {
849 __ push(rcx);
850 }
851
852 if (UseTLAB && ShenandoahAsmWB) {
853
854 Register new_obj = r8;
855 __ movptr(new_obj, Address(r15_thread, JavaThread::gclab_top_offset()));
856 __ testptr(new_obj, new_obj);
857 __ jcc(Assembler::zero, slow_case); // No TLAB.
858
859 __ load_klass(rcx, rax);
860
861 // Figure out object size.
862 __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
863 __ testl(rcx, Klass::_lh_instance_slow_path_bit);
864 // test to see if it has a finalizer or is malformed in some way
865 __ jcc(Assembler::notZero, slow_case);
866 __ cmpl(rcx, Klass::_lh_neutral_value); // Make sure it's an instance (LH > 0)
867 __ jcc(Assembler::lessEqual, not_an_instance); // Thrashes rcx, returns size in rcx. Uses rax.
868 __ bind(is_array);
869
870 // Size in rdi, new_obj in r8, src obj in rax
871
872 Register new_obj_end = rdi;
873 int oop_extra_words = Universe::heap()->oop_extra_words();
874 __ addq(rcx, oop_extra_words * HeapWordSize);
875 __ lea(new_obj_end, Address(new_obj, rcx, Address::times_1));
876 __ cmpptr(new_obj_end, Address(r15_thread, JavaThread::gclab_end_offset()));
877 __ jcc(Assembler::above, slow_case);
878 __ subq(rcx, oop_extra_words * HeapWordSize);
879
880 // Store Brooks pointer and adjust start of newobj.
881 Universe::heap()->compile_prepare_oop(_masm, new_obj);
882
883 // Size in rcx, new_obj in r8, src obj in rax
884
885 // Copy object.
886 Label loop;
887 if (!c_abi) {
888 __ push(rdi); // Save new_obj_end
889 __ push(rsi);
890 } else {
891 __ mov(r9, rdi); // Save new_obj_end
892 }
893 __ shrl(rcx, 3); // Make it num-64-bit-words
894 __ mov(rdi, r8); // Mov dst into rdi
895 __ mov(rsi, rax); // Src into rsi.
896 __ rep_mov();
897 if (!c_abi) {
898 __ pop(rsi); // Restore rsi.
899 __ pop(rdi); // Restore new_obj_end
900 } else {
901 __ mov(rdi, r9); // Restore new_obj_end
902 }
903
904 // Src obj still in rax.
905 if (os::is_MP()) {
906 __ lock();
907 }
908 __ cmpxchgptr(new_obj, Address(rax, BrooksPointer::byte_offset(), Address::times_1));
909 __ jccb(Assembler::notEqual, done); // Failed. Updated object in rax.
910 // Otherwise, we succeeded.
911 __ mov(rax, new_obj);
912 __ movptr(Address(r15_thread, JavaThread::gclab_top_offset()), new_obj_end);
913 __ bind(done);
914
915 if (!c_abi) {
916 __ pop(rcx);
917 __ pop(r8);
918 __ pop(rdi);
919 }
920
921 __ ret(0);
922
923 __ bind(not_an_instance);
924 if (!c_abi) {
925 __ push(rdx);
926 }
927 // Layout_helper bits are in rcx
928 __ movl(rdx, rcx); // Move layout_helper bits to rdx
929 __ movl(rdi, Address(rax, arrayOopDesc::length_offset_in_bytes()));
930 __ shrl(rcx, Klass::_lh_log2_element_size_shift);
931 __ andl(rcx, Klass::_lh_log2_element_size_mask);
932 __ shll(rdi); // Shifts left by number of bits in rcx (CL)
933 __ shrl(rdx, Klass::_lh_header_size_shift);
934 __ andl(rdx, Klass::_lh_header_size_mask);
935 __ addl(rdi, rdx);
936 // Round up.
937 __ addl(rdi, HeapWordSize-1);
938 __ andl(rdi, -HeapWordSize);
939 if (!c_abi) {
940 __ pop(rdx);
941 }
942 // Move size (rdi) into rcx
943 __ movl(rcx, rdi);
944 __ jmp(is_array);
945
946 __ bind(slow_case);
947 }
948
949 if (!c_abi) {
950 __ push(rdx);
951 __ push(rdi);
952 __ push(rsi);
953 __ push(r8);
954 __ push(r9);
955 __ push(r10);
956 __ push(r11);
957 __ push(r12);
958 __ push(r13);
959 __ push(r14);
960 __ push(r15);
961 }
962 __ save_vector_registers();
963 __ movptr(rdi, rax);
964 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_JRT), rdi);
965 __ restore_vector_registers();
966 if (!c_abi) {
|
786 __ jcc(Assembler::equal, ok_ret);
787
788 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
789
790 __ ldmxcsr(mxcsr_std);
791
792 __ bind(ok_ret);
793 __ addptr(rsp, wordSize);
794 __ pop(rax);
795 }
796
797 __ ret(0);
798
799 return start;
800 }
801
802 address generate_shenandoah_wb(bool c_abi, bool do_cset_test) {
803 StubCodeMark mark(this, "StubRoutines", "shenandoah_wb");
804 address start = __ pc();
805
806 Label not_done;
807
808 // We use RDI, which also serves as argument register for slow call.
809 // RAX always holds the src object ptr, except after the slow call and
810 // the cmpxchg, then it holds the result.
811 // R8 and RCX are used as temporary registers.
812 if (!c_abi) {
813 __ push(rdi);
814 __ push(r8);
815 }
816
817 // Check for object beeing in the collection set.
818 // TODO: Can we use only 1 register here?
819 // The source object arrives here in rax.
820 // live: rax
821 // live: rdi
822 if (!c_abi) {
823 __ mov(rdi, rax);
824 } else {
825 if (rax != c_rarg0) {
826 __ mov(rax, c_rarg0);
830 __ shrptr(rdi, ShenandoahHeapRegion::region_size_bytes_shift_jint());
831 // live: r8
832 __ movptr(r8, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
833 __ movbool(r8, Address(r8, rdi, Address::times_1));
834 // unlive: rdi
835 __ testbool(r8);
836 // unlive: r8
837 __ jccb(Assembler::notZero, not_done);
838
839 if (!c_abi) {
840 __ pop(r8);
841 __ pop(rdi);
842 }
843 __ ret(0);
844
845 __ bind(not_done);
846 }
847
848 if (!c_abi) {
849 __ push(rcx);
850 }
851
852 if (!c_abi) {
853 __ push(rdx);
854 __ push(rdi);
855 __ push(rsi);
856 __ push(r8);
857 __ push(r9);
858 __ push(r10);
859 __ push(r11);
860 __ push(r12);
861 __ push(r13);
862 __ push(r14);
863 __ push(r15);
864 }
865 __ save_vector_registers();
866 __ movptr(rdi, rax);
867 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_JRT), rdi);
868 __ restore_vector_registers();
869 if (!c_abi) {
|