20 * questions. |
20 * questions. |
21 * |
21 * |
22 */ |
22 */ |
23 |
23 |
24 #include "precompiled.hpp" |
24 #include "precompiled.hpp" |
|
25 #include "gc/shenandoah/shenandoahBarrierSet.hpp" |
25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" |
26 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" |
26 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp" |
|
27 #include "gc/shenandoah/shenandoahForwarding.hpp" |
27 #include "gc/shenandoah/shenandoahForwarding.hpp" |
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp" |
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp" |
30 #include "gc/shenandoah/shenandoahHeuristics.hpp" |
30 #include "gc/shenandoah/shenandoahHeuristics.hpp" |
31 #include "gc/shenandoah/shenandoahRuntime.hpp" |
31 #include "gc/shenandoah/shenandoahRuntime.hpp" |
368 if (!is_reference_type(type)) { |
368 if (!is_reference_type(type)) { |
369 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
369 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
370 return; |
370 return; |
371 } |
371 } |
372 |
372 |
373 // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set |
373 // 2: load a reference from src location and apply LRB if needed |
374 if (ShenandoahLoadRefBarrier) { |
374 if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { |
375 Register result_dst = dst; |
375 Register result_dst = dst; |
376 |
376 |
377 // Preserve src location for LRB |
377 // Preserve src location for LRB |
378 if (dst == src.base() || dst == src.index()) { |
378 if (dst == src.base() || dst == src.index()) { |
379 dst = rscratch1; |
379 dst = rscratch1; |
380 } |
380 } |
381 assert_different_registers(dst, src.base(), src.index()); |
381 assert_different_registers(dst, src.base(), src.index()); |
382 |
382 |
383 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
383 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
384 |
384 |
385 // Native barrier is for concurrent root processing |
385 if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) { |
386 bool in_native = (decorators & IN_NATIVE) != 0; |
|
387 if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { |
|
388 load_reference_barrier_native(masm, dst, src); |
386 load_reference_barrier_native(masm, dst, src); |
389 } else { |
387 } else { |
390 load_reference_barrier(masm, dst, src); |
388 load_reference_barrier(masm, dst, src); |
391 } |
389 } |
392 |
390 |
396 } |
394 } |
397 } else { |
395 } else { |
398 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
396 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); |
399 } |
397 } |
400 |
398 |
401 // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set |
399 // 3: apply keep-alive barrier if needed |
402 if (ShenandoahKeepAliveBarrier) { |
400 if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { |
403 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
401 __ enter(); |
404 bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
402 satb_write_barrier_pre(masm /* masm */, |
405 bool on_reference = on_weak || on_phantom; |
403 noreg /* obj */, |
406 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
404 dst /* pre_val */, |
407 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
405 rthread /* thread */, |
408 |
406 tmp1 /* tmp */, |
409 if (on_reference && keep_alive) { |
407 true /* tosca_live */, |
410 __ enter(); |
408 true /* expand_call */); |
411 satb_write_barrier_pre(masm /* masm */, |
409 __ leave(); |
412 noreg /* obj */, |
|
413 dst /* pre_val */, |
|
414 rthread /* thread */, |
|
415 tmp1 /* tmp */, |
|
416 true /* tosca_live */, |
|
417 true /* expand_call */); |
|
418 __ leave(); |
|
419 } |
|
420 } |
410 } |
421 } |
411 } |
422 |
412 |
423 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
413 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
424 Address dst, Register val, Register tmp1, Register tmp2) { |
414 Address dst, Register val, Register tmp1, Register tmp2) { |