< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Print this page




 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) {


< prev index next >