src/hotspot/share/runtime/orderAccess.hpp
changeset 59247 56bf71d64d51
parent 54323 846bc643f4ef
equal deleted inserted replaced
59246:fcad92f425c5 59247:56bf71d64d51
    24 
    24 
    25 #ifndef SHARE_RUNTIME_ORDERACCESS_HPP
    25 #ifndef SHARE_RUNTIME_ORDERACCESS_HPP
    26 #define SHARE_RUNTIME_ORDERACCESS_HPP
    26 #define SHARE_RUNTIME_ORDERACCESS_HPP
    27 
    27 
    28 #include "memory/allocation.hpp"
    28 #include "memory/allocation.hpp"
    29 #include "runtime/atomic.hpp"
       
    30 #include "utilities/macros.hpp"
    29 #include "utilities/macros.hpp"
    31 
    30 
    32 //                Memory Access Ordering Model
    31 //                Memory Access Ordering Model
    33 //
    32 //
    34 // This interface is based on the JSR-133 Cookbook for Compiler Writers.
    33 // This interface is based on the JSR-133 Cookbook for Compiler Writers.
   229 // and friends' constructors do a fence, a lock and an acquire *in that
   228 // and friends' constructors do a fence, a lock and an acquire *in that
   230 // order*.  And that their destructors do a release and unlock, in *that*
   229 // order*.  And that their destructors do a release and unlock, in *that*
   231 // order.  If their implementations change such that these assumptions
   230 // order.  If their implementations change such that these assumptions
   232 // are violated, a whole lot of code will break.
   231 // are violated, a whole lot of code will break.
   233 
   232 
   234 enum ScopedFenceType {
   233 class OrderAccess : public AllStatic {
   235     X_ACQUIRE
       
   236   , RELEASE_X
       
   237   , RELEASE_X_FENCE
       
   238 };
       
   239 
       
   240 template <ScopedFenceType T>
       
   241 class ScopedFenceGeneral: public StackObj {
       
   242  public:
       
   243   void prefix() {}
       
   244   void postfix() {}
       
   245 };
       
   246 
       
   247 template <ScopedFenceType T>
       
   248 class ScopedFence : public ScopedFenceGeneral<T> {
       
   249   void *const _field;
       
   250  public:
       
   251   ScopedFence(void *const field) : _field(field) { prefix(); }
       
   252   ~ScopedFence() { postfix(); }
       
   253   void prefix() { ScopedFenceGeneral<T>::prefix(); }
       
   254   void postfix() { ScopedFenceGeneral<T>::postfix(); }
       
   255 };
       
   256 
       
   257 class OrderAccess : private Atomic {
       
   258  public:
   234  public:
   259   // barriers
   235   // barriers
   260   static void     loadload();
   236   static void     loadload();
   261   static void     storestore();
   237   static void     storestore();
   262   static void     loadstore();
   238   static void     loadstore();
   265   static void     acquire();
   241   static void     acquire();
   266   static void     release();
   242   static void     release();
   267   static void     fence();
   243   static void     fence();
   268 
   244 
   269   static void     cross_modify_fence();
   245   static void     cross_modify_fence();
   270 
   246 private:
   271   template <typename T>
       
   272   static T        load_acquire(const volatile T* p);
       
   273 
       
   274   template <typename T, typename D>
       
   275   static void     release_store(volatile D* p, T v);
       
   276 
       
   277   template <typename T, typename D>
       
   278   static void     release_store_fence(volatile D* p, T v);
       
   279 
       
   280  private:
       
   281   // This is a helper that invokes the StubRoutines::fence_entry()
   247   // This is a helper that invokes the StubRoutines::fence_entry()
   282   // routine if it exists, It should only be used by platforms that
   248   // routine if it exists, It should only be used by platforms that
   283   // don't have another way to do the inline assembly.
   249   // don't have another way to do the inline assembly.
   284   static void StubRoutines_fence();
   250   static void StubRoutines_fence();
   285 
       
   286   // Give platforms a variation point to specialize.
       
   287   template<size_t byte_size, ScopedFenceType type> struct PlatformOrderedStore;
       
   288   template<size_t byte_size, ScopedFenceType type> struct PlatformOrderedLoad;
       
   289 
       
   290   template<typename FieldType, ScopedFenceType FenceType>
       
   291   static void ordered_store(volatile FieldType* p, FieldType v);
       
   292 
       
   293   template<typename FieldType, ScopedFenceType FenceType>
       
   294   static FieldType ordered_load(const volatile FieldType* p);
       
   295 };
   251 };
   296 
   252 
   297 // The following methods can be specialized using simple template specialization
       
   298 // in the platform specific files for optimization purposes. Otherwise the
       
   299 // generalized variant is used.
       
   300 
       
   301 template<size_t byte_size, ScopedFenceType type>
       
   302 struct OrderAccess::PlatformOrderedStore {
       
   303   template <typename T>
       
   304   void operator()(T v, volatile T* p) const {
       
   305     ordered_store<T, type>(p, v);
       
   306   }
       
   307 };
       
   308 
       
   309 template<size_t byte_size, ScopedFenceType type>
       
   310 struct OrderAccess::PlatformOrderedLoad {
       
   311   template <typename T>
       
   312   T operator()(const volatile T* p) const {
       
   313     return ordered_load<T, type>(p);
       
   314   }
       
   315 };
       
   316 
       
   317 #include OS_CPU_HEADER(orderAccess)
   253 #include OS_CPU_HEADER(orderAccess)
   318 
   254 
   319 template<> inline void ScopedFenceGeneral<X_ACQUIRE>::postfix()       { OrderAccess::acquire(); }
       
   320 template<> inline void ScopedFenceGeneral<RELEASE_X>::prefix()        { OrderAccess::release(); }
       
   321 template<> inline void ScopedFenceGeneral<RELEASE_X_FENCE>::prefix()  { OrderAccess::release(); }
       
   322 template<> inline void ScopedFenceGeneral<RELEASE_X_FENCE>::postfix() { OrderAccess::fence();   }
       
   323 
       
   324 
       
   325 template <typename FieldType, ScopedFenceType FenceType>
       
   326 inline void OrderAccess::ordered_store(volatile FieldType* p, FieldType v) {
       
   327   ScopedFence<FenceType> f((void*)p);
       
   328   Atomic::store(v, p);
       
   329 }
       
   330 
       
   331 template <typename FieldType, ScopedFenceType FenceType>
       
   332 inline FieldType OrderAccess::ordered_load(const volatile FieldType* p) {
       
   333   ScopedFence<FenceType> f((void*)p);
       
   334   return Atomic::load(p);
       
   335 }
       
   336 
       
   337 template <typename T>
       
   338 inline T OrderAccess::load_acquire(const volatile T* p) {
       
   339   return LoadImpl<T, PlatformOrderedLoad<sizeof(T), X_ACQUIRE> >()(p);
       
   340 }
       
   341 
       
   342 template <typename T, typename D>
       
   343 inline void OrderAccess::release_store(volatile D* p, T v) {
       
   344   StoreImpl<T, D, PlatformOrderedStore<sizeof(D), RELEASE_X> >()(v, p);
       
   345 }
       
   346 
       
   347 template <typename T, typename D>
       
   348 inline void OrderAccess::release_store_fence(volatile D* p, T v) {
       
   349   StoreImpl<T, D, PlatformOrderedStore<sizeof(D), RELEASE_X_FENCE> >()(v, p);
       
   350 }
       
   351 #endif // SHARE_RUNTIME_ORDERACCESS_HPP
   255 #endif // SHARE_RUNTIME_ORDERACCESS_HPP