src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
changeset 52424 e3d79743f57d
parent 52224 4f2215a00ed1
child 52426 38bf0c9c4e64
equal deleted inserted replaced
52423:00db205006c9 52424:e3d79743f57d
    47 const DecoratorSet C2_UNSAFE_ACCESS          = DECORATOR_LAST << 6;
    47 const DecoratorSet C2_UNSAFE_ACCESS          = DECORATOR_LAST << 6;
    48 // This denotes that the access mutates state.
    48 // This denotes that the access mutates state.
    49 const DecoratorSet C2_WRITE_ACCESS           = DECORATOR_LAST << 7;
    49 const DecoratorSet C2_WRITE_ACCESS           = DECORATOR_LAST << 7;
    50 // This denotes that the access reads state.
    50 // This denotes that the access reads state.
    51 const DecoratorSet C2_READ_ACCESS            = DECORATOR_LAST << 8;
    51 const DecoratorSet C2_READ_ACCESS            = DECORATOR_LAST << 8;
       
    52 // A nearby allocation?
       
    53 const DecoratorSet C2_TIGHLY_COUPLED_ALLOC   = DECORATOR_LAST << 9;
       
    54 // Loads and stores from an arraycopy being optimized
       
    55 const DecoratorSet C2_ARRAY_COPY             = DECORATOR_LAST << 10;
    52 
    56 
    53 class GraphKit;
    57 class GraphKit;
    54 class IdealKit;
    58 class IdealKit;
    55 class Node;
    59 class Node;
    56 class Type;
    60 class Type;
    86 
    90 
    87 // This class wraps a bunch of context parameters thare are passed around in the
    91 // This class wraps a bunch of context parameters thare are passed around in the
    88 // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate.
    92 // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate.
    89 class C2Access: public StackObj {
    93 class C2Access: public StackObj {
    90 protected:
    94 protected:
    91   GraphKit*         _kit;
       
    92   DecoratorSet      _decorators;
    95   DecoratorSet      _decorators;
    93   BasicType         _type;
    96   BasicType         _type;
    94   Node*             _base;
    97   Node*             _base;
    95   C2AccessValuePtr& _addr;
    98   C2AccessValuePtr& _addr;
    96   Node*             _raw_access;
    99   Node*             _raw_access;
    97 
   100 
    98   void fixup_decorators();
   101   void fixup_decorators();
    99   void* barrier_set_state() const;
   102 
   100 
   103 public:
   101 public:
   104   C2Access(DecoratorSet decorators,
   102   C2Access(GraphKit* kit, DecoratorSet decorators,
       
   103            BasicType type, Node* base, C2AccessValuePtr& addr) :
   105            BasicType type, Node* base, C2AccessValuePtr& addr) :
   104     _kit(kit),
       
   105     _decorators(decorators),
   106     _decorators(decorators),
   106     _type(type),
   107     _type(type),
   107     _base(base),
   108     _base(base),
   108     _addr(addr),
   109     _addr(addr),
   109     _raw_access(NULL)
   110     _raw_access(NULL)
   110   {
   111   {}
   111     fixup_decorators();
   112 
   112   }
       
   113 
       
   114   GraphKit* kit() const           { return _kit; }
       
   115   DecoratorSet decorators() const { return _decorators; }
   113   DecoratorSet decorators() const { return _decorators; }
   116   Node* base() const              { return _base; }
   114   Node* base() const              { return _base; }
   117   C2AccessValuePtr& addr() const  { return _addr; }
   115   C2AccessValuePtr& addr() const  { return _addr; }
   118   BasicType type() const          { return _type; }
   116   BasicType type() const          { return _type; }
   119   bool is_oop() const             { return _type == T_OBJECT || _type == T_ARRAY; }
   117   bool is_oop() const             { return _type == T_OBJECT || _type == T_ARRAY; }
   124   virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses.
   122   virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses.
   125 
   123 
   126   MemNode::MemOrd mem_node_mo() const;
   124   MemNode::MemOrd mem_node_mo() const;
   127   bool needs_cpu_membar() const;
   125   bool needs_cpu_membar() const;
   128 
   126 
       
   127   virtual PhaseGVN& gvn() const = 0;
       
   128   virtual bool is_parse_access() const { return false; }
       
   129   virtual bool is_opt_access() const { return false; }
       
   130 };
       
   131 
       
   132 // C2Access for parse time calls to the BarrierSetC2 backend.
       
   133 class C2ParseAccess: public C2Access {
       
   134 protected:
       
   135   GraphKit*         _kit;
       
   136 
       
   137   void* barrier_set_state() const;
       
   138 
       
   139 public:
       
   140   C2ParseAccess(GraphKit* kit, DecoratorSet decorators,
       
   141                 BasicType type, Node* base, C2AccessValuePtr& addr) :
       
   142     C2Access(decorators, type, base, addr),
       
   143     _kit(kit) {
       
   144     fixup_decorators();
       
   145   }
       
   146 
       
   147   GraphKit* kit() const           { return _kit; }
       
   148 
   129   template <typename T>
   149   template <typename T>
   130   T barrier_set_state_as() const {
   150   T barrier_set_state_as() const {
   131     return reinterpret_cast<T>(barrier_set_state());
   151     return reinterpret_cast<T>(barrier_set_state());
   132   }
   152   }
       
   153 
       
   154   virtual PhaseGVN& gvn() const;
       
   155   virtual bool is_parse_access() const { return true; }
   133 };
   156 };
   134 
   157 
   135 // This class wraps a bunch of context parameters thare are passed around in the
   158 // This class wraps a bunch of context parameters thare are passed around in the
   136 // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate.
   159 // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate.
   137 class C2AtomicAccess: public C2Access {
   160 class C2AtomicParseAccess: public C2ParseAccess {
   138   Node* _memory;
   161   Node* _memory;
   139   uint  _alias_idx;
   162   uint  _alias_idx;
   140   bool  _needs_pinning;
   163   bool  _needs_pinning;
   141 
   164 
   142 public:
   165 public:
   143   C2AtomicAccess(GraphKit* kit, DecoratorSet decorators, BasicType type,
   166   C2AtomicParseAccess(GraphKit* kit, DecoratorSet decorators, BasicType type,
   144                  Node* base, C2AccessValuePtr& addr, uint alias_idx) :
   167                  Node* base, C2AccessValuePtr& addr, uint alias_idx) :
   145     C2Access(kit, decorators, type, base, addr),
   168     C2ParseAccess(kit, decorators, type, base, addr),
   146     _memory(NULL),
   169     _memory(NULL),
   147     _alias_idx(alias_idx),
   170     _alias_idx(alias_idx),
   148     _needs_pinning(true) {}
   171     _needs_pinning(true) {}
   149 
   172 
   150   // Set the memory node based on the current memory slice.
   173   // Set the memory node based on the current memory slice.
   154   uint alias_idx() const     { return _alias_idx; }
   177   uint alias_idx() const     { return _alias_idx; }
   155   bool needs_pinning() const { return _needs_pinning; }
   178   bool needs_pinning() const { return _needs_pinning; }
   156 
   179 
   157   void set_needs_pinning(bool value)    { _needs_pinning = value; }
   180   void set_needs_pinning(bool value)    { _needs_pinning = value; }
   158 };
   181 };
       
   182 
       
   183 // C2Access for optimization time calls to the BarrierSetC2 backend.
       
   184 class C2OptAccess: public C2Access {
       
   185   PhaseGVN& _gvn;
       
   186   MergeMemNode* _mem;
       
   187   Node* _ctl;
       
   188 
       
   189 public:
       
   190   C2OptAccess(PhaseGVN& gvn, Node* ctl, MergeMemNode* mem, DecoratorSet decorators,
       
   191               BasicType type, Node* base, C2AccessValuePtr& addr) :
       
   192     C2Access(decorators, type, base, addr),
       
   193     _gvn(gvn), _mem(mem), _ctl(ctl) {
       
   194     fixup_decorators();
       
   195   }
       
   196 
       
   197 
       
   198   MergeMemNode* mem() const { return _mem; }
       
   199   Node* ctl() const { return _ctl; }
       
   200   // void set_mem(Node* mem) { _mem = mem; }
       
   201   void set_ctl(Node* ctl) { _ctl = ctl; }
       
   202 
       
   203   virtual PhaseGVN& gvn() const { return _gvn; }
       
   204   virtual bool is_opt_access() const { return true; }
       
   205 };
       
   206 
   159 
   207 
   160 // This is the top-level class for the backend of the Access API in C2.
   208 // This is the top-level class for the backend of the Access API in C2.
   161 // The top-level class is responsible for performing raw accesses. The
   209 // The top-level class is responsible for performing raw accesses. The
   162 // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle
   210 // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle
   163 // barriers into the accesses.
   211 // barriers into the accesses.
   165 protected:
   213 protected:
   166   virtual void resolve_address(C2Access& access) const;
   214   virtual void resolve_address(C2Access& access) const;
   167   virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const;
   215   virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const;
   168   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
   216   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
   169 
   217 
   170   virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val,
   218   virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
   171                                                Node* new_val, const Type* val_type) const;
   219                                                Node* new_val, const Type* val_type) const;
   172   virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val,
   220   virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
   173                                                 Node* new_val, const Type* value_type) const;
   221                                                 Node* new_val, const Type* value_type) const;
   174   virtual Node* atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const;
   222   virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const;
   175   virtual Node* atomic_add_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const;
   223   virtual Node* atomic_add_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const;
   176   void pin_atomic_op(C2AtomicAccess& access) const;
   224   void pin_atomic_op(C2AtomicParseAccess& access) const;
   177 
   225 
   178 public:
   226 public:
   179   // This is the entry-point for the backend to perform accesses through the Access API.
   227   // This is the entry-point for the backend to perform accesses through the Access API.
   180   virtual Node* store_at(C2Access& access, C2AccessValue& val) const;
   228   virtual Node* store_at(C2Access& access, C2AccessValue& val) const;
   181   virtual Node* load_at(C2Access& access, const Type* val_type) const;
   229   virtual Node* load_at(C2Access& access, const Type* val_type) const;
   182 
   230 
   183   virtual Node* atomic_cmpxchg_val_at(C2AtomicAccess& access, Node* expected_val,
   231   virtual Node* atomic_cmpxchg_val_at(C2AtomicParseAccess& access, Node* expected_val,
   184                                       Node* new_val, const Type* val_type) const;
   232                                       Node* new_val, const Type* val_type) const;
   185   virtual Node* atomic_cmpxchg_bool_at(C2AtomicAccess& access, Node* expected_val,
   233   virtual Node* atomic_cmpxchg_bool_at(C2AtomicParseAccess& access, Node* expected_val,
   186                                        Node* new_val, const Type* val_type) const;
   234                                        Node* new_val, const Type* val_type) const;
   187   virtual Node* atomic_xchg_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const;
   235   virtual Node* atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const;
   188   virtual Node* atomic_add_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const;
   236   virtual Node* atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const;
   189 
   237 
   190   virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const;
   238   virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const;
   191 
   239 
   192   virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; }
   240   virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; }
   193 
   241 
   201     Parsing,
   249     Parsing,
   202     Optimization,
   250     Optimization,
   203     Expansion
   251     Expansion
   204   };
   252   };
   205   virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return false; }
   253   virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return false; }
       
   254   virtual void clone_barrier_at_expansion(ArrayCopyNode* ac, Node* call, PhaseIterGVN& igvn) const;
   206 
   255 
   207   // Support for GC barriers emitted during parsing
   256   // Support for GC barriers emitted during parsing
   208   virtual bool has_load_barriers() const { return false; }
   257   virtual bool has_load_barriers() const { return false; }
   209   virtual bool is_gc_barrier_node(Node* node) const { return false; }
   258   virtual bool is_gc_barrier_node(Node* node) const { return false; }
   210   virtual Node* step_over_gc_barrier(Node* c) const { return c; }
   259   virtual Node* step_over_gc_barrier(Node* c) const { return c; }