8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shenandoah/brooksPointer.hpp"
26 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
27 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
28 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
29 #include "gc/shenandoah/shenandoahRuntime.hpp"
30 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "interpreter/interp_masm.hpp"
33 #include "runtime/sharedRuntime.hpp"
34 #include "runtime/thread.hpp"
35 #include "utilities/macros.hpp"
36 #ifdef COMPILER1
37 #include "c1/c1_LIRAssembler.hpp"
38 #include "c1/c1_MacroAssembler.hpp"
39 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
40 #endif
41
42 #define __ masm->
43
44 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
45 Register src, Register dst, Register count) {
46
47 bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
48 bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
49 bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
50 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
51
52 if (type == T_OBJECT || type == T_ARRAY) {
53 #ifdef _LP64
54 if (!checkcast && !obj_int) {
55 // Save count for barrier
56 __ movptr(r11, count);
57 } else if (disjoint && obj_int) {
58 // Save dst in r11 in the disjoint case
59 __ movq(r11, dst);
60 }
61 #else
62 if (disjoint) {
63 __ mov(rdx, dst); // save 'to'
821 __ save_live_registers_no_oop_map(true);
822
823 // load the pre-value
824 __ load_parameter(0, rcx);
825 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), rcx, thread);
826
827 __ restore_live_registers(true);
828
829 __ bind(done);
830
831 __ pop(rdx);
832 __ pop(rax);
833
834 __ epilogue();
835 }
836
837 #undef __
838
839 #endif // COMPILER1
840
|
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "gc/shenandoah/brooksPointer.hpp"
26 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
27 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
28 #include "gc/shenandoah/shenandoahHeap.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc/shenandoah/shenandoahRuntime.hpp"
31 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
32 #include "interpreter/interpreter.hpp"
33 #include "interpreter/interp_masm.hpp"
34 #include "runtime/sharedRuntime.hpp"
35 #include "runtime/thread.hpp"
36 #include "utilities/macros.hpp"
37 #ifdef COMPILER1
38 #include "c1/c1_LIRAssembler.hpp"
39 #include "c1/c1_MacroAssembler.hpp"
40 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
41 #endif
42
43 #define __ masm->
44
45 address ShenandoahBarrierSetAssembler::_shenandoah_wb = NULL;
46 address ShenandoahBarrierSetAssembler::_shenandoah_wb_C = NULL;
47
48 void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
49 Register src, Register dst, Register count) {
50
51 bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
52 bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
53 bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
54 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
55
56 if (type == T_OBJECT || type == T_ARRAY) {
57 #ifdef _LP64
58 if (!checkcast && !obj_int) {
59 // Save count for barrier
60 __ movptr(r11, count);
61 } else if (disjoint && obj_int) {
62 // Save dst in r11 in the disjoint case
63 __ movq(r11, dst);
64 }
65 #else
66 if (disjoint) {
67 __ mov(rdx, dst); // save 'to'
825 __ save_live_registers_no_oop_map(true);
826
827 // load the pre-value
828 __ load_parameter(0, rcx);
829 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre_entry), rcx, thread);
830
831 __ restore_live_registers(true);
832
833 __ bind(done);
834
835 __ pop(rdx);
836 __ pop(rax);
837
838 __ epilogue();
839 }
840
841 #undef __
842
843 #endif // COMPILER1
844
845 address ShenandoahBarrierSetAssembler::shenandoah_wb() {
846 assert(_shenandoah_wb != NULL, "need write barrier stub");
847 return _shenandoah_wb;
848 }
849
850 address ShenandoahBarrierSetAssembler::shenandoah_wb_C() {
851 assert(_shenandoah_wb_C != NULL, "need write barrier stub");
852 return _shenandoah_wb_C;
853 }
854
855 #define __ cgen->assembler()->
856
857 address ShenandoahBarrierSetAssembler::generate_shenandoah_wb(StubCodeGenerator* cgen, bool c_abi, bool do_cset_test) {
858 __ align(CodeEntryAlignment);
859 StubCodeMark mark(cgen, "StubRoutines", "shenandoah_wb");
860 address start = __ pc();
861
862 Label not_done;
863
864 // We use RDI, which also serves as argument register for slow call.
865 // RAX always holds the src object ptr, except after the slow call and
866 // the cmpxchg, then it holds the result.
867 // R8 and RCX are used as temporary registers.
868 if (!c_abi) {
869 __ push(rdi);
870 __ push(r8);
871 }
872
873 // Check for object beeing in the collection set.
874 // TODO: Can we use only 1 register here?
875 // The source object arrives here in rax.
876 // live: rax
877 // live: rdi
878 if (!c_abi) {
879 __ mov(rdi, rax);
880 } else {
881 if (rax != c_rarg0) {
882 __ mov(rax, c_rarg0);
883 }
884 }
885 if (do_cset_test) {
886 __ shrptr(rdi, ShenandoahHeapRegion::region_size_bytes_shift_jint());
887 // live: r8
888 __ movptr(r8, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
889 __ movbool(r8, Address(r8, rdi, Address::times_1));
890 // unlive: rdi
891 __ testbool(r8);
892 // unlive: r8
893 __ jccb(Assembler::notZero, not_done);
894
895 if (!c_abi) {
896 __ pop(r8);
897 __ pop(rdi);
898 }
899 __ ret(0);
900
901 __ bind(not_done);
902 }
903
904 if (!c_abi) {
905 __ push(rcx);
906 }
907
908 if (!c_abi) {
909 __ push(rdx);
910 __ push(rdi);
911 __ push(rsi);
912 __ push(r8);
913 __ push(r9);
914 __ push(r10);
915 __ push(r11);
916 __ push(r12);
917 __ push(r13);
918 __ push(r14);
919 __ push(r15);
920 }
921 __ save_vector_registers();
922 __ movptr(rdi, rax);
923 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_barrier_JRT), rdi);
924 __ restore_vector_registers();
925 if (!c_abi) {
926 __ pop(r15);
927 __ pop(r14);
928 __ pop(r13);
929 __ pop(r12);
930 __ pop(r11);
931 __ pop(r10);
932 __ pop(r9);
933 __ pop(r8);
934 __ pop(rsi);
935 __ pop(rdi);
936 __ pop(rdx);
937
938 __ pop(rcx);
939 __ pop(r8);
940 __ pop(rdi);
941 }
942 __ ret(0);
943
944 return start;
945 }
946
947 #undef __
948
949 void ShenandoahBarrierSetAssembler::barrier_stubs_init() {
950 if (ShenandoahWriteBarrier || ShenandoahStoreValEnqueueBarrier) {
951 int stub_code_size = 1536;
952 ResourceMark rm;
953 BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size);
954 CodeBuffer buf(bb);
955 StubCodeGenerator cgen(&buf);
956 _shenandoah_wb = generate_shenandoah_wb(&cgen, false, true);
957 _shenandoah_wb_C = generate_shenandoah_wb(&cgen, true, !ShenandoahWriteBarrierCsetTestInIR);
958 }
959 }
|