344 load_reference_barrier_not_null(masm, dst, load_addr); |
345 load_reference_barrier_not_null(masm, dst, load_addr); |
345 __ bind(is_null); |
346 __ bind(is_null); |
346 } |
347 } |
347 } |
348 } |
348 |
349 |
|
350 // |
|
351 // Arguments: |
|
352 // |
|
353 // Inputs: |
|
354 // src: oop location to load from, might be clobbered |
|
355 // |
|
356 // Output: |
|
357 // dst: oop loaded from src location |
|
358 // |
|
359 // Kill: |
|
360 // rscratch1 (scratch reg) |
|
361 // |
|
362 // Alias: |
|
363 // dst: rscratch1 (might use rscratch1 as temporary output register to avoid clobbering src) |
|
364 // |
349 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
365 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
350 Register dst, Address src, Register tmp1, Register tmp_thread) { |
366 Register dst, Address src, Register tmp1, Register tmp_thread) { |
351 bool on_oop = is_reference_type(type); |
367 // 1: non-reference load, no additional barrier is needed |
352 bool not_in_heap = (decorators & IN_NATIVE) != 0; |
368 if (!is_reference_type(type)) { |
353 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
369 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
354 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
370 return; |
355 bool on_reference = on_weak || on_phantom; |
371 } |
356 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
372 |
357 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
373 // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set |
358 |
374 if (ShenandoahLoadRefBarrier) { |
359 Register result_dst = dst; |
375 Register result_dst = dst; |
360 |
376 |
361 if (on_oop) { |
377 // Preserve src location for LRB |
362 // We want to preserve src |
|
363 if (dst == src.base() || dst == src.index()) { |
378 if (dst == src.base() || dst == src.index()) { |
364 dst = rscratch1; |
379 dst = rscratch1; |
365 } |
380 } |
366 assert_different_registers(dst, src.base(), src.index()); |
381 assert_different_registers(dst, src.base(), src.index()); |
367 } |
382 |
368 |
383 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
369 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
384 |
370 if (on_oop) { |
385 // Native barrier is for concurrent root processing |
371 if (not_in_heap && !is_traversal_mode) { |
386 bool in_native = (decorators & IN_NATIVE) != 0; |
|
387 if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { |
372 load_reference_barrier_native(masm, dst, src); |
388 load_reference_barrier_native(masm, dst, src); |
373 } else { |
389 } else { |
374 load_reference_barrier(masm, dst, src); |
390 load_reference_barrier(masm, dst, src); |
375 } |
391 } |
376 |
392 |
377 if (dst != result_dst) { |
393 if (dst != result_dst) { |
378 __ mov(result_dst, dst); |
394 __ mov(result_dst, dst); |
379 dst = result_dst; |
395 dst = result_dst; |
380 } |
396 } |
381 |
397 } else { |
382 if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { |
398 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
|
399 } |
|
400 |
|
401 // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set |
|
402 if (ShenandoahKeepAliveBarrier) { |
|
403 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
|
404 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
|
405 bool on_reference = on_weak || on_phantom; |
|
406 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
|
407 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
|
408 |
|
409 if (on_reference && keep_alive) { |
383 __ enter(); |
410 __ enter(); |
384 satb_write_barrier_pre(masm /* masm */, |
411 satb_write_barrier_pre(masm /* masm */, |
385 noreg /* obj */, |
412 noreg /* obj */, |
386 dst /* pre_val */, |
413 dst /* pre_val */, |
387 rthread /* thread */, |
414 rthread /* thread */, |