< prev index next >

src/hotspot/share/oops/access.hpp

erik arraycopy

37 // A decorator is an attribute or property that affects the way a memory access is performed in some way.                            
38 // There are different groups of decorators. Some have to do with memory ordering, others to do with,                                
39 // e.g. strength of references, strength of GC barriers, or whether compression should be applied or not.                            
40 // Some decorators are set at buildtime, such as whether primitives require GC barriers or not, others                               
41 // at callsites such as whether an access is in the heap or not, and others are resolved at runtime                                  
42 // such as GC-specific barriers and encoding/decoding compressed oops. For more information about what                               
43 // decorators are available, cf. oops/accessDecorators.hpp.                                                                          
44 // By pipelining handling of these decorators, the design of the Access API allows separation of concern                             
45 // over the different orthogonal concerns of decorators, while providing a powerful way of                                           
46 // expressing these orthogonal semantic properties in a unified way.                                                                 
47 //                                                                                                                                   
48 // == OPERATIONS ==                                                                                                                  
49 // * load: Load a value from an address.                                                                                             
50 // * load_at: Load a value from an internal pointer relative to a base object.                                                       
51 // * store: Store a value at an address.                                                                                             
52 // * store_at: Store a value in an internal pointer relative to a base object.                                                       
53 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.             
54 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared
55 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.                            
56 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.        
57 // * arraycopy: Copy data from one heap array to another heap array.                                                                 
58 // * clone: Clone the contents of an object to a newly allocated object.                                                             
59 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transi
60 // * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)                    
61 //                                                                                                                                   
62 // == IMPLEMENTATION ==                                                                                                              
63 // Each access goes through the following steps in a template pipeline.                                                              
64 // There are essentially 5 steps for each access:                                                                                    
65 // * Step 1:   Set default decorators and decay types. This step gets rid of CV qualifiers                                           
66 //             and sets default decorators to sensible values.                                                                       
67 // * Step 2:   Reduce types. This step makes sure there is only a single T type and not                                              
68 //             multiple types. The P type of the address and T type of the value must                                                
69 //             match.                                                                                                                
70 // * Step 3:   Pre-runtime dispatch. This step checks whether a runtime call can be                                                  
71 //             avoided, and in that case avoids it (calling raw accesses or                                                          
72 //             primitive accesses in a build that does not require primitive GC barriers)                                            
73 // * Step 4:   Runtime-dispatch. This step performs a runtime dispatch to the corresponding                                          
74 //             BarrierSet::AccessBarrier accessor that attaches GC-required barriers                                                 
75 //             to the access.                                                                                                        
76 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch                                            

37 // A decorator is an attribute or property that affects the way a memory access is performed in some way.
38 // There are different groups of decorators. Some have to do with memory ordering, others to do with,
39 // e.g. strength of references, strength of GC barriers, or whether compression should be applied or not.
40 // Some decorators are set at buildtime, such as whether primitives require GC barriers or not, others
41 // at callsites such as whether an access is in the heap or not, and others are resolved at runtime
42 // such as GC-specific barriers and encoding/decoding compressed oops. For more information about what
43 // decorators are available, cf. oops/accessDecorators.hpp.
44 // By pipelining handling of these decorators, the design of the Access API allows separation of concern
45 // over the different orthogonal concerns of decorators, while providing a powerful way of
46 // expressing these orthogonal semantic properties in a unified way.
47 //
48 // == OPERATIONS ==
49 // * load: Load a value from an address.
50 // * load_at: Load a value from an internal pointer relative to a base object.
51 // * store: Store a value at an address.
52 // * store_at: Store a value in an internal pointer relative to a base object.
53 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.
54 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared
55 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
56 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
57 // * arraycopy: Copy data from one heap array to another heap array. The ArrayAccess class has convenience functions for this.
58 // * clone: Clone the contents of an object to a newly allocated object.
59 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transi
60 // * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)
61 //
62 // == IMPLEMENTATION ==
63 // Each access goes through the following steps in a template pipeline.
64 // There are essentially 5 steps for each access:
65 // * Step 1:   Set default decorators and decay types. This step gets rid of CV qualifiers
66 //             and sets default decorators to sensible values.
67 // * Step 2:   Reduce types. This step makes sure there is only a single T type and not
68 //             multiple types. The P type of the address and T type of the value must
69 //             match.
70 // * Step 3:   Pre-runtime dispatch. This step checks whether a runtime call can be
71 //             avoided, and in that case avoids it (calling raw accesses or
72 //             primitive accesses in a build that does not require primitive GC barriers)
73 // * Step 4:   Runtime-dispatch. This step performs a runtime dispatch to the corresponding
74 //             BarrierSet::AccessBarrier accessor that attaches GC-required barriers
75 //             to the access.
76 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch

