1 /* 2 * Copyright (c) 2015, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 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 "gc/shenandoah/brooksPointer.hpp" 25 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" 26 27 #include "asm/macroAssembler.hpp" 28 #include "interpreter/interpreter.hpp" 29 30 #define __ masm-> 31 32 #ifndef CC_INTERP 33 void ShenandoahBarrierSet::compile_resolve_oop_runtime(MacroAssembler* masm, Register dst) { 34 35 __ push(rscratch1); 36 37 if (dst != rax) { 38 __ push(rax); 39 } 40 if (dst != rbx) { 41 __ push(rbx); 42 } 43 if (dst != rcx) { 44 __ push(rcx); 45 } 46 if (dst != rdx) { 47 __ push(rdx); 48 } 49 if (dst != rdi) { 50 __ push(rdi); 51 } 52 if (dst != rsi) { 53 __ push(rsi); 54 } 55 if (dst != rbp) { 56 __ push(rbp); 57 } 58 if (dst != r8) { 59 __ push(r8); 60 } 61 if (dst != r9) { 62 __ push(r9); 63 } 64 if (dst != r11) { 65 __ push(r11); 66 } 67 if (dst != r12) { 68 __ push(r12); 69 } 70 if (dst != r13) { 71 __ push(r13); 72 } 73 if (dst != r14) { 74 __ push(r14); 75 } 76 if (dst != r15) { 77 __ push(r15); 78 } 79 80 __ subptr(rsp, 128); 81 __ movdbl(Address(rsp, 0), xmm0); 82 __ movdbl(Address(rsp, 8), xmm1); 83 __ movdbl(Address(rsp, 16), xmm2); 84 __ movdbl(Address(rsp, 24), xmm3); 85 __ movdbl(Address(rsp, 32), xmm4); 86 __ movdbl(Address(rsp, 40), xmm5); 87 __ movdbl(Address(rsp, 48), xmm6); 88 __ movdbl(Address(rsp, 56), xmm7); 89 __ movdbl(Address(rsp, 64), xmm8); 90 __ movdbl(Address(rsp, 72), xmm9); 91 __ movdbl(Address(rsp, 80), xmm10); 92 __ movdbl(Address(rsp, 88), xmm11); 93 __ movdbl(Address(rsp, 96), xmm12); 94 __ movdbl(Address(rsp, 104), xmm13); 95 __ movdbl(Address(rsp, 112), xmm14); 96 __ movdbl(Address(rsp, 120), xmm15); 97 98 __ mov(c_rarg1, dst); 99 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::resolve_oop_static), c_rarg1); 100 __ mov(rscratch1, rax); 101 102 __ movdbl(xmm0, Address(rsp, 0)); 103 __ movdbl(xmm1, Address(rsp, 8)); 104 __ movdbl(xmm2, Address(rsp, 16)); 105 __ movdbl(xmm3, Address(rsp, 24)); 106 __ movdbl(xmm4, Address(rsp, 32)); 107 __ movdbl(xmm5, Address(rsp, 40)); 108 __ movdbl(xmm6, Address(rsp, 48)); 109 __ movdbl(xmm7, Address(rsp, 56)); 110 __ movdbl(xmm8, Address(rsp, 64)); 111 __ movdbl(xmm9, Address(rsp, 72)); 112 __ movdbl(xmm10, Address(rsp, 80)); 113 __ movdbl(xmm11, Address(rsp, 88)); 114 __ movdbl(xmm12, Address(rsp, 96)); 115 __ movdbl(xmm13, Address(rsp, 104)); 116 __ movdbl(xmm14, Address(rsp, 112)); 117 __ movdbl(xmm15, Address(rsp, 120)); 118 __ addptr(rsp, 128); 119 120 if (dst != r15) { 121 __ pop(r15); 122 } 123 if (dst != r14) { 124 __ pop(r14); 125 } 126 if (dst != r13) { 127 __ pop(r13); 128 } 129 if (dst != r12) { 130 __ pop(r12); 131 } 132 if (dst != r11) { 133 __ pop(r11); 134 } 135 if (dst != r9) { 136 __ pop(r9); 137 } 138 if (dst != r8) { 139 __ pop(r8); 140 } 141 if (dst != rbp) { 142 __ pop(rbp); 143 } 144 if (dst != rsi) { 145 __ pop(rsi); 146 } 147 if (dst != rdi) { 148 __ pop(rdi); 149 } 150 if (dst != rdx) { 151 __ pop(rdx); 152 } 153 if (dst != rcx) { 154 __ pop(rcx); 155 } 156 if (dst != rbx) { 157 __ pop(rbx); 158 } 159 if (dst != rax) { 160 __ pop(rax); 161 } 162 163 __ mov(dst, rscratch1); 164 165 __ pop(rscratch1); 166 } 167 168 void ShenandoahBarrierSet::interpreter_read_barrier(MacroAssembler* masm, Register dst) { 169 if (ShenandoahReadBarrier) { 170 171 Label is_null; 172 __ testptr(dst, dst); 173 __ jcc(Assembler::zero, is_null); 174 interpreter_read_barrier_not_null(masm, dst); 175 __ bind(is_null); 176 } 177 } 178 179 void ShenandoahBarrierSet::interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst) { 180 if (ShenandoahReadBarrier) { 181 if (ShenandoahVerifyReadsToFromSpace) { 182 compile_resolve_oop_runtime(masm, dst); 183 return; 184 } 185 __ movptr(dst, Address(dst, BrooksPointer::byte_offset())); 186 } 187 } 188 189 void ShenandoahBarrierSet::interpreter_write_barrier(MacroAssembler* masm, Register dst) { 190 191 if (! ShenandoahWriteBarrier) { 192 return interpreter_read_barrier(masm, dst); 193 } 194 195 __ shenandoah_write_barrier(dst); 196 } 197 198 void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) { 199 Label done; 200 __ jccb(Assembler::equal, done); 201 interpreter_read_barrier(masm, op1); 202 interpreter_read_barrier(masm, op2); 203 __ cmpptr(op1, op2); 204 __ bind(done); 205 } 206 207 void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) { 208 __ incrementq(obj, BrooksPointer::byte_size()); 209 __ movptr(Address(obj, BrooksPointer::byte_offset()), obj); 210 } 211 #endif