src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp
changeset 58946 83810b7d12e7
parent 58819 ef8be51fff48
child 58985 5606867a5e6e
equal deleted inserted replaced
58945:a3b046720c3b 58946:83810b7d12e7
    21  *
    21  *
    22  */
    22  */
    23 
    23 
    24 #include "precompiled.hpp"
    24 #include "precompiled.hpp"
    25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
    25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
       
    26 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
    26 #include "gc/shenandoah/shenandoahForwarding.hpp"
    27 #include "gc/shenandoah/shenandoahForwarding.hpp"
    27 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
    28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
    28 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
    29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
    29 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    30 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    30 #include "gc/shenandoah/shenandoahRuntime.hpp"
    31 #include "gc/shenandoah/shenandoahRuntime.hpp"
   443     load_reference_barrier_not_null(masm, dst, src);
   444     load_reference_barrier_not_null(masm, dst, src);
   444     __ bind(done);
   445     __ bind(done);
   445   }
   446   }
   446 }
   447 }
   447 
   448 
       
   449 //
       
   450 // Arguments:
       
   451 //
       
   452 // Inputs:
       
   453 //   src:        oop location, might be clobbered
       
   454 //   tmp1:       scratch register, might not be valid.
       
   455 //
       
   456 // Output:
       
   457 //   dst:        oop loaded from src location
       
   458 //
       
   459 // Kill:
       
   460 //   tmp1 (if it is valid)
       
   461 //
   448 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
   462 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
   449              Register dst, Address src, Register tmp1, Register tmp_thread) {
   463              Register dst, Address src, Register tmp1, Register tmp_thread) {
   450   bool on_oop = is_reference_type(type);
   464   // 1: non-reference load, no additional barrier is needed
   451   bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
   465   if (!is_reference_type(type)) {
   452   bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
   466     BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
   453   bool not_in_heap = (decorators & IN_NATIVE) != 0;
   467     return;
   454   bool on_reference = on_weak || on_phantom;
   468   }
   455   bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
   469 
   456   bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
   470   // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set
   457 
   471   if (ShenandoahLoadRefBarrier) {
   458   Register result_dst = dst;
   472     Register result_dst = dst;
   459   bool use_tmp1_for_dst = false;
   473     bool use_tmp1_for_dst = false;
   460 
   474 
   461   if (on_oop) {
   475     // Preserve src location for LRB
   462     // We want to preserve src
       
   463     if (dst == src.base() || dst == src.index()) {
   476     if (dst == src.base() || dst == src.index()) {
   464       // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
   477       // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
   465       if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
   478       if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
   466         dst = tmp1;
   479         dst = tmp1;
   467         use_tmp1_for_dst = true;
   480         use_tmp1_for_dst = true;
   468       } else {
   481       } else {
   469         dst = rdi;
   482         dst = rdi;
   470         __ push(dst);
   483         __ push(dst);
   471       }
   484       }
   472     }
   485       assert_different_registers(dst, src.base(), src.index());
   473     assert_different_registers(dst, src.base(), src.index());
   486     }
   474   }
   487 
   475 
   488     BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
   476   BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
   489 
   477 
   490     // Native barrier is for concurrent root processing
   478   if (on_oop) {
   491     bool in_native = (decorators & IN_NATIVE) != 0;
   479     if (not_in_heap && !is_traversal_mode) {
   492     if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
   480       load_reference_barrier_native(masm, dst, src);
   493       load_reference_barrier_native(masm, dst, src);
   481     } else {
   494     } else {
   482       load_reference_barrier(masm, dst, src);
   495       load_reference_barrier(masm, dst, src);
   483     }
   496     }
   484 
   497 
       
   498     // Move loaded oop to final destination
   485     if (dst != result_dst) {
   499     if (dst != result_dst) {
   486       __ movptr(result_dst, dst);
   500       __ movptr(result_dst, dst);
   487 
   501 
   488       if (!use_tmp1_for_dst) {
   502       if (!use_tmp1_for_dst) {
   489         __ pop(dst);
   503         __ pop(dst);
   490       }
   504       }
   491 
   505 
   492       dst = result_dst;
   506       dst = result_dst;
   493     }
   507     }
   494 
   508   } else {
   495     if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
   509     BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
       
   510   }
       
   511 
       
   512   // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
       
   513   if (ShenandoahKeepAliveBarrier) {
       
   514     bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
       
   515     bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
       
   516     bool on_reference = on_weak || on_phantom;
       
   517     bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
       
   518     bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
       
   519 
       
   520     if (on_reference && keep_alive) {
   496       const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
   521       const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
   497       assert_different_registers(dst, tmp1, tmp_thread);
   522       assert_different_registers(dst, tmp1, tmp_thread);
   498       NOT_LP64(__ get_thread(thread));
   523       NOT_LP64(__ get_thread(thread));
   499       // Generate the SATB pre-barrier code to log the value of
   524       // Generate the SATB pre-barrier code to log the value of
   500       // the referent field in an SATB buffer.
   525       // the referent field in an SATB buffer.