112   static void verify_oop_decorators() {                                                                                              
113     const DecoratorSet oop_decorators = AS_DECORATOR_MASK | IN_DECORATOR_MASK |                                                      
114                                         (ON_DECORATOR_MASK ^ ON_UNKNOWN_OOP_REF) | // no unknown oop refs outside of the heap        
115                                         OOP_DECORATOR_MASK;                                                                          
116     verify_decorators<expected_mo_decorators | oop_decorators>();                                                                    
117   }                                                                                                                                  
118 
119   template <DecoratorSet expected_mo_decorators>                                                                                     
120   static void verify_heap_oop_decorators() {                                                                                         
121     const DecoratorSet heap_oop_decorators = AS_DECORATOR_MASK | ON_DECORATOR_MASK |                                                 
122                                              OOP_DECORATOR_MASK | (IN_DECORATOR_MASK ^                                               
123                                                                    (IN_ROOT | IN_CONCURRENT_ROOT)); // no root accesses in the heap  
124     verify_decorators<expected_mo_decorators | heap_oop_decorators>();                                                               
125   }                                                                                                                                  
126 
127   static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;                  
128   static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;                 
129   static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;                                                                  
130   static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;                                                  
131 
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
132 public:                                                                                                                              
133   // Primitive heap accesses                                                                                                         
134   static inline AccessInternal::LoadAtProxy<decorators> load_at(oop base, ptrdiff_t offset) {                                        
135     verify_primitive_decorators<load_mo_decorators>();                                                                               
136     return AccessInternal::LoadAtProxy<decorators>(base, offset);                                                                    
137   }                                                                                                                                  
138 
139   template <typename T>                                                                                                              
140   static inline void store_at(oop base, ptrdiff_t offset, T value) {                                                                 
141     verify_primitive_decorators<store_mo_decorators>();                                                                              
142     AccessInternal::store_at<decorators>(base, offset, value);                                                                       
143   }                                                                                                                                  
144 
145   template <typename T>                                                                                                              
146   static inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {                                      
147     verify_primitive_decorators<atomic_cmpxchg_mo_decorators>();                                                                     
148     return AccessInternal::atomic_cmpxchg_at<decorators>(new_value, base, offset, compare_value);                                    
149   }                                                                                                                                  
150 
151   template <typename T>                                                                                                              
152   static inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {                                                          
153     verify_primitive_decorators<atomic_xchg_mo_decorators>();                                                                        
154     return AccessInternal::atomic_xchg_at<decorators>(new_value, base, offset);                                                      
155   }                                                                                                                                  
156 
157   template <typename T>                                                                                                              
158   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,                                       
159                                arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,                                             
160                                size_t length) {                                                                                      
161     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | IN_HEAP_ARRAY |                                                           
162                       AS_DECORATOR_MASK>();                                                                                          
163     AccessInternal::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,                                                     
164                                           dst_obj, dst_offset_in_bytes, dst_raw,                                                     
165                                           length);                                                                                   
166   }                                                                                                                                  
167                                                                                                                                      
168   // Oop heap accesses                                                                                                               
169   static inline AccessInternal::OopLoadAtProxy<decorators> oop_load_at(oop base, ptrdiff_t offset) {                                 
170     verify_heap_oop_decorators<load_mo_decorators>();                                                                                
171     return AccessInternal::OopLoadAtProxy<decorators>(base, offset);                                                                 
172   }                                                                                                                                  
173 
174   template <typename T>                                                                                                              
175   static inline void oop_store_at(oop base, ptrdiff_t offset, T value) {                                                             
176     verify_heap_oop_decorators<store_mo_decorators>();                                                                               
177     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;                                                                
178     OopType oop_value = value;                                                                                                       
179     AccessInternal::store_at<decorators | INTERNAL_VALUE_IS_OOP>(base, offset, oop_value);                                           
180   }                                                                                                                                  
181 
182   template <typename T>                                                                                                              
183   static inline T oop_atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {                                  
184     verify_heap_oop_decorators<atomic_cmpxchg_mo_decorators>();                                                                      
185     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;                                                                
186     OopType new_oop_value = new_value;                                                                                               
187     OopType compare_oop_value = compare_value;                                                                                       
188     return AccessInternal::atomic_cmpxchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset, compare_oop_value);    
189   }                                                                                                                                  
190 
191   template <typename T>                                                                                                              
192   static inline T oop_atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {                                                      
193     verify_heap_oop_decorators<atomic_xchg_mo_decorators>();                                                                         
194     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;                                                                
195     OopType new_oop_value = new_value;                                                                                               
196     return AccessInternal::atomic_xchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset);                          
197   }                                                                                                                                  
198 
199   template <typename T>                                                                                                              
200   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,                                   
201                                    arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,                                         
202                                    size_t length) {                                                                                  
203     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |  IN_HEAP_ARRAY |                                                          
204                       AS_DECORATOR_MASK>();                                                                                          
205     return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,                      
206                                                                          dst_obj, dst_offset_in_bytes, dst_raw,                      
207                                                                          length);                                                    
208   }                                                                                                                                  
209                                                                                                                                      
210   // Clone an object from src to dst                                                                                                 
211   static inline void clone(oop src, oop dst, size_t size) {                                                                          
212     verify_decorators<IN_HEAP>();                                                                                                    
213     AccessInternal::clone<decorators>(src, dst, size);                                                                               
214   }                                                                                                                                  
215 
216   // Primitive accesses                                                                                                              
217   template <typename P>                                                                                                              
218   static inline P load(P* addr) {                                                                                                    
219     verify_primitive_decorators<load_mo_decorators>();                                                                               
220     return AccessInternal::load<decorators, P, P>(addr);                                                                             
221   }                                                                                                                                  
222 
223   template <typename P, typename T>                                                                                                  
224   static inline void store(P* addr, T value) {                                                                                       
225     verify_primitive_decorators<store_mo_decorators>();                                                                              
226     AccessInternal::store<decorators>(addr, value);                                                                                  
227   }                                                                                                                                  
228 

