< prev index next >

src/hotspot/share/oops/access.hpp

less_template_poop_in_access_hpp

erik_version

roman_version

4  * This code is free software; you can redistribute it and/or modify it                                                              
5  * under the terms of the GNU General Public License version 2 only, as                                                              
6  * published by the Free Software Foundation.                                                                                        
7  *                                                                                                                                   
8  * This code is distributed in the hope that it will be useful, but WITHOUT                                                          
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or                                                             
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License                                                             
11  * version 2 for more details (a copy is included in the LICENSE file that                                                           
12  * accompanied this code).                                                                                                           
13  *                                                                                                                                   
14  * You should have received a copy of the GNU General Public License version                                                         
15  * 2 along with this work; if not, write to the Free Software Foundation,                                                            
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                                                                     
17  *                                                                                                                                   
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA                                                           
19  * or visit www.oracle.com if you need additional information or have any                                                            
20  * questions.                                                                                                                        
21  *                                                                                                                                   
22  */                                                                                                                                  
23 
24 #ifndef SHARE_VM_RUNTIME_ACCESS_HPP                                                                                                  
25 #define SHARE_VM_RUNTIME_ACCESS_HPP                                                                                                  
26 
27 #include "memory/allocation.hpp"                                                                                                     
28 #include "metaprogramming/decay.hpp"                                                                                                 
29 #include "metaprogramming/integralConstant.hpp"                                                                                      
30 #include "oops/oopsHierarchy.hpp"                                                                                                    
31 #include "utilities/debug.hpp"                                                                                                       
32 #include "utilities/globalDefinitions.hpp"                                                                                           
33 
                                                                                                                                     
34 // = GENERAL =                                                                                                                       
35 // Access is an API for performing accesses with declarative semantics. Each access can have a number of "decorators".               
36 // A decorator is an attribute or property that affects the way a memory access is performed in some way.                            
37 // There are different groups of decorators. Some have to do with memory ordering, others to do with,                                
38 // e.g. strength of references, strength of GC barriers, or whether compression should be applied or not.                            
39 // Some decorators are set at buildtime, such as whether primitives require GC barriers or not, others                               
40 // at callsites such as whether an access is in the heap or not, and others are resolved at runtime                                  
41 // such as GC-specific barriers and encoding/decoding compressed oops.                                                               
                                                                                                                                     
