src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
changeset 58946 83810b7d12e7
parent 58819 ef8be51fff48
child 58962 2dcfc28a314d
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/shared/barrierSet.hpp"
    25 #include "gc/shared/barrierSet.hpp"
       
    26 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
    26 #include "gc/shenandoah/shenandoahForwarding.hpp"
    27 #include "gc/shenandoah/shenandoahForwarding.hpp"
    27 #include "gc/shenandoah/shenandoahHeap.hpp"
    28 #include "gc/shenandoah/shenandoahHeap.hpp"
    28 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    29 #include "gc/shenandoah/shenandoahHeuristics.hpp"
    29 #include "gc/shenandoah/shenandoahRuntime.hpp"
    30 #include "gc/shenandoah/shenandoahRuntime.hpp"
    30 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
    31 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
   532   }
   533   }
   533   return BarrierSetC2::store_at_resolved(access, val);
   534   return BarrierSetC2::store_at_resolved(access, val);
   534 }
   535 }
   535 
   536 
   536 Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
   537 Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
       
   538   // 1: non-reference load, no additional barrier is needed
       
   539   if (!access.is_oop()) {
       
   540     return BarrierSetC2::load_at_resolved(access, val_type);;
       
   541   }
       
   542 
       
   543   Node* load = BarrierSetC2::load_at_resolved(access, val_type);
   537   DecoratorSet decorators = access.decorators();
   544   DecoratorSet decorators = access.decorators();
   538 
       
   539   Node* adr = access.addr().node();
       
   540   Node* obj = access.base();
       
   541 
       
   542   bool mismatched = (decorators & C2_MISMATCHED) != 0;
       
   543   bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0;
       
   544   bool on_heap = (decorators & IN_HEAP) != 0;
       
   545   bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0;
       
   546   bool is_unordered = (decorators & MO_UNORDERED) != 0;
       
   547   bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap;
       
   548   bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
       
   549   bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode;
       
   550   bool in_native = (decorators & IN_NATIVE) != 0;
   545   bool in_native = (decorators & IN_NATIVE) != 0;
   551 
   546 
   552   Node* top = Compile::current()->top();
   547   // 2: apply LRB if ShenandoahLoadRefBarrier is set
   553 
   548   if (ShenandoahLoadRefBarrier) {
   554   Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top;
   549     // Native barrier is for concurrent root processing
   555   Node* load = BarrierSetC2::load_at_resolved(access, val_type);
   550     bool use_native_barrier = in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots();
   556 
   551     load = new ShenandoahLoadReferenceBarrierNode(NULL, load, use_native_barrier);
   557   if (access.is_oop()) {
   552     if (access.is_parse_access()) {
   558     if (ShenandoahLoadRefBarrier) {
   553       load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
   559       load = new ShenandoahLoadReferenceBarrierNode(NULL, load, in_native && !is_traversal_mode);
   554     } else {
   560       if (access.is_parse_access()) {
   555       load = static_cast<C2OptAccess &>(access).gvn().transform(load);
   561         load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
   556     }
   562       } else {
   557   }
   563         load = static_cast<C2OptAccess &>(access).gvn().transform(load);
   558 
   564       }
   559   // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
   565     }
   560   if (ShenandoahKeepAliveBarrier) {
   566   }
   561     Node* top = Compile::current()->top();
   567 
   562     Node* adr = access.addr().node();
   568   // If we are reading the value of the referent field of a Reference
   563     Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top;
   569   // object (either by using Unsafe directly or through reflection)
   564     Node* obj = access.base();
   570   // then, if SATB is enabled, we need to record the referent in an
   565 
   571   // SATB log buffer using the pre-barrier mechanism.
   566     bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0;
   572   // Also we need to add memory barrier to prevent commoning reads
   567     bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0;
   573   // from this field across safepoint since GC can change its value.
   568     bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
   574   bool need_read_barrier = ShenandoahKeepAliveBarrier &&
   569     bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode;
   575     (on_weak_ref || (unknown && offset != top && obj != top));
   570 
   576 
   571     // If we are reading the value of the referent field of a Reference
   577   if (!access.is_oop() || !need_read_barrier) {
   572     // object (either by using Unsafe directly or through reflection)
   578     return load;
   573     // then, if SATB is enabled, we need to record the referent in an
   579   }
   574     // SATB log buffer using the pre-barrier mechanism.
   580 
   575     // Also we need to add memory barrier to prevent commoning reads
   581   assert(access.is_parse_access(), "entry not supported at optimization time");
   576     // from this field across safepoint since GC can change its value.
   582   C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
   577     if (!on_weak_ref || (unknown && (offset == top || obj == top)) || !keep_alive) {
   583   GraphKit* kit = parse_access.kit();
   578       return load;
   584 
   579     }
   585   if (on_weak_ref && keep_alive) {
   580 
   586     // Use the pre-barrier to record the value in the referent field
   581     assert(access.is_parse_access(), "entry not supported at optimization time");
   587     satb_write_barrier_pre(kit, false /* do_load */,
   582     C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);
   588                            NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */,
   583     GraphKit* kit = parse_access.kit();
   589                            load /* pre_val */, T_OBJECT);
   584     bool mismatched = (decorators & C2_MISMATCHED) != 0;
   590     // Add memory barrier to prevent commoning reads from this field
   585     bool is_unordered = (decorators & MO_UNORDERED) != 0;
   591     // across safepoint since GC can change its value.
   586     bool need_cpu_mem_bar = !is_unordered || mismatched || in_native;
   592     kit->insert_mem_bar(Op_MemBarCPUOrder);
   587 
   593   } else if (unknown) {
   588     if (on_weak_ref) {
   594     // We do not require a mem bar inside pre_barrier if need_mem_bar
   589       // Use the pre-barrier to record the value in the referent field
   595     // is set: the barriers would be emitted by us.
   590       satb_write_barrier_pre(kit, false /* do_load */,
   596     insert_pre_barrier(kit, obj, offset, load, !need_cpu_mem_bar);
   591                              NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */,
       
   592                              load /* pre_val */, T_OBJECT);
       
   593       // Add memory barrier to prevent commoning reads from this field
       
   594       // across safepoint since GC can change its value.
       
   595       kit->insert_mem_bar(Op_MemBarCPUOrder);
       
   596     } else if (unknown) {
       
   597       // We do not require a mem bar inside pre_barrier if need_mem_bar
       
   598       // is set: the barriers would be emitted by us.
       
   599       insert_pre_barrier(kit, obj, offset, load, !need_cpu_mem_bar);
       
   600     }
   597   }
   601   }
   598 
   602 
   599   return load;
   603   return load;
   600 }
   604 }
   601 
   605