112   static void verify_oop_decorators() {
113     const DecoratorSet oop_decorators = AS_DECORATOR_MASK | IN_DECORATOR_MASK |
114                                         (ON_DECORATOR_MASK ^ ON_UNKNOWN_OOP_REF) | // no unknown oop refs outside of the heap
115                                         OOP_DECORATOR_MASK;
116     verify_decorators<expected_mo_decorators | oop_decorators>();
117   }
118 
119   template <DecoratorSet expected_mo_decorators>
120   static void verify_heap_oop_decorators() {
121     const DecoratorSet heap_oop_decorators = AS_DECORATOR_MASK | ON_DECORATOR_MASK |
122                                              OOP_DECORATOR_MASK | (IN_DECORATOR_MASK ^
123                                                                    (IN_ROOT | IN_CONCURRENT_ROOT)); // no root accesses in the heap
124     verify_decorators<expected_mo_decorators | heap_oop_decorators>();
125   }
126 
127   static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;
128   static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_VOLATILE | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;
129   static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
130   static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
131 
132 protected:
133   template <typename T>
134   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
135                                    arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
136                                    size_t length) {
137     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |  IN_HEAP_ARRAY |
138                       AS_DECORATOR_MASK>();
139     return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
140                                                                          dst_obj, dst_offset_in_bytes, dst_raw,
141                                                                          length);
142   }
143 
144   template <typename T>
145   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
146                                arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
147                                size_t length) {
148     verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | IN_HEAP_ARRAY |
149                       AS_DECORATOR_MASK>();
150     AccessInternal::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
151                                           dst_obj, dst_offset_in_bytes, dst_raw,
152                                           length);
153   }
154 
155 public:
156   // Primitive heap accesses
157   static inline AccessInternal::LoadAtProxy<decorators> load_at(oop base, ptrdiff_t offset) {
158     verify_primitive_decorators<load_mo_decorators>();
159     return AccessInternal::LoadAtProxy<decorators>(base, offset);
160   }
161 
162   template <typename T>
163   static inline void store_at(oop base, ptrdiff_t offset, T value) {
164     verify_primitive_decorators<store_mo_decorators>();
165     AccessInternal::store_at<decorators>(base, offset, value);
166   }
167 
168   template <typename T>
169   static inline T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
170     verify_primitive_decorators<atomic_cmpxchg_mo_decorators>();
171     return AccessInternal::atomic_cmpxchg_at<decorators>(new_value, base, offset, compare_value);
172   }
173 
174   template <typename T>
175   static inline T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
176     verify_primitive_decorators<atomic_xchg_mo_decorators>();
177     return AccessInternal::atomic_xchg_at<decorators>(new_value, base, offset);
178   }
179 











