src/hotspot/share/gc/shared/barrierSet.hpp
changeset 47998 fb0275c320a0
parent 47794 e84aa2c71241
child 48628 69d65d9dcadb
child 55934 912c55e702d6
equal deleted inserted replaced
47997:55c43e677ded 47998:fb0275c320a0
    23  */
    23  */
    24 
    24 
    25 #ifndef SHARE_VM_GC_SHARED_BARRIERSET_HPP
    25 #ifndef SHARE_VM_GC_SHARED_BARRIERSET_HPP
    26 #define SHARE_VM_GC_SHARED_BARRIERSET_HPP
    26 #define SHARE_VM_GC_SHARED_BARRIERSET_HPP
    27 
    27 
       
    28 #include "gc/shared/barrierSetConfig.hpp"
    28 #include "memory/memRegion.hpp"
    29 #include "memory/memRegion.hpp"
       
    30 #include "oops/access.hpp"
       
    31 #include "oops/accessBackend.hpp"
    29 #include "oops/oopsHierarchy.hpp"
    32 #include "oops/oopsHierarchy.hpp"
    30 #include "utilities/fakeRttiSupport.hpp"
    33 #include "utilities/fakeRttiSupport.hpp"
    31 
    34 
    32 // This class provides the interface between a barrier implementation and
    35 // This class provides the interface between a barrier implementation and
    33 // the rest of the system.
    36 // the rest of the system.
    34 
    37 
    35 class BarrierSet: public CHeapObj<mtGC> {
    38 class BarrierSet: public CHeapObj<mtGC> {
    36   friend class VMStructs;
    39   friend class VMStructs;
    37 public:
    40 
       
    41   static BarrierSet* _bs;
       
    42 
       
    43 public:
       
    44   enum Name {
       
    45 #define BARRIER_SET_DECLARE_BS_ENUM(bs_name) bs_name ,
       
    46     FOR_EACH_BARRIER_SET_DO(BARRIER_SET_DECLARE_BS_ENUM)
       
    47 #undef BARRIER_SET_DECLARE_BS_ENUM
       
    48     UnknownBS
       
    49   };
       
    50 
       
    51   static BarrierSet* barrier_set() { return _bs; }
       
    52 
       
    53 protected:
    38   // Fake RTTI support.  For a derived class T to participate
    54   // Fake RTTI support.  For a derived class T to participate
    39   // - T must have a corresponding Name entry.
    55   // - T must have a corresponding Name entry.
    40   // - GetName<T> must be specialized to return the corresponding Name
    56   // - GetName<T> must be specialized to return the corresponding Name
    41   //   entry.
    57   //   entry.
    42   // - If T is a base class, the constructor must have a FakeRtti
    58   // - If T is a base class, the constructor must have a FakeRtti
    43   //   parameter and pass it up to its base class, with the tag set
    59   //   parameter and pass it up to its base class, with the tag set
    44   //   augmented with the corresponding Name entry.
    60   //   augmented with the corresponding Name entry.
    45   // - If T is a concrete class, the constructor must create a
    61   // - If T is a concrete class, the constructor must create a
    46   //   FakeRtti object whose tag set includes the corresponding Name
    62   //   FakeRtti object whose tag set includes the corresponding Name
    47   //   entry, and pass it up to its base class.
    63   //   entry, and pass it up to its base class.
    48 
       
    49   enum Name {                   // associated class
       
    50     ModRef,                     // ModRefBarrierSet
       
    51     CardTableModRef,            // CardTableModRefBS
       
    52     CardTableForRS,             // CardTableModRefBSForCTRS
       
    53     CardTableExtension,         // CardTableExtension
       
    54     G1SATBCT,                   // G1SATBCardTableModRefBS
       
    55     G1SATBCTLogging             // G1SATBCardTableLoggingModRefBS
       
    56   };
       
    57 
       
    58 protected:
       
    59   typedef FakeRttiSupport<BarrierSet, Name> FakeRtti;
    64   typedef FakeRttiSupport<BarrierSet, Name> FakeRtti;
    60 
    65 
    61 private:
    66 private:
    62   FakeRtti _fake_rtti;
    67   FakeRtti _fake_rtti;
    63 
    68 
       
    69 public:
    64   // Metafunction mapping a class derived from BarrierSet to the
    70   // Metafunction mapping a class derived from BarrierSet to the
    65   // corresponding Name enum tag.
    71   // corresponding Name enum tag.
    66   template<typename T> struct GetName;
    72   template<typename T> struct GetName;
    67 
    73 
    68   // Downcast argument to a derived barrier set type.
    74   // Metafunction mapping a Name enum type to the corresponding
    69   // The cast is checked in a debug build.
    75   // lass derived from BarrierSet.
    70   // T must have a specialization for BarrierSet::GetName<T>.
    76   template<BarrierSet::Name T> struct GetType;
    71   template<typename T> friend T* barrier_set_cast(BarrierSet* bs);
    77 
    72 
       
    73 public:
       
    74   // Note: This is not presently the Name corresponding to the
    78   // Note: This is not presently the Name corresponding to the
    75   // concrete class of this object.
    79   // concrete class of this object.
    76   BarrierSet::Name kind() const { return _fake_rtti.concrete_tag(); }
    80   BarrierSet::Name kind() const { return _fake_rtti.concrete_tag(); }
    77 
    81 
    78   // Test whether this object is of the type corresponding to bsn.
    82   // Test whether this object is of the type corresponding to bsn.
    81   // End of fake RTTI support.
    85   // End of fake RTTI support.
    82 
    86 
    83 protected:
    87 protected:
    84   BarrierSet(const FakeRtti& fake_rtti) : _fake_rtti(fake_rtti) { }
    88   BarrierSet(const FakeRtti& fake_rtti) : _fake_rtti(fake_rtti) { }
    85   ~BarrierSet() { }
    89   ~BarrierSet() { }
    86 
       
    87 public:
       
    88   // Invoke the barrier, if any, necessary when writing "new_val" into the
       
    89   // ref field at "offset" in "obj".
       
    90   // (For efficiency reasons, this operation is specialized for certain
       
    91   // barrier types.  Semantically, it should be thought of as a call to the
       
    92   // virtual "_work" function below, which must implement the barrier.)
       
    93   // First the pre-write versions...
       
    94   template <class T> inline void write_ref_field_pre(T* field, oop new_val);
       
    95 
       
    96   // ...then the post-write version.
       
    97   inline void write_ref_field(void* field, oop new_val, bool release = false);
       
    98 
       
    99 protected:
       
   100   virtual void write_ref_field_pre_work(      oop* field, oop new_val) {};
       
   101   virtual void write_ref_field_pre_work(narrowOop* field, oop new_val) {};
       
   102   virtual void write_ref_field_work(void* field, oop new_val, bool release) = 0;
       
   103 
    90 
   104 public:
    91 public:
   105   // Operations on arrays, or general regions (e.g., for "clone") may be
    92   // Operations on arrays, or general regions (e.g., for "clone") may be
   106   // optimized by some barriers.
    93   // optimized by some barriers.
   107 
    94 
   142   // within the heap, this function tells whether they are met.
   129   // within the heap, this function tells whether they are met.
   143   virtual bool is_aligned(HeapWord* addr) = 0;
   130   virtual bool is_aligned(HeapWord* addr) = 0;
   144 
   131 
   145   // Print a description of the memory for the barrier set
   132   // Print a description of the memory for the barrier set
   146   virtual void print_on(outputStream* st) const = 0;
   133   virtual void print_on(outputStream* st) const = 0;
       
   134 
       
   135   static void set_bs(BarrierSet* bs) { _bs = bs; }
       
   136 
       
   137   // The AccessBarrier of a BarrierSet subclass is called by the Access API
       
   138   // (cf. oops/access.hpp) to perform decorated accesses. GC implementations
       
   139   // may override these default access operations by declaring an
       
   140   // AccessBarrier class in its BarrierSet. Its accessors will then be
       
   141   // automatically resolved at runtime.
       
   142   //
       
   143   // In order to register a new FooBarrierSet::AccessBarrier with the Access API,
       
   144   // the following steps should be taken:
       
   145   // 1) Provide an enum "name" for the BarrierSet in barrierSetConfig.hpp
       
   146   // 2) Make sure the barrier set headers are included from barrierSetConfig.inline.hpp
       
   147   // 3) Provide specializations for BarrierSet::GetName and BarrierSet::GetType.
       
   148   template <DecoratorSet decorators, typename BarrierSetT>
       
   149   class AccessBarrier: protected RawAccessBarrier<decorators> {
       
   150   protected:
       
   151     typedef RawAccessBarrier<decorators> Raw;
       
   152     typedef typename BarrierSetT::template AccessBarrier<decorators> CRTPAccessBarrier;
       
   153 
       
   154   public:
       
   155     // Primitive heap accesses. These accessors get resolved when
       
   156     // IN_HEAP is set (e.g. when using the HeapAccess API), it is
       
   157     // not an oop_* overload, and the barrier strength is AS_NORMAL.
       
   158     template <typename T>
       
   159     static T load_in_heap(T* addr) {
       
   160       return Raw::template load<T>(addr);
       
   161     }
       
   162 
       
   163     template <typename T>
       
   164     static T load_in_heap_at(oop base, ptrdiff_t offset) {
       
   165       return Raw::template load_at<T>(base, offset);
       
   166     }
       
   167 
       
   168     template <typename T>
       
   169     static void store_in_heap(T* addr, T value) {
       
   170       Raw::store(addr, value);
       
   171     }
       
   172 
       
   173     template <typename T>
       
   174     static void store_in_heap_at(oop base, ptrdiff_t offset, T value) {
       
   175       Raw::store_at(base, offset, value);
       
   176     }
       
   177 
       
   178     template <typename T>
       
   179     static T atomic_cmpxchg_in_heap(T new_value, T* addr, T compare_value) {
       
   180       return Raw::atomic_cmpxchg(new_value, addr, compare_value);
       
   181     }
       
   182 
       
   183     template <typename T>
       
   184     static T atomic_cmpxchg_in_heap_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
       
   185       return Raw::oop_atomic_cmpxchg_at(new_value, base, offset, compare_value);
       
   186     }
       
   187 
       
   188     template <typename T>
       
   189     static T atomic_xchg_in_heap(T new_value, T* addr) {
       
   190       return Raw::atomic_xchg(new_value, addr);
       
   191     }
       
   192 
       
   193     template <typename T>
       
   194     static T atomic_xchg_in_heap_at(T new_value, oop base, ptrdiff_t offset) {
       
   195       return Raw::atomic_xchg_at(new_value, base, offset);
       
   196     }
       
   197 
       
   198     template <typename T>
       
   199     static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
       
   200       return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
       
   201     }
       
   202 
       
   203     // Heap oop accesses. These accessors get resolved when
       
   204     // IN_HEAP is set (e.g. when using the HeapAccess API), it is
       
   205     // an oop_* overload, and the barrier strength is AS_NORMAL.
       
   206     template <typename T>
       
   207     static oop oop_load_in_heap(T* addr) {
       
   208       return Raw::template oop_load<oop>(addr);
       
   209     }
       
   210 
       
   211     static oop oop_load_in_heap_at(oop base, ptrdiff_t offset) {
       
   212       return Raw::template oop_load_at<oop>(base, offset);
       
   213     }
       
   214 
       
   215     template <typename T>
       
   216     static void oop_store_in_heap(T* addr, oop value) {
       
   217       Raw::oop_store(addr, value);
       
   218     }
       
   219 
       
   220     static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) {
       
   221       Raw::oop_store_at(base, offset, value);
       
   222     }
       
   223 
       
   224     template <typename T>
       
   225     static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value) {
       
   226       return Raw::oop_atomic_cmpxchg(new_value, addr, compare_value);
       
   227     }
       
   228 
       
   229     static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
       
   230       return Raw::oop_atomic_cmpxchg_at(new_value, base, offset, compare_value);
       
   231     }
       
   232 
       
   233     template <typename T>
       
   234     static oop oop_atomic_xchg_in_heap(oop new_value, T* addr) {
       
   235       return Raw::oop_atomic_xchg(new_value, addr);
       
   236     }
       
   237 
       
   238     static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
       
   239       return Raw::oop_atomic_xchg_at(new_value, base, offset);
       
   240     }
       
   241 
       
   242     template <typename T>
       
   243     static bool oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
       
   244       return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
       
   245     }
       
   246 
       
   247     // Off-heap oop accesses. These accessors get resolved when
       
   248     // IN_HEAP is not set (e.g. when using the RootAccess API), it is
       
   249     // an oop* overload, and the barrier strength is AS_NORMAL.
       
   250     template <typename T>
       
   251     static oop oop_load_not_in_heap(T* addr) {
       
   252       return Raw::template oop_load<oop>(addr);
       
   253     }
       
   254 
       
   255     template <typename T>
       
   256     static void oop_store_not_in_heap(T* addr, oop value) {
       
   257       Raw::oop_store(addr, value);
       
   258     }
       
   259 
       
   260     template <typename T>
       
   261     static oop oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value) {
       
   262       return Raw::oop_atomic_cmpxchg(new_value, addr, compare_value);
       
   263     }
       
   264 
       
   265     template <typename T>
       
   266     static oop oop_atomic_xchg_not_in_heap(oop new_value, T* addr) {
       
   267       return Raw::oop_atomic_xchg(new_value, addr);
       
   268     }
       
   269 
       
   270     // Clone barrier support
       
   271     static void clone_in_heap(oop src, oop dst, size_t size) {
       
   272       Raw::clone(src, dst, size);
       
   273     }
       
   274   };
   147 };
   275 };
   148 
   276 
   149 template<typename T>
   277 template<typename T>
   150 inline T* barrier_set_cast(BarrierSet* bs) {
   278 inline T* barrier_set_cast(BarrierSet* bs) {
   151   assert(bs->is_a(BarrierSet::GetName<T>::value), "wrong type of barrier set");
   279   assert(bs->is_a(BarrierSet::GetName<T>::value), "wrong type of barrier set");