75 // BarrierSet::AccessBarrier accessor that attaches GC-required barriers
76 // to the access.
77 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch
78 // happens for an access. The appropriate BarrierSet::AccessBarrier accessor
79 // is resolved, then the function pointer is updated to that accessor for
80 // future invocations.
81 // * Step 5.b: Post-runtime dispatch. This step now casts previously unknown types such
82 // as the address type of an oop on the heap (is it oop* or narrowOop*) to
83 // the appropriate type. It also splits sufficiently orthogonal accesses into
84 // different functions, such as whether the access involves oops or primitives
85 // and whether the access is performed on the heap or outside. Then the
86 // appropriate BarrierSet::AccessBarrier is called to perform the access.
87 //
88 // The implementation of step 1-4 resides in in accessBackend.hpp, to allow selected
89 // accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
90 // Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
91 // include the various GC backend .inline.hpp headers. Their implementation resides in
92 // access.inline.hpp. The accesses that are allowed through the access.hpp file
93 // must be instantiated in access.cpp using the INSTANTIATE_HPP_ACCESS macro.
94
95 template <DecoratorSet decorators = INTERNAL_EMPTY>
96 class Access: public AllStatic {
97 // This function asserts that if an access gets passed in a decorator outside
98 // of the expected_decorators, then something is wrong. It additionally checks
99 // the consistency of the decorators so that supposedly disjoint decorators are indeed
100 // disjoint. For example, an access can not be both in heap and on root at the
101 // same time.
102 template <DecoratorSet expected_decorators>
103 static void verify_decorators();
104
105 template <DecoratorSet expected_mo_decorators>
106 static void verify_primitive_decorators() {
107 const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE) |
108 IN_HEAP | IS_ARRAY;
109 verify_decorators<expected_mo_decorators | primitive_decorators>();
110 }
111
112 template <DecoratorSet expected_mo_decorators>
113 static void verify_oop_decorators() {
114 const DecoratorSet oop_decorators = AS_DECORATOR_MASK | IN_DECORATOR_MASK |
115 (ON_DECORATOR_MASK ^ ON_UNKNOWN_OOP_REF) | // no unknown oop refs outside of the heap
255 }
256
257 template <typename P, typename T>
258 static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {
259 verify_oop_decorators<atomic_cmpxchg_mo_decorators>();
260 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
261 OopType new_oop_value = new_value;
262 OopType compare_oop_value = compare_value;
263 return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);
264 }
265
266 template <typename P, typename T>
267 static inline T oop_atomic_xchg(T new_value, P* addr) {
268 verify_oop_decorators<atomic_xchg_mo_decorators>();
269 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
270 OopType new_oop_value = new_value;
271 return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
272 }
273
274 static oop resolve(oop obj) {
275 verify_decorators<INTERNAL_EMPTY>();
276 return AccessInternal::resolve<decorators>(obj);
277 }
278
279 static bool equals(oop o1, oop o2) {
280 verify_decorators<AS_RAW>();
281 return AccessInternal::equals<decorators>(o1, o2);
282 }
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 NativeAccess: public Access<IN_NATIVE | decorators> {};
299
300 // Helper for array access.
301 template <DecoratorSet decorators = INTERNAL_EMPTY>
302 class ArrayAccess: public HeapAccess<IS_ARRAY | decorators> {
303 typedef HeapAccess<IS_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 }
|
75 // BarrierSet::AccessBarrier accessor that attaches GC-required barriers
76 // to the access.
77 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch
78 // happens for an access. The appropriate BarrierSet::AccessBarrier accessor
79 // is resolved, then the function pointer is updated to that accessor for
80 // future invocations.
81 // * Step 5.b: Post-runtime dispatch. This step now casts previously unknown types such
82 // as the address type of an oop on the heap (is it oop* or narrowOop*) to
83 // the appropriate type. It also splits sufficiently orthogonal accesses into
84 // different functions, such as whether the access involves oops or primitives
85 // and whether the access is performed on the heap or outside. Then the
86 // appropriate BarrierSet::AccessBarrier is called to perform the access.
87 //
88 // The implementation of step 1-4 resides in in accessBackend.hpp, to allow selected
89 // accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
90 // Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
91 // include the various GC backend .inline.hpp headers. Their implementation resides in
92 // access.inline.hpp. The accesses that are allowed through the access.hpp file
93 // must be instantiated in access.cpp using the INSTANTIATE_HPP_ACCESS macro.
94
95 template <DecoratorSet decorators = DECORATORS_NONE>
96 class Access: public AllStatic {
97 // This function asserts that if an access gets passed in a decorator outside
98 // of the expected_decorators, then something is wrong. It additionally checks
99 // the consistency of the decorators so that supposedly disjoint decorators are indeed
100 // disjoint. For example, an access can not be both in heap and on root at the
101 // same time.
102 template <DecoratorSet expected_decorators>
103 static void verify_decorators();
104
105 template <DecoratorSet expected_mo_decorators>
106 static void verify_primitive_decorators() {
107 const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE) |
108 IN_HEAP | IS_ARRAY;
109 verify_decorators<expected_mo_decorators | primitive_decorators>();
110 }
111
112 template <DecoratorSet expected_mo_decorators>
113 static void verify_oop_decorators() {
114 const DecoratorSet oop_decorators = AS_DECORATOR_MASK | IN_DECORATOR_MASK |
115 (ON_DECORATOR_MASK ^ ON_UNKNOWN_OOP_REF) | // no unknown oop refs outside of the heap
255 }
256
257 template <typename P, typename T>
258 static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {
259 verify_oop_decorators<atomic_cmpxchg_mo_decorators>();
260 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
261 OopType new_oop_value = new_value;
262 OopType compare_oop_value = compare_value;
263 return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);
264 }
265
266 template <typename P, typename T>
267 static inline T oop_atomic_xchg(T new_value, P* addr) {
268 verify_oop_decorators<atomic_xchg_mo_decorators>();
269 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
270 OopType new_oop_value = new_value;
271 return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
272 }
273
274 static oop resolve(oop obj) {
275 verify_decorators<DECORATORS_NONE>();
276 return AccessInternal::resolve<decorators>(obj);
277 }
278
279 static bool equals(oop o1, oop o2) {
280 verify_decorators<AS_RAW>();
281 return AccessInternal::equals<decorators>(o1, o2);
282 }
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 = DECORATORS_NONE>
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 = DECORATORS_NONE>
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 = DECORATORS_NONE>
298 class NativeAccess: public Access<IN_NATIVE | decorators> {};
299
300 // Helper for array access.
301 template <DecoratorSet decorators = DECORATORS_NONE>
302 class ArrayAccess: public HeapAccess<IS_ARRAY | decorators> {
303 typedef HeapAccess<IS_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 }
|