< prev index next >

src/hotspot/share/gc/shared/c2/barrierSetC2.hpp

Print this page

        

*** 47,56 **** --- 47,60 ---- const DecoratorSet C2_UNSAFE_ACCESS = DECORATOR_LAST << 6; // This denotes that the access mutates state. const DecoratorSet C2_WRITE_ACCESS = DECORATOR_LAST << 7; // This denotes that the access reads state. const DecoratorSet C2_READ_ACCESS = DECORATOR_LAST << 8; + // A nearby allocation? + const DecoratorSet C2_TIGHLY_COUPLED_ALLOC = DECORATOR_LAST << 9; + // Loads and stores from an arraycopy being optimized + const DecoratorSet C2_ARRAY_COPY = DECORATOR_LAST << 10; class GraphKit; class IdealKit; class Node; class Type;
*** 86,119 **** // This class wraps a bunch of context parameters thare are passed around in the // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate. class C2Access: public StackObj { protected: - GraphKit* _kit; DecoratorSet _decorators; BasicType _type; Node* _base; C2AccessValuePtr& _addr; Node* _raw_access; void fixup_decorators(); - void* barrier_set_state() const; public: ! C2Access(GraphKit* kit, DecoratorSet decorators, BasicType type, Node* base, C2AccessValuePtr& addr) : - _kit(kit), _decorators(decorators), _type(type), _base(base), _addr(addr), _raw_access(NULL) ! { ! fixup_decorators(); ! } - GraphKit* kit() const { return _kit; } DecoratorSet decorators() const { return _decorators; } Node* base() const { return _base; } C2AccessValuePtr& addr() const { return _addr; } BasicType type() const { return _type; } bool is_oop() const { return _type == T_OBJECT || _type == T_ARRAY; } --- 90,117 ---- // This class wraps a bunch of context parameters thare are passed around in the // BarrierSetC2 backend hierarchy, for loads and stores, to reduce boiler plate. class C2Access: public StackObj { protected: DecoratorSet _decorators; BasicType _type; Node* _base; C2AccessValuePtr& _addr; Node* _raw_access; void fixup_decorators(); public: ! C2Access(DecoratorSet decorators, BasicType type, Node* base, C2AccessValuePtr& addr) : _decorators(decorators), _type(type), _base(base), _addr(addr), _raw_access(NULL) ! {} DecoratorSet decorators() const { return _decorators; } Node* base() const { return _base; } C2AccessValuePtr& addr() const { return _addr; } BasicType type() const { return _type; } bool is_oop() const { return _type == T_OBJECT || _type == T_ARRAY; }
*** 124,150 **** virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses. MemNode::MemOrd mem_node_mo() const; bool needs_cpu_membar() const; template <typename T> T barrier_set_state_as() const { return reinterpret_cast<T>(barrier_set_state()); } }; // This class wraps a bunch of context parameters thare are passed around in the // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate. ! class C2AtomicAccess: public C2Access { Node* _memory; uint _alias_idx; bool _needs_pinning; public: ! C2AtomicAccess(GraphKit* kit, DecoratorSet decorators, BasicType type, Node* base, C2AccessValuePtr& addr, uint alias_idx) : ! C2Access(kit, decorators, type, base, addr), _memory(NULL), _alias_idx(alias_idx), _needs_pinning(true) {} // Set the memory node based on the current memory slice. --- 122,173 ---- virtual void set_memory() {} // no-op for normal accesses, but not for atomic accesses. MemNode::MemOrd mem_node_mo() const; bool needs_cpu_membar() const; + virtual PhaseGVN& gvn() const = 0; + virtual bool is_parse_access() const { return false; } + virtual bool is_opt_access() const { return false; } + }; + + // C2Access for parse time calls to the BarrierSetC2 backend. + class C2ParseAccess: public C2Access { + protected: + GraphKit* _kit; + + void* barrier_set_state() const; + + public: + C2ParseAccess(GraphKit* kit, DecoratorSet decorators, + BasicType type, Node* base, C2AccessValuePtr& addr) : + C2Access(decorators, type, base, addr), + _kit(kit) { + fixup_decorators(); + } + + GraphKit* kit() const { return _kit; } + template <typename T> T barrier_set_state_as() const { return reinterpret_cast<T>(barrier_set_state()); } + + virtual PhaseGVN& gvn() const; + virtual bool is_parse_access() const { return true; } }; // This class wraps a bunch of context parameters thare are passed around in the // BarrierSetC2 backend hierarchy, for atomic accesses, to reduce boiler plate. ! class C2AtomicParseAccess: public C2ParseAccess { Node* _memory; uint _alias_idx; bool _needs_pinning; public: ! C2AtomicParseAccess(GraphKit* kit, DecoratorSet decorators, BasicType type, Node* base, C2AccessValuePtr& addr, uint alias_idx) : ! C2ParseAccess(kit, decorators, type, base, addr), _memory(NULL), _alias_idx(alias_idx), _needs_pinning(true) {} // Set the memory node based on the current memory slice.
*** 155,193 **** bool needs_pinning() const { return _needs_pinning; } void set_needs_pinning(bool value) { _needs_pinning = value; } }; // This is the top-level class for the backend of the Access API in C2. // The top-level class is responsible for performing raw accesses. The // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle // barriers into the accesses. class BarrierSetC2: public CHeapObj<mtGC> { protected: virtual void resolve_address(C2Access& access) const; virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val, Node* new_val, const Type* value_type) const; ! virtual Node* atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_add_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* val_type) const; ! void pin_atomic_op(C2AtomicAccess& access) const; public: // This is the entry-point for the backend to perform accesses through the Access API. virtual Node* store_at(C2Access& access, C2AccessValue& val) const; virtual Node* load_at(C2Access& access, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_val_at(C2AtomicAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_bool_at(C2AtomicAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_xchg_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const; ! virtual Node* atomic_add_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const; virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const; virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; } --- 178,241 ---- bool needs_pinning() const { return _needs_pinning; } void set_needs_pinning(bool value) { _needs_pinning = value; } }; + // C2Access for optimization time calls to the BarrierSetC2 backend. + class C2OptAccess: public C2Access { + PhaseGVN& _gvn; + MergeMemNode* _mem; + Node* _ctl; + + public: + C2OptAccess(PhaseGVN& gvn, Node* ctl, MergeMemNode* mem, DecoratorSet decorators, + BasicType type, Node* base, C2AccessValuePtr& addr) : + C2Access(decorators, type, base, addr), + _gvn(gvn), _mem(mem), _ctl(ctl) { + fixup_decorators(); + } + + + MergeMemNode* mem() const { return _mem; } + Node* ctl() const { return _ctl; } + // void set_mem(Node* mem) { _mem = mem; } + void set_ctl(Node* ctl) { _ctl = ctl; } + + virtual PhaseGVN& gvn() const { return _gvn; } + virtual bool is_opt_access() const { return true; } + }; + + // This is the top-level class for the backend of the Access API in C2. // The top-level class is responsible for performing raw accesses. The // various GC barrier sets inherit from the BarrierSetC2 class to sprinkle // barriers into the accesses. class BarrierSetC2: public CHeapObj<mtGC> { protected: virtual void resolve_address(C2Access& access) const; virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* value_type) const; ! virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_add_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const; ! void pin_atomic_op(C2AtomicParseAccess& access) const; public: // This is the entry-point for the backend to perform accesses through the Access API. virtual Node* store_at(C2Access& access, C2AccessValue& val) const; virtual Node* load_at(C2Access& access, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_val_at(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_cmpxchg_bool_at(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; ! virtual Node* atomic_xchg_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; ! virtual Node* atomic_add_at(C2AtomicParseAccess& access, Node* new_val, const Type* value_type) const; virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const; virtual Node* resolve(GraphKit* kit, Node* n, DecoratorSet decorators) const { return n; }
*** 201,210 **** --- 249,259 ---- Parsing, Optimization, Expansion }; virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return false; } + virtual void clone_barrier_at_expansion(ArrayCopyNode* ac, Node* call, PhaseIterGVN& igvn) const; // Support for GC barriers emitted during parsing virtual bool has_load_barriers() const { return false; } virtual bool is_gc_barrier_node(Node* node) const { return false; } virtual Node* step_over_gc_barrier(Node* c) const { return c; }
< prev index next >