src/hotspot/share/oops/access.hpp
changeset 50389 7e8c0409a747
parent 49658 8237a91c1cca
child 50532 a18c60527166
equal deleted inserted replaced
50388:55fac6146d31 50389:7e8c0409a747
    53 // * store_at: Store a value in an internal pointer relative to a base object.
    53 // * store_at: Store a value in an internal pointer relative to a base object.
    54 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.
    54 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.
    55 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
    55 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
    56 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
    56 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
    57 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
    57 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
    58 // * arraycopy: Copy data from one heap array to another heap array.
    58 // * arraycopy: Copy data from one heap array to another heap array. The ArrayAccess class has convenience functions for this.
    59 // * clone: Clone the contents of an object to a newly allocated object.
    59 // * clone: Clone the contents of an object to a newly allocated object.
    60 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
    60 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
    61 // * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)
    61 // * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)
    62 //
    62 //
    63 // == IMPLEMENTATION ==
    63 // == IMPLEMENTATION ==
   128   static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;
   128   static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;
   129   static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;
   129   static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;
   130   static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
   130   static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
   131   static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
   131   static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
   132 
   132 
       
   133 protected:
       
   134   template <typename T>
       
   135   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
       
   136                                    arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
       
   137                                    size_t length) {
       
   138     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |  IN_HEAP_ARRAY |
       
   139                       AS_DECORATOR_MASK>();
       
   140     return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
       
   141                                                                          dst_obj, dst_offset_in_bytes, dst_raw,
       
   142                                                                          length);
       
   143   }
       
   144 
       
   145   template <typename T>
       
   146   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
       
   147                                arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
       
   148                                size_t length) {
       
   149     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | IN_HEAP_ARRAY |
       
   150                       AS_DECORATOR_MASK>();
       
   151     AccessInternal::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
       
   152                                           dst_obj, dst_offset_in_bytes, dst_raw,
       
   153                                           length);
       
   154   }
       
   155 
   133 public:
   156 public:
   134   // Primitive heap accesses
   157   // Primitive heap accesses
   135   static inline AccessInternal::LoadAtProxy<decorators> load_at(oop base, ptrdiff_t offset) {
   158   static inline AccessInternal::LoadAtProxy<decorators> load_at(oop base, ptrdiff_t offset) {
   136     verify_primitive_decorators<load_mo_decorators>();
   159     verify_primitive_decorators<load_mo_decorators>();
   137     return AccessInternal::LoadAtProxy<decorators>(base, offset);
   160     return AccessInternal::LoadAtProxy<decorators>(base, offset);
   153   static inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
   176   static inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
   154     verify_primitive_decorators<atomic_xchg_mo_decorators>();
   177     verify_primitive_decorators<atomic_xchg_mo_decorators>();
   155     return AccessInternal::atomic_xchg_at<decorators>(new_value, base, offset);
   178     return AccessInternal::atomic_xchg_at<decorators>(new_value, base, offset);
   156   }
   179   }
   157 
   180 
   158   template <typename T>
       
   159   static inline void arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
       
   160     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
       
   161                       AS_DECORATOR_MASK>();
       
   162     AccessInternal::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
       
   163   }
       
   164 
       
   165   // Oop heap accesses
   181   // Oop heap accesses
   166   static inline AccessInternal::OopLoadAtProxy<decorators> oop_load_at(oop base, ptrdiff_t offset) {
   182   static inline AccessInternal::OopLoadAtProxy<decorators> oop_load_at(oop base, ptrdiff_t offset) {
   167     verify_heap_oop_decorators<load_mo_decorators>();
   183     verify_heap_oop_decorators<load_mo_decorators>();
   168     return AccessInternal::OopLoadAtProxy<decorators>(base, offset);
   184     return AccessInternal::OopLoadAtProxy<decorators>(base, offset);
   169   }
   185   }
   189   static inline T oop_atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
   205   static inline T oop_atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
   190     verify_heap_oop_decorators<atomic_xchg_mo_decorators>();
   206     verify_heap_oop_decorators<atomic_xchg_mo_decorators>();
   191     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
   207     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
   192     OopType new_oop_value = new_value;
   208     OopType new_oop_value = new_value;
   193     return AccessInternal::atomic_xchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset);
   209     return AccessInternal::atomic_xchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset);
   194   }
       
   195 
       
   196   template <typename T>
       
   197   static inline bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
       
   198     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | AS_DECORATOR_MASK>();
       
   199     return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, dst_obj, src, dst, length);
       
   200   }
   210   }
   201 
   211 
   202   // Clone an object from src to dst
   212   // Clone an object from src to dst
   203   static inline void clone(oop src, oop dst, size_t size) {
   213   static inline void clone(oop src, oop dst, size_t size) {
   204     verify_decorators<IN_HEAP>();
   214     verify_decorators<IN_HEAP>();
   285 
   295 
   286 // Helper for performing normal accesses in roots. These accesses
   296 // Helper for performing normal accesses in roots. These accesses
   287 // may resolve an accessor on a GC barrier set
   297 // may resolve an accessor on a GC barrier set
   288 template <DecoratorSet decorators = INTERNAL_EMPTY>
   298 template <DecoratorSet decorators = INTERNAL_EMPTY>
   289 class RootAccess: public Access<IN_ROOT | decorators> {};
   299 class RootAccess: public Access<IN_ROOT | decorators> {};
       
   300 
       
   301 // Helper for array access.
       
   302 template <DecoratorSet decorators = INTERNAL_EMPTY>
       
   303 class ArrayAccess: public HeapAccess<IN_HEAP_ARRAY | decorators> {
       
   304   typedef HeapAccess<IN_HEAP_ARRAY | decorators> AccessT;
       
   305 public:
       
   306   template <typename T>
       
   307   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
       
   308                                arrayOop dst_obj, size_t dst_offset_in_bytes,
       
   309                                size_t length) {
       
   310     AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
       
   311                        dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
       
   312                        length);
       
   313   }
       
   314 
       
   315   template <typename T>
       
   316   static inline void arraycopy_to_native(arrayOop src_obj, size_t src_offset_in_bytes,
       
   317                                          T* dst,
       
   318                                          size_t length) {
       
   319     AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
       
   320                        NULL, 0, dst,
       
   321                        length);
       
   322   }
       
   323 
       
   324   template <typename T>
       
   325   static inline void arraycopy_from_native(const T* src,
       
   326                                            arrayOop dst_obj, size_t dst_offset_in_bytes,
       
   327                                            size_t length) {
       
   328     AccessT::arraycopy(NULL, 0, src,
       
   329                        dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
       
   330                        length);
       
   331   }
       
   332 
       
   333   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
       
   334                                    arrayOop dst_obj, size_t dst_offset_in_bytes,
       
   335                                    size_t length) {
       
   336     return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const HeapWord*>(NULL),
       
   337                                   dst_obj, dst_offset_in_bytes, reinterpret_cast<HeapWord*>(NULL),
       
   338                                   length);
       
   339   }
       
   340 
       
   341   template <typename T>
       
   342   static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {
       
   343     return AccessT::oop_arraycopy(NULL, 0, src,
       
   344                                   NULL, 0, dst,
       
   345                                   length);
       
   346   }
       
   347 
       
   348 };
   290 
   349 
   291 template <DecoratorSet decorators>
   350 template <DecoratorSet decorators>
   292 template <DecoratorSet expected_decorators>
   351 template <DecoratorSet expected_decorators>
   293 void Access<decorators>::verify_decorators() {
   352 void Access<decorators>::verify_decorators() {
   294   STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used
   353   STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used