42 // By pipelining handling of these decorators, the design of the Access API allows separation of concern                             
43 // over the different orthogonal concerns of decorators, while providing a powerful way of                                           
44 // expressing these orthogonal semantic properties in a unified way.                                                                 
45                                                                                                                                      
46 // == OPERATIONS ==                                                                                                                  
47 // * load: Load a value from an address.                                                                                             
48 // * load_at: Load a value from an internal pointer relative to a base object.                                                       
49 // * store: Store a value at an address.                                                                                             
50 // * store_at: Store a value in an internal pointer relative to a base object.                                                       
51 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.             
52 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared
53 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.                            
54 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.        
55 // * arraycopy: Copy data from one heap array to another heap array.                                                                 
56 // * clone: Clone the contents of an object to a newly allocated object.                                                             
57 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transi
58                                                                                                                                      
59 typedef uint64_t DecoratorSet;                                                                                                       
60                                                                                                                                      
61 // == Internal Decorators - do not use ==                                                                                            
62 // * INTERNAL_EMPTY: This is the name for the empty decorator set (in absence of other decorators).                                  
63 // * INTERNAL_CONVERT_COMPRESSED_OOPS: This is an oop access that will require converting an oop                                     
64 //   to a narrowOop or vice versa, if UseCompressedOops is known to be set.                                                          
65 // * INTERNAL_VALUE_IS_OOP: Remember that the involved access is on oop rather than primitive.                                       
66 const DecoratorSet INTERNAL_EMPTY                    = UCONST64(0);                                                                  
67 const DecoratorSet INTERNAL_CONVERT_COMPRESSED_OOP   = UCONST64(1) << 1;                                                             
68 const DecoratorSet INTERNAL_VALUE_IS_OOP             = UCONST64(1) << 2;                                                             
69                                                                                                                                      
70 // == Internal build-time Decorators ==                                                                                              
71 // * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.                                                
72 // * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff                                                
73 //   no GC is bundled in the build that is to-space invariant.                                                                       
74 const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;                                                             
75 const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT    = UCONST64(1) << 4;                                                             
76                                                                                                                                      
77 // == Internal run-time Decorators ==                                                                                                
78 // * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved                                                 
79 //   access backends iff UseCompressedOops is true.                                                                                  
80 const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS   = UCONST64(1) << 5;                                                             
81                                                                                                                                      
82 const DecoratorSet INTERNAL_DECORATOR_MASK           = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |                     
83                                                        INTERNAL_BT_BARRIER_ON_PRIMITIVES | INTERNAL_RT_USE_COMPRESSED_OOPS;          
84                                                                                                                                      
85 // == Memory Ordering Decorators ==                                                                                                  
86 // The memory ordering decorators can be described in the following way:                                                             
87 // === Decorator Rules ===                                                                                                           
88 // The different types of memory ordering guarantees have a strict order of strength.                                                
89 // Explicitly specifying the stronger ordering implies that the guarantees of the weaker                                             
90 // property holds too. The names come from the C++11 atomic operations, and typically                                                
91 // have a JMM equivalent property.                                                                                                   
92 // The equivalence may be viewed like this:                                                                                          
93 // MO_UNORDERED is equivalent to JMM plain.                                                                                          
94 // MO_VOLATILE has no equivalence in JMM, because it's a C++ thing.                                                                  
95 // MO_RELAXED is equivalent to JMM opaque.                                                                                           
96 // MO_ACQUIRE is equivalent to JMM acquire.                                                                                          
97 // MO_RELEASE is equivalent to JMM release.                                                                                          
98 // MO_SEQ_CST is equivalent to JMM volatile.                                                                                         
99 //                                                                                                                                   
100 // === Stores ===                                                                                                                    
101 //  * MO_UNORDERED (Default): No guarantees.                                                                                         
102 //    - The compiler and hardware are free to reorder aggressively. And they will.                                                   
103 //  * MO_VOLATILE: Volatile stores (in the C++ sense).                                                                               
104 //    - The stores are not reordered by the compiler (but possibly the HW) w.r.t. other                                              
105 //      volatile accesses in program order (but possibly non-volatile accesses).                                                     
106 //  * MO_RELAXED: Relaxed atomic stores.                                                                                             
107 //    - The stores are atomic.                                                                                                       
108 //    - Guarantees from volatile stores hold.                                                                                        
109 //  * MO_RELEASE: Releasing stores.                                                                                                  
110 //    - The releasing store will make its preceding memory accesses observable to memory accesses                                    
111 //      subsequent to an acquiring load observing this releasing store.                                                              
112 //    - Guarantees from relaxed stores hold.                                                                                         
113 //  * MO_SEQ_CST: Sequentially consistent stores.                                                                                    
114 //    - The stores are observed in the same order by MO_SEQ_CST loads on other processors                                            
115 //    - Preceding loads and stores in program order are not reordered with subsequent loads and stores in program order.             
116 //    - Guarantees from releasing stores hold.                                                                                       
117 // === Loads ===                                                                                                                     
118 //  * MO_UNORDERED (Default): No guarantees                                                                                          
119 //    - The compiler and hardware are free to reorder aggressively. And they will.                                                   
120 //  * MO_VOLATILE: Volatile loads (in the C++ sense).                                                                                
121 //    - The loads are not reordered by the compiler (but possibly the HW) w.r.t. other                                               
122 //      volatile accesses in program order (but possibly non-volatile accesses).                                                     
123 //  * MO_RELAXED: Relaxed atomic loads.                                                                                              
124 //    - The stores are atomic.                                                                                                       
125 //    - Guarantees from volatile loads hold.                                                                                         
126 //  * MO_ACQUIRE: Acquiring loads.                                                                                                   
127 //    - An acquiring load will make subsequent memory accesses observe the memory accesses                                           
128 //      preceding the releasing store that the acquiring load observed.                                                              
129 //    - Guarantees from relaxed loads hold.                                                                                          
130 //  * MO_SEQ_CST: Sequentially consistent loads.                                                                                     
131 //    - These loads observe MO_SEQ_CST stores in the same order on other processors                                                  
132 //    - Preceding loads and stores in program order are not reordered with subsequent loads and stores in program order.             
133 //    - Guarantees from acquiring loads hold.                                                                                        
134 // === Atomic Cmpxchg ===                                                                                                            
135 //  * MO_RELAXED: Atomic but relaxed cmpxchg.                                                                                        
136 //    - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold unconditionally.                                                 
137 //  * MO_SEQ_CST: Sequentially consistent cmpxchg.                                                                                   
138 //    - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold unconditionally.                                                 
139 // === Atomic Xchg ===                                                                                                               
140 //  * MO_RELAXED: Atomic but relaxed atomic xchg.                                                                                    
141 //    - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.                                                                 
142 //  * MO_SEQ_CST: Sequentially consistent xchg.                                                                                      
143 //    - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.                                                                 
144 const DecoratorSet MO_UNORDERED      = UCONST64(1) << 6;                                                                             
145 const DecoratorSet MO_VOLATILE       = UCONST64(1) << 7;                                                                             
146 const DecoratorSet MO_RELAXED        = UCONST64(1) << 8;                                                                             
147 const DecoratorSet MO_ACQUIRE        = UCONST64(1) << 9;                                                                             
148 const DecoratorSet MO_RELEASE        = UCONST64(1) << 10;                                                                            
149 const DecoratorSet MO_SEQ_CST        = UCONST64(1) << 11;                                                                            
150 const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |                                                     
151                                        MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;                                                         
152                                                                                                                                      
153 // === Barrier Strength Decorators ===                                                                                               
154 // * AS_RAW: The access will translate into a raw memory access, hence ignoring all semantic concerns                                
155 //   except memory ordering and compressed oops. This will bypass runtime function pointer dispatching                               
156 //   in the pipeline and hardwire to raw accesses without going trough the GC access barriers.                                       
157 //  - Accesses on oop* translate to raw memory accesses without runtime checks                                                       
158 //  - Accesses on narrowOop* translate to encoded/decoded memory accesses without runtime checks                                     
159 //  - Accesses on HeapWord* translate to a runtime check choosing one of the above                                                   
160 //  - Accesses on other types translate to raw memory accesses without runtime checks                                                
161 // * AS_DEST_NOT_INITIALIZED: This property can be important to e.g. SATB barriers by                                                
162 //   marking that the previous value is uninitialized nonsense rather than a real value.                                             
163 // * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects                              
164 //   alive, regardless of the type of reference being accessed. It will however perform the memory access                            
165 //   in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed,                               
166 //   or maintain, e.g. intergenerational or interregional pointers if applicable. This should be used with                           
167 //   extreme caution in isolated scopes.                                                                                             
168 // * AS_NORMAL: The accesses will be resolved to an accessor on the BarrierSet class, giving the                                     
169 //   responsibility of performing the access and what barriers to be performed to the GC. This is the default.                       
170 //   Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time                             
171 //   decorator for enabling primitive barriers is enabled for the build.                                                             
172 const DecoratorSet AS_RAW                  = UCONST64(1) << 12;                                                                      
173 const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 13;                                                                      
174 const DecoratorSet AS_NO_KEEPALIVE         = UCONST64(1) << 14;                                                                      
175 const DecoratorSet AS_NORMAL               = UCONST64(1) << 15;                                                                      
176 const DecoratorSet AS_DECORATOR_MASK       = AS_RAW | AS_DEST_NOT_INITIALIZED |                                                      
177                                              AS_NO_KEEPALIVE | AS_NORMAL;                                                            
178                                                                                                                                      
179 // === Reference Strength Decorators ===                                                                                             
180 // These decorators only apply to accesses on oop-like types (oop/narrowOop).                                                        
181 // * ON_STRONG_OOP_REF: Memory access is performed on a strongly reachable reference.                                                
182 // * ON_WEAK_OOP_REF: The memory access is performed on a weakly reachable reference.                                                
183 // * ON_PHANTOM_OOP_REF: The memory access is performed on a phantomly reachable reference.                                          
184 //   This is the same ring of strength as jweak and weak oops in the VM.                                                             
185 // * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.                                          
186 //   This could for example come from the unsafe API.                                                                                
187 // * Default (no explicit reference strength specified): ON_STRONG_OOP_REF                                                           
188 const DecoratorSet ON_STRONG_OOP_REF  = UCONST64(1) << 16;                                                                           
189 const DecoratorSet ON_WEAK_OOP_REF    = UCONST64(1) << 17;                                                                           
190 const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;                                                                           
191 const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;                                                                           
192 const DecoratorSet ON_DECORATOR_MASK  = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |                                                        
193                                         ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;                                                     
194                                                                                                                                      
195 // === Access Location ===                                                                                                           
196 // Accesses can take place in, e.g. the heap, old or young generation and different native roots.                                    
197 // The location is important to the GC as it may imply different actions. The following decorators are used:                         
198 // * IN_HEAP: The access is performed in the heap. Many barriers such as card marking will                                           
199 //   be omitted if this decorator is not set.                                                                                        
200 // * IN_HEAP_ARRAY: The access is performed on a heap allocated array. This is sometimes a special case                              
201 //   for some GCs, and implies that it is an IN_HEAP.                                                                                
202 // * IN_ROOT: The access is performed in an off-heap data structure pointing into the Java heap.                                     
203 // * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,                          
204 //   but is notably not scanned during safepoints. This is sometimes a special case for some GCs and                                 
205 //   implies that it is also an IN_ROOT.                                                                                             
206 const DecoratorSet IN_HEAP            = UCONST64(1) << 20;                                                                           
207 const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 21;                                                                           
208 const DecoratorSet IN_ROOT            = UCONST64(1) << 22;                                                                           
209 const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;                                                                           
210 const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 24;                                                                           
211 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_HEAP_ARRAY |                                                                    
212                                         IN_ROOT | IN_CONCURRENT_ROOT |                                                               
213                                         IN_ARCHIVE_ROOT;                                                                             
214                                                                                                                                      
215 // == Value Decorators ==                                                                                                            
216 // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.                                          
217 const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 25;                                                                           
218 const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;                                                                                
219                                                                                                                                      
220 // == Arraycopy Decorators ==                                                                                                        
221 // * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source                                                
222 //   are not guaranteed to be subclasses of the class of the destination array. This requires                                        
223 //   a check-cast barrier during the copying operation. If this is not set, it is assumed                                            
224 //   that the array is covariant: (the source array type is-a destination array type)                                                
225 // * ARRAYCOPY_DISJOINT: This property means that it is known that the two array ranges                                              
226 //   are disjoint.                                                                                                                   
227 // * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.                                                                             
228 // * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.                                                 
229 // * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.                                                               
230 const DecoratorSet ARRAYCOPY_CHECKCAST            = UCONST64(1) << 26;                                                               
231 const DecoratorSet ARRAYCOPY_DISJOINT             = UCONST64(1) << 27;                                                               
232 const DecoratorSet ARRAYCOPY_ARRAYOF              = UCONST64(1) << 28;                                                               
233 const DecoratorSet ARRAYCOPY_ATOMIC               = UCONST64(1) << 29;                                                               
234 const DecoratorSet ARRAYCOPY_ALIGNED              = UCONST64(1) << 30;                                                               
235 const DecoratorSet ARRAYCOPY_DECORATOR_MASK       = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |                                       
236                                                     ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |                                         
237                                                     ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;                                            
238                                                                                                                                      
239 // The HasDecorator trait can help at compile-time determining whether a decorator set                                               
240 // has an intersection with a certain other decorator set                                                                            
241 template <DecoratorSet decorators, DecoratorSet decorator>                                                                           
242 struct HasDecorator: public IntegralConstant<bool, (decorators & decorator) != 0> {};                                                
243                                                                                                                                      
244 namespace AccessInternal {                                                                                                           
245   template <typename T>                                                                                                              
246   struct OopOrNarrowOopInternal: AllStatic {                                                                                         
247     typedef oop type;                                                                                                                
248   };                                                                                                                                 
249                                                                                                                                      
250   template <>                                                                                                                        
251   struct OopOrNarrowOopInternal<narrowOop>: AllStatic {                                                                              
252     typedef narrowOop type;                                                                                                          
253   };                                                                                                                                 
254                                                                                                                                      
255   // This metafunction returns a canonicalized oop/narrowOop type for a passed                                                       
256   // in oop-like types passed in from oop_* overloads where the user has sworn                                                       
257   // that the passed in values should be oop-like (e.g. oop, oopDesc*, arrayOop,                                                     
258   // narrowOoop, instanceOopDesc*, and random other things).                                                                         
259   // In the oop_* overloads, it must hold that if the passed in type T is not                                                        
260   // narrowOop, then it by contract has to be one of many oop-like types implicitly                                                  
261   // convertible to oop, and hence returns oop as the canonical oop type.                                                            
262   // If it turns out it was not, then the implicit conversion to oop will fail                                                       
263   // to compile, as desired.                                                                                                         
264   template <typename T>                                                                                                              
265   struct OopOrNarrowOop: AllStatic {                                                                                                 
266     typedef typename OopOrNarrowOopInternal<typename Decay<T>::type>::type type;                                                     
267   };                                                                                                                                 
268                                                                                                                                      
269   inline void* field_addr(oop base, ptrdiff_t byte_offset) {                                                                         
270     return reinterpret_cast<void*>(reinterpret_cast<intptr_t>((void*)base) + byte_offset);                                           
271   }                                                                                                                                  
272                                                                                                                                      
273   template <DecoratorSet decorators, typename T>                                                                                     
274   void store_at(oop base, ptrdiff_t offset, T value);                                                                                
275                                                                                                                                      
276   template <DecoratorSet decorators, typename T>                                                                                     
277   T load_at(oop base, ptrdiff_t offset);                                                                                             
278                                                                                                                                      
279   template <DecoratorSet decorators, typename T>                                                                                     
280   T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value);                                                     
281                                                                                                                                      
282   template <DecoratorSet decorators, typename T>                                                                                     
283   T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset);                                                                         
284                                                                                                                                      
285   template <DecoratorSet decorators, typename P, typename T>                                                                         
286   void store(P* addr, T value);                                                                                                      
287                                                                                                                                      
288   template <DecoratorSet decorators, typename P, typename T>                                                                         
289   T load(P* addr);                                                                                                                   
290                                                                                                                                      
291   template <DecoratorSet decorators, typename P, typename T>                                                                         
292   T atomic_cmpxchg(T new_value, P* addr, T compare_value);                                                                           
293                                                                                                                                      
294   template <DecoratorSet decorators, typename P, typename T>                                                                         
295   T atomic_xchg(T new_value, P* addr);                                                                                               
296                                                                                                                                      
297   template <DecoratorSet decorators, typename T>                                                                                     
298   bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length);                                                 
299                                                                                                                                      
300   template <DecoratorSet decorators>                                                                                                 
301   void clone(oop src, oop dst, size_t size);                                                                                         
302                                                                                                                                      
303   template <DecoratorSet decorators>                                                                                                 
304   oop resolve(oop src);                                                                                                              
305                                                                                                                                      
306   // Infer the type that should be returned from a load.                                                                             
307   template <typename P, DecoratorSet decorators>                                                                                     
308   class OopLoadProxy: public StackObj {                                                                                              
309   private:                                                                                                                           
310     P *const _addr;                                                                                                                  
311   public:                                                                                                                            
312     OopLoadProxy(P* addr) : _addr(addr) {}                                                                                           
313                                                                                                                                      
314     inline operator oop() {                                                                                                          
315       return load<decorators | INTERNAL_VALUE_IS_OOP, P, oop>(_addr);                                                                
316     }                                                                                                                                
317                                                                                                                                      
318     inline operator narrowOop() {                                                                                                    
319       return load<decorators | INTERNAL_VALUE_IS_OOP, P, narrowOop>(_addr);                                                          
320     }                                                                                                                                
321                                                                                                                                      
322     template <typename T>                                                                                                            
323     inline bool operator ==(const T& other) const {                                                                                  
324       return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) == other;                                                         
325     }                                                                                                                                
326                                                                                                                                      
327     template <typename T>                                                                                                            
328     inline bool operator !=(const T& other) const {                                                                                  
329       return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) != other;                                                         
330     }                                                                                                                                
331   };                                                                                                                                 
332                                                                                                                                      
333   // Infer the type that should be returned from a load_at.                                                                          
334   template <DecoratorSet decorators>                                                                                                 
335   class LoadAtProxy: public StackObj {                                                                                               
336   private:                                                                                                                           
337     const oop _base;                                                                                                                 
338     const ptrdiff_t _offset;                                                                                                         
339   public:                                                                                                                            
340     LoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}                                                        
341                                                                                                                                      
342     template <typename T>                                                                                                            
343     inline operator T() const {                                                                                                      
344       return load_at<decorators, T>(_base, _offset);                                                                                 
345     }                                                                                                                                
346                                                                                                                                      
347     template <typename T>                                                                                                            
348     inline bool operator ==(const T& other) const { return load_at<decorators, T>(_base, _offset) == other; }                        
349                                                                                                                                      
350     template <typename T>                                                                                                            
351     inline bool operator !=(const T& other) const { return load_at<decorators, T>(_base, _offset) != other; }                        
352   };                                                                                                                                 
353                                                                                                                                      
354   template <DecoratorSet decorators>                                                                                                 
355   class OopLoadAtProxy: public StackObj {                                                                                            
356   private:                                                                                                                           
357     const oop _base;                                                                                                                 
358     const ptrdiff_t _offset;                                                                                                         
359   public:                                                                                                                            
360     OopLoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}                                                     
361                                                                                                                                      
362     inline operator oop() const {                                                                                                    
363       return load_at<decorators | INTERNAL_VALUE_IS_OOP, oop>(_base, _offset);                                                       
364     }                                                                                                                                
365                                                                                                                                      
366     inline operator narrowOop() const {                                                                                              
367       return load_at<decorators | INTERNAL_VALUE_IS_OOP, narrowOop>(_base, _offset);                                                 
368     }                                                                                                                                
369                                                                                                                                      
370     template <typename T>                                                                                                            
371     inline bool operator ==(const T& other) const {                                                                                  
372       return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) == other;                                                
373     }                                                                                                                                
374                                                                                                                                      
375     template <typename T>                                                                                                            
376     inline bool operator !=(const T& other) const {                                                                                  
377       return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) != other;                                                
378     }                                                                                                                                
379   };                                                                                                                                 
380 }                                                                                                                                    
381 
382 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
383 class Access: public AllStatic {                                                                                                     
384   // This function asserts that if an access gets passed in a decorator outside                                                      
385   // of the expected_decorators, then something is wrong. It additionally checks                                                     
386   // the consistency of the decorators so that supposedly disjoint decorators are indeed                                             
387   // disjoint. For example, an access can not be both in heap and on root at the                                                     
388   // same time.                                                                                                                      
389   template <DecoratorSet expected_decorators>                                                                                        
390   static void verify_decorators();                                                                                                   
391 
392   template <DecoratorSet expected_mo_decorators>                                                                                     
393   static void verify_primitive_decorators() {                                                                                        
394     const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |                      
395                                               IN_HEAP | IN_HEAP_ARRAY;                                                               
396     verify_decorators<expected_mo_decorators | primitive_decorators>();                                                              
397   }                                                                                                                                  
398 
399   template <DecoratorSet expected_mo_decorators>                                                                                     

4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  *
22  */
23 
24 #ifndef SHARE_OOPS_ACCESS_HPP
25 #define SHARE_OOPS_ACCESS_HPP
26 
27 #include "memory/allocation.hpp"
28 #include "oops/accessBackend.hpp"
29 #include "oops/accessDecorators.hpp"
30 #include "oops/oopsHierarchy.hpp"
31 #include "utilities/debug.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 
34 
35 // = GENERAL =
36 // Access is an API for performing accesses with declarative semantics. Each access can have a number of "decorators".
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
77 //             happens for an access. The appropriate BarrierSet::AccessBarrier accessor
78 //             is resolved, then the function pointer is updated to that accessor for
79 //             future invocations.
80 // * Step 5.b: Post-runtime dispatch. This step now casts previously unknown types such
81 //             as the address type of an oop on the heap (is it oop* or narrowOop*) to
82 //             the appropriate type. It also splits sufficiently orthogonal accesses into
83 //             different functions, such as whether the access involves oops or primitives
84 //             and whether the access is performed on the heap or outside. Then the
85 //             appropriate BarrierSet::AccessBarrier is called to perform the access.
86 //
87 // The implementation of step 1-4 resides in in accessBackend.hpp, to allow selected
88 // accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
89 // Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
90 // include the various GC backend .inline.hpp headers. Their implementation resides in
91 // access.inline.hpp. The accesses that are allowed through the access.hpp file
92 // must be instantiated in access.cpp using the INSTANTIATE_HPP_ACCESS macro.


























































































































































































































































93 
94 template <DecoratorSet decorators = INTERNAL_EMPTY>
95 class Access: public AllStatic {
96   // This function asserts that if an access gets passed in a decorator outside
97   // of the expected_decorators, then something is wrong. It additionally checks
98   // the consistency of the decorators so that supposedly disjoint decorators are indeed
99   // disjoint. For example, an access can not be both in heap and on root at the
100   // same time.
101   template <DecoratorSet expected_decorators>
102   static void verify_decorators();
103 
104   template <DecoratorSet expected_mo_decorators>
105   static void verify_primitive_decorators() {
106     const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |
107                                               IN_HEAP | IN_HEAP_ARRAY;
108     verify_decorators<expected_mo_decorators | primitive_decorators>();
109   }
110 
111   template <DecoratorSet expected_mo_decorators>

536   static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {                                                        
537     verify_oop_decorators<atomic_cmpxchg_mo_decorators>();                                                                           
538     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;                                                                
539     OopType new_oop_value = new_value;                                                                                               
540     OopType compare_oop_value = compare_value;                                                                                       
541     return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);               
542   }                                                                                                                                  
543 
544   template <typename P, typename T>                                                                                                  
545   static inline T oop_atomic_xchg(T new_value, P* addr) {                                                                            
546     verify_oop_decorators<atomic_xchg_mo_decorators>();                                                                              
547     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;                                                                
548     OopType new_oop_value = new_value;                                                                                               
549     return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);                                     
550   }                                                                                                                                  
551 
552   static oop resolve(oop obj) {                                                                                                      
553     verify_decorators<INTERNAL_EMPTY>();                                                                                             
554     return AccessInternal::resolve<decorators>(obj);                                                                                 
555   }                                                                                                                                  
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
556 };                                                                                                                                   
557 
558 // Helper for performing raw accesses (knows only of memory ordering                                                                 
559 // atomicity decorators as well as compressed oops)                                                                                  
560 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
561 class RawAccess: public Access<AS_RAW | decorators> {};                                                                              
562 
563 // Helper for performing normal accesses on the heap. These accesses                                                                 
564 // may resolve an accessor on a GC barrier set                                                                                       
565 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
566 class HeapAccess: public Access<IN_HEAP | decorators> {};                                                                            
567 
568 // Helper for performing normal accesses in roots. These accesses                                                                    
569 // may resolve an accessor on a GC barrier set                                                                                       
570 template <DecoratorSet decorators = INTERNAL_EMPTY>                                                                                  
571 class RootAccess: public Access<IN_ROOT | decorators> {};                                                                            
572 
573 #endif // SHARE_VM_RUNTIME_ACCESS_HPP                                                                                                
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     
                                                                                                                                     

