260 |
260 |
261 __ bind(done); |
261 __ bind(done); |
262 __ leave(); |
262 __ leave(); |
263 } |
263 } |
264 |
264 |
265 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Register tmp) { |
265 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr) { |
266 if (!ShenandoahLoadRefBarrier) { |
266 if (!ShenandoahLoadRefBarrier) { |
267 return; |
267 return; |
268 } |
268 } |
269 |
269 |
270 assert(dst != rscratch2, "need rscratch2"); |
270 assert(dst != rscratch2, "need rscratch2"); |
271 |
271 |
272 Label is_null; |
272 Label is_null; |
273 Label done; |
273 Label done; |
|
274 |
|
275 __ block_comment("load_reference_barrier_native { "); |
274 |
276 |
275 __ cbz(dst, is_null); |
277 __ cbz(dst, is_null); |
276 |
278 |
277 __ enter(); |
279 __ enter(); |
278 |
280 |
283 __ tbz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, done); |
285 __ tbz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, done); |
284 |
286 |
285 __ mov(rscratch2, dst); |
287 __ mov(rscratch2, dst); |
286 __ push_call_clobbered_registers(); |
288 __ push_call_clobbered_registers(); |
287 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); |
289 __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); |
|
290 __ lea(r1, load_addr); |
288 __ mov(r0, rscratch2); |
291 __ mov(r0, rscratch2); |
289 __ blr(lr); |
292 __ blr(lr); |
290 __ mov(rscratch2, r0); |
293 __ mov(rscratch2, r0); |
291 __ pop_call_clobbered_registers(); |
294 __ pop_call_clobbered_registers(); |
292 __ mov(dst, rscratch2); |
295 __ mov(dst, rscratch2); |
293 |
296 |
294 __ bind(done); |
297 __ bind(done); |
295 __ leave(); |
298 __ leave(); |
296 __ bind(is_null); |
299 __ bind(is_null); |
|
300 __ block_comment("} load_reference_barrier_native"); |
297 } |
301 } |
298 |
302 |
299 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { |
303 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { |
300 if (ShenandoahStoreValEnqueueBarrier) { |
304 if (ShenandoahStoreValEnqueueBarrier) { |
301 // Save possibly live regs. |
305 // Save possibly live regs. |
325 bool on_oop = is_reference_type(type); |
329 bool on_oop = is_reference_type(type); |
326 bool not_in_heap = (decorators & IN_NATIVE) != 0; |
330 bool not_in_heap = (decorators & IN_NATIVE) != 0; |
327 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
331 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
328 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
332 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
329 bool on_reference = on_weak || on_phantom; |
333 bool on_reference = on_weak || on_phantom; |
330 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0; |
334 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
|
335 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
|
336 |
|
337 Register result_dst = dst; |
|
338 |
|
339 if (on_oop) { |
|
340 // We want to preserve src |
|
341 if (dst == src.base() || dst == src.index()) { |
|
342 dst = rscratch1; |
|
343 } |
|
344 assert_different_registers(dst, src.base(), src.index()); |
|
345 } |
331 |
346 |
332 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
347 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
333 if (on_oop) { |
348 if (on_oop) { |
334 if (not_in_heap) { |
349 if (not_in_heap && !is_traversal_mode) { |
335 if (ShenandoahHeap::heap()->is_traversal_mode()) { |
350 load_reference_barrier_native(masm, dst, src); |
336 load_reference_barrier(masm, dst, tmp1); |
351 } else { |
337 keep_alive = true; |
352 load_reference_barrier(masm, dst, tmp1); |
338 } else { |
353 } |
339 load_reference_barrier_native(masm, dst, tmp1); |
354 |
340 } |
355 if (dst != result_dst) { |
341 } else { |
356 __ mov(result_dst, dst); |
342 load_reference_barrier(masm, dst, tmp1); |
357 dst = result_dst; |
343 } |
358 } |
|
359 |
344 if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { |
360 if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { |
345 __ enter(); |
361 __ enter(); |
346 satb_write_barrier_pre(masm /* masm */, |
362 satb_write_barrier_pre(masm /* masm */, |
347 noreg /* obj */, |
363 noreg /* obj */, |
348 dst /* pre_val */, |
364 dst /* pre_val */, |