180   // Oop heap accesses
181   static inline AccessInternal::OopLoadAtProxy<decorators> oop_load_at(oop base, ptrdiff_t offset) {
182     verify_heap_oop_decorators<load_mo_decorators>();
183     return AccessInternal::OopLoadAtProxy<decorators>(base, offset);
184   }
185 
186   template <typename T>
187   static inline void oop_store_at(oop base, ptrdiff_t offset, T value) {
188     verify_heap_oop_decorators<store_mo_decorators>();
189     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
190     OopType oop_value = value;
191     AccessInternal::store_at<decorators | INTERNAL_VALUE_IS_OOP>(base, offset, oop_value);
192   }
193 
194   template <typename T>
195   static inline T oop_atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
196     verify_heap_oop_decorators<atomic_cmpxchg_mo_decorators>();
197     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
198     OopType new_oop_value = new_value;
199     OopType compare_oop_value = compare_value;
200     return AccessInternal::atomic_cmpxchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset, compare_oop_value);
201   }
202 
203   template <typename T>
204   static inline T oop_atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
205     verify_heap_oop_decorators<atomic_xchg_mo_decorators>();
206     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
207     OopType new_oop_value = new_value;
208     return AccessInternal::atomic_xchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset);
209   }
210 











211   // Clone an object from src to dst
212   static inline void clone(oop src, oop dst, size_t size) {
213     verify_decorators<IN_HEAP>();
214     AccessInternal::clone<decorators>(src, dst, size);
215   }
216 
217   // Primitive accesses
218   template <typename P>
219   static inline P load(P* addr) {
220     verify_primitive_decorators<load_mo_decorators>();
221     return AccessInternal::load<decorators, P, P>(addr);
222   }
223 
224   template <typename P, typename T>
225   static inline void store(P* addr, T value) {
226     verify_primitive_decorators<store_mo_decorators>();
227     AccessInternal::store<decorators>(addr, value);
228   }
229 