248   static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {
249     verify_oop_decorators<atomic_cmpxchg_mo_decorators>();
250     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
251     OopType new_oop_value = new_value;
252     OopType compare_oop_value = compare_value;
253     return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);
254   }
255 
256   template <typename P, typename T>
257   static inline T oop_atomic_xchg(T new_value, P* addr) {
258     verify_oop_decorators<atomic_xchg_mo_decorators>();
259     typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
260     OopType new_oop_value = new_value;
261     return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
262   }
263 
264   static oop resolve(oop obj) {
265     verify_decorators<INTERNAL_EMPTY>();
266     return AccessInternal::resolve<decorators>(obj);
267   }
268 
269   static bool equals(oop o1, oop o2) {
270     verify_decorators<INTERNAL_EMPTY>();
271     return AccessInternal::equals<decorators>(o1, o2);
272   }
273 };
274 
275 // Helper for performing raw accesses (knows only of memory ordering
276 // atomicity decorators as well as compressed oops)
277 template <DecoratorSet decorators = INTERNAL_EMPTY>
278 class RawAccess: public Access<AS_RAW | decorators> {};
279 
280 // Helper for performing normal accesses on the heap. These accesses
281 // may resolve an accessor on a GC barrier set
282 template <DecoratorSet decorators = INTERNAL_EMPTY>
283 class HeapAccess: public Access<IN_HEAP | decorators> {};
284 
285 // Helper for performing normal accesses in roots. These accesses
286 // may resolve an accessor on a GC barrier set
287 template <DecoratorSet decorators = INTERNAL_EMPTY>
288 class RootAccess: public Access<IN_ROOT | decorators> {};
289 
290 template <DecoratorSet decorators>
291 template <DecoratorSet expected_decorators>
292 void Access<decorators>::verify_decorators() {
293   STATIC_ASSERT((~expected_decorators & decorators) == 0); // unexpected decorator used
294   const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;
295   STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set
296     (barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||
297     (barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||
298     (barrier_strength_decorators ^ AS_RAW) == 0 ||
299     (barrier_strength_decorators ^ AS_NORMAL) == 0
300   ));
301   const DecoratorSet ref_strength_decorators = decorators & ON_DECORATOR_MASK;
302   STATIC_ASSERT(ref_strength_decorators == 0 || ( // make sure ref strength decorators are disjoint if set
303     (ref_strength_decorators ^ ON_STRONG_OOP_REF) == 0 ||
304     (ref_strength_decorators ^ ON_WEAK_OOP_REF) == 0 ||
305     (ref_strength_decorators ^ ON_PHANTOM_OOP_REF) == 0 ||
306     (ref_strength_decorators ^ ON_UNKNOWN_OOP_REF) == 0
307   ));
308   const DecoratorSet memory_ordering_decorators = decorators & MO_DECORATOR_MASK;
309   STATIC_ASSERT(memory_ordering_decorators == 0 || ( // make sure memory ordering decorators are disjoint if set
310     (memory_ordering_decorators ^ MO_UNORDERED) == 0 ||
311     (memory_ordering_decorators ^ MO_VOLATILE) == 0 ||
312     (memory_ordering_decorators ^ MO_RELAXED) == 0 ||
313     (memory_ordering_decorators ^ MO_ACQUIRE) == 0 ||
314     (memory_ordering_decorators ^ MO_RELEASE) == 0 ||
315     (memory_ordering_decorators ^ MO_SEQ_CST) == 0
316   ));
317   const DecoratorSet location_decorators = decorators & IN_DECORATOR_MASK;
318   STATIC_ASSERT(location_decorators == 0 || ( // make sure location decorators are disjoint if set
319     (location_decorators ^ IN_ROOT) == 0 ||
320     (location_decorators ^ IN_HEAP) == 0 ||
321     (location_decorators ^ (IN_HEAP | IN_HEAP_ARRAY)) == 0 ||
322     (location_decorators ^ (IN_ROOT | IN_CONCURRENT_ROOT)) == 0 ||
323     (location_decorators ^ (IN_ROOT | IN_ARCHIVE_ROOT)) == 0
324   ));
325 }
326 
327 #endif // SHARE_OOPS_ACCESS_HPP
< prev index next >