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