282 };                                                                                                                                   
283 
284 // Helper for performing raw accesses (knows only of memory ordering                                                                 
285 // atomicity decorators as well as compressed oops)                                                                                  
286 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
287 class RawAccess: public Access<AS_RAW | decorators> {};                                                                              
288 
289 // Helper for performing normal accesses on the heap. These accesses                                                                 
290 // may resolve an accessor on a GC barrier set                                                                                       
291 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
292 class HeapAccess: public Access<IN_HEAP | decorators> {};                                                                            
293 
294 // Helper for performing normal accesses in roots. These accesses                                                                    
295 // may resolve an accessor on a GC barrier set                                                                                       
296 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
297 class RootAccess: public Access<IN_ROOT | decorators> {};                                                                            
298 
299 // Helper for array access.                                                                                                          
300 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
301 class ArrayAccess: public HeapAccess<IN_HEAP_ARRAY | decorators> {                                                                   
                                                                                                                                     
302 public:                                                                                                                              
303   template <typename T>                                                                                                              
304   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,                                                         
305                                arrayOop dst_obj, size_t dst_offset_in_bytes,                                                         
306                                size_t length) {                                                                                      
307     HeapAccess<decorators | IN_HEAP_ARRAY>::arraycopy(src_obj, src_offset_in_bytes, (const T*) NULL,                                 
308                                                       dst_obj, dst_offset_in_bytes, (T*) NULL,                                       
309                                                       length);                                                                       
310   }                                                                                                                                  
311 
312   template <typename T>                                                                                                              
313   static inline void arraycopy_to_native(arrayOop src_obj, size_t src_offset_in_bytes, T* dst, size_t length) {                      
314     HeapAccess<decorators | IN_HEAP_ARRAY>::arraycopy(src_obj, src_offset_in_bytes, (const T*) NULL,                                 
315                                                       NULL, 0, dst,                                                                  
316                                                       length);                                                                       
                                                                                                                                     
                                                                                                                                     
317   }                                                                                                                                  
318 
319   template <typename T>                                                                                                              
320   static inline void arraycopy_from_native(const T* src, arrayOop dst_obj, size_t dst_offset_in_bytes, size_t length) {              
321     HeapAccess<decorators | IN_HEAP_ARRAY>::arraycopy(NULL, 0, src, dst_obj, dst_offset_in_bytes, (T*) NULL, length);                
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
322   }                                                                                                                                  
323 
324   template <typename T>                                                                                                              
325   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,                                                     
326                                    arrayOop dst_obj, size_t dst_offset_in_bytes,                                                     
327                                    size_t length) {                                                                                  
328     return HeapAccess<decorators | IN_HEAP_ARRAY>::oop_arraycopy(src_obj, src_offset_in_bytes, (const T*) NULL,                      
329                                                                  dst_obj, dst_offset_in_bytes, (T*) NULL, length);                   
                                                                                                                                     
330   }                                                                                                                                  
331 
332   template <typename T>                                                                                                              
333   static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {                                                              
334     return HeapAccess<decorators | IN_HEAP_ARRAY>::oop_arraycopy(NULL, 0, src, NULL, 0, dst, length);                                
                                                                                                                                     
                                                                                                                                     
335   }                                                                                                                                  
336 
337 };                                                                                                                                   
338 
339 template <DecoratorSet decorators>                                                                                                   
340 template <DecoratorSet expected_decorators>                                                                                          
341 void Access<decorators>::verify_decorators() {                                                                                       
342   STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used                                              
343   const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;                                                   
344   STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set                   
345     (barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||                                                                          
346     (barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||                                                                  
347     (barrier_strength_decorators ^ AS_RAW) == 0 ||                                                                                   
348     (barrier_strength_decorators ^ AS_NORMAL) == 0                                                                                   
349   ));                                                                                                                                
350   const DecoratorSet ref_strength_decorators = decorators & ON_DECORATOR_MASK;                                                       
351   STATIC_ASSERT(ref_strength_decorators == 0 || ( // make sure ref strength decorators are disjoint if set                           
352     (ref_strength_decorators ^ ON_STRONG_OOP_REF) == 0 ||                                                                            
353     (ref_strength_decorators ^ ON_WEAK_OOP_REF) == 0 ||                                                                              

283 };
284 
285 // Helper for performing raw accesses (knows only of memory ordering
286 // atomicity decorators as well as compressed oops)
287 template <DecoratorSet decorators = INTERNAL_EMPTY>
288 class RawAccess: public Access<AS_RAW | decorators> {};
289 
290 // Helper for performing normal accesses on the heap. These accesses
291 // may resolve an accessor on a GC barrier set
292 template <DecoratorSet decorators = INTERNAL_EMPTY>
293 class HeapAccess: public Access<IN_HEAP | decorators> {};
294 
295 // Helper for performing normal accesses in roots. These accesses
296 // may resolve an accessor on a GC barrier set
297 template <DecoratorSet decorators = INTERNAL_EMPTY>
298 class RootAccess: public Access<IN_ROOT | decorators> {};
299 
300 // Helper for array access.
301 template <DecoratorSet decorators = INTERNAL_EMPTY>
302 class ArrayAccess: public HeapAccess<IN_HEAP_ARRAY | decorators> {
303   typedef HeapAccess<IN_HEAP_ARRAY | decorators> AccessT;
304 public:
305   template <typename T>
306   static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
307                                arrayOop dst_obj, size_t dst_offset_in_bytes,
308                                size_t length) {
309     AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
310                        dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
311                        length);
312   }
313 
314   template <typename T>
315   static inline void arraycopy_to_native(arrayOop src_obj, size_t src_offset_in_bytes,
316                                          T* dst,
317                                          size_t length) {
318     AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
319                        NULL, 0, dst,
320                        length);
321   }
322 
323   template <typename T>
324   static inline void arraycopy_from_native(const T* src,
325                                            arrayOop dst_obj, size_t dst_offset_in_bytes,
326                                            size_t length) {
327     AccessT::arraycopy(NULL, 0, src,
328                        dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
329                        length);
330   }
331 

332   static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
333                                    arrayOop dst_obj, size_t dst_offset_in_bytes,
334                                    size_t length) {
335     return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const HeapWord*>(NULL),
336                                   dst_obj, dst_offset_in_bytes, reinterpret_cast<HeapWord*>(NULL),
337                                   length);
338   }
339 
340   template <typename T>
341   static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {
342     return AccessT::oop_arraycopy(NULL, 0, src,
343                                   NULL, 0, dst,
344                                   length);
345   }
346 
347 };
348 
349 template <DecoratorSet decorators>
350 template <DecoratorSet expected_decorators>
351 void Access<decorators>::verify_decorators() {
352   STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used
353   const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;
354   STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set
355     (barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||
356     (barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||
357     (barrier_strength_decorators ^ AS_RAW) == 0 ||
358     (barrier_strength_decorators ^ AS_NORMAL) == 0
359   ));
360   const DecoratorSet ref_strength_decorators = decorators & ON_DECORATOR_MASK;
361   STATIC_ASSERT(ref_strength_decorators == 0 || ( // make sure ref strength decorators are disjoint if set
362     (ref_strength_decorators ^ ON_STRONG_OOP_REF) == 0 ||
363     (ref_strength_decorators ^ ON_WEAK_OOP_REF) == 0 ||
< prev index next >