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 assert(dst != rscratch1, "different regs");
196 //assert(dst != rscratch2, "Need rscratch2");
197
198 Label done;
199
200 Address evacuation_in_progress = Address(r15_thread, in_bytes(JavaThread::evacuation_in_progress_offset()));
201
202 __ cmpb(evacuation_in_progress, 0);
203
204 // Now check if evacuation is in progress.
205 interpreter_read_barrier_not_null(masm, dst);
206
207 __ jcc(Assembler::equal, done);
208 __ push(rscratch1);
209 __ push(rscratch2);
210
211 __ movptr(rscratch1, dst);
212 __ shrptr(rscratch1, ShenandoahHeapRegion::RegionSizeShift);
213 __ movptr(rscratch2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
214 __ movbool(rscratch2, Address(rscratch2, rscratch1, Address::times_1));
215 __ testb(rscratch2, 0x1);
216
217 __ pop(rscratch2);
218 __ pop(rscratch1);
219
220 __ jcc(Assembler::zero, done);
221
222 __ push(rscratch1);
223
224 // Save possibly live regs.
225 if (dst != rax) {
226 __ push(rax);
227 }
228 if (dst != rbx) {
229 __ push(rbx);
230 }
231 if (dst != rcx) {
232 __ push(rcx);
233 }
234 if (dst != rdx) {
235 __ push(rdx);
236 }
237 if (dst != c_rarg1) {
238 __ push(c_rarg1);
239 }
240
241 __ subptr(rsp, 2 * wordSize);
242 __ movdbl(Address(rsp, 0), xmm0);
243
244 // Call into runtime
245 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_interp), dst);
246 __ mov(rscratch1, rax);
247
248 // Restore possibly live regs.
249 __ movdbl(xmm0, Address(rsp, 0));
250 __ addptr(rsp, 2 * Interpreter::stackElementSize);
251
252 if (dst != c_rarg1) {
253 __ pop(c_rarg1);
254 }
255 if (dst != rdx) {
256 __ pop(rdx);
257 }
258 if (dst != rcx) {
259 __ pop(rcx);
260 }
261 if (dst != rbx) {
262 __ pop(rbx);
263 }
264 if (dst != rax) {
265 __ pop(rax);
266 }
267
268 // Move result into dst reg.
269 __ mov(dst, rscratch1);
270
271 __ pop(rscratch1);
272
273 __ bind(done);
274 }
275
276 void ShenandoahBarrierSet::asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2) {
277 Label done;
278 __ jccb(Assembler::equal, done);
279 interpreter_read_barrier(masm, op1);
280 interpreter_read_barrier(masm, op2);
281 __ cmpptr(op1, op2);
282 __ bind(done);
283 }
284
285 void ShenandoahHeap::compile_prepare_oop(MacroAssembler* masm, Register obj) {
286 __ incrementq(obj, BrooksPointer::byte_size());
287 __ movptr(Address(obj, BrooksPointer::byte_offset()), obj);
288 }
289 #endif
|
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
|