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.
43 // By pipelining handling of these decorators, the design of the Access API allows separation of concern
44 // over the different orthogonal concerns of decorators, while providing a powerful way of
45 // expressing these orthogonal semantic properties in a unified way.
46
47 // == OPERATIONS ==
48 // * load: Load a value from an address.
49 // * load_at: Load a value from an internal pointer relative to a base object.
50 // * store: Store a value at an address.
51 // * store_at: Store a value in an internal pointer relative to a base object.
52 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.
53 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
54 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
55 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
56 // * arraycopy: Copy data from one heap array to another heap array.
57 // * clone: Clone the contents of an object to a newly allocated object.
58 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
59
60 typedef uint64_t DecoratorSet;
61
62 // == Internal Decorators - do not use ==
63 // * INTERNAL_EMPTY: This is the name for the empty decorator set (in absence of other decorators).
64 // * INTERNAL_CONVERT_COMPRESSED_OOPS: This is an oop access that will require converting an oop
65 // to a narrowOop or vice versa, if UseCompressedOops is known to be set.
66 // * INTERNAL_VALUE_IS_OOP: Remember that the involved access is on oop rather than primitive.
67 const DecoratorSet INTERNAL_EMPTY = UCONST64(0);
68 const DecoratorSet INTERNAL_CONVERT_COMPRESSED_OOP = UCONST64(1) << 1;
69 const DecoratorSet INTERNAL_VALUE_IS_OOP = UCONST64(1) << 2;
70
71 // == Internal build-time Decorators ==
72 // * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
73 // * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
74 // no GC is bundled in the build that is to-space invariant.
75 const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
76 const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT = UCONST64(1) << 4;
77
78 // == Internal run-time Decorators ==
79 // * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
287 void store(P* addr, T value);
288
289 template <DecoratorSet decorators, typename P, typename T>
290 T load(P* addr);
291
292 template <DecoratorSet decorators, typename P, typename T>
293 T atomic_cmpxchg(T new_value, P* addr, T compare_value);
294
295 template <DecoratorSet decorators, typename P, typename T>
296 T atomic_xchg(T new_value, P* addr);
297
298 template <DecoratorSet decorators, typename T>
299 bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length);
300
301 template <DecoratorSet decorators>
302 void clone(oop src, oop dst, size_t size);
303
304 template <DecoratorSet decorators>
305 oop resolve(oop src);
306
307 // Infer the type that should be returned from a load.
308 template <typename P, DecoratorSet decorators>
309 class LoadProxy: public StackObj {
310 private:
311 P *const _addr;
312 public:
313 LoadProxy(P* addr) : _addr(addr) {}
314
315 template <typename T>
316 inline operator T() {
317 return load<decorators, P, T>(_addr);
318 }
319
320 inline operator P() {
321 return load<decorators, P, P>(_addr);
322 }
323 };
324
325 // Infer the type that should be returned from a load_at.
326 template <DecoratorSet decorators>
494 template <typename P, typename T>
495 static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {
496 verify_oop_decorators<atomic_cmpxchg_mo_decorators>();
497 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
498 OopType new_oop_value = new_value;
499 OopType compare_oop_value = compare_value;
500 return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);
501 }
502
503 template <typename P, typename T>
504 static inline T oop_atomic_xchg(T new_value, P* addr) {
505 verify_oop_decorators<atomic_xchg_mo_decorators>();
506 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
507 OopType new_oop_value = new_value;
508 return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
509 }
510
511 static oop resolve(oop obj) {
512 verify_decorators<INTERNAL_EMPTY>();
513 return AccessInternal::resolve<decorators>(obj);
514 }
515 };
516
517 // Helper for performing raw accesses (knows only of memory ordering
518 // atomicity decorators as well as compressed oops)
519 template <DecoratorSet decorators = INTERNAL_EMPTY>
520 class RawAccess: public Access<AS_RAW | decorators> {};
521
522 // Helper for performing normal accesses on the heap. These accesses
523 // may resolve an accessor on a GC barrier set
524 template <DecoratorSet decorators = INTERNAL_EMPTY>
525 class HeapAccess: public Access<IN_HEAP | decorators> {};
526
527 // Helper for performing normal accesses in roots. These accesses
528 // may resolve an accessor on a GC barrier set
529 template <DecoratorSet decorators = INTERNAL_EMPTY>
530 class RootAccess: public Access<IN_ROOT | decorators> {};
531
532 #endif // SHARE_VM_RUNTIME_ACCESS_HPP
|
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.
43 // By pipelining handling of these decorators, the design of the Access API allows separation of concern
44 // over the different orthogonal concerns of decorators, while providing a powerful way of
45 // expressing these orthogonal semantic properties in a unified way.
46
47 // == OPERATIONS ==
48 // * load: Load a value from an address.
49 // * load_at: Load a value from an internal pointer relative to a base object.
50 // * store: Store a value at an address.
51 // * store_at: Store a value in an internal pointer relative to a base object.
52 // * atomic_cmpxchg: Atomically compare-and-swap a new value at an address if previous value matched the compared value.
53 // * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
54 // * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
55 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
56 // * arraycopy: Copy data from one heap array to another heap array.
57 // * clone: Clone the contents of an object to a newly allocated object.
58 // * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
59 // * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)
60 typedef uint64_t DecoratorSet;
61
62 // == Internal Decorators - do not use ==
63 // * INTERNAL_EMPTY: This is the name for the empty decorator set (in absence of other decorators).
64 // * INTERNAL_CONVERT_COMPRESSED_OOPS: This is an oop access that will require converting an oop
65 // to a narrowOop or vice versa, if UseCompressedOops is known to be set.
66 // * INTERNAL_VALUE_IS_OOP: Remember that the involved access is on oop rather than primitive.
67 const DecoratorSet INTERNAL_EMPTY = UCONST64(0);
68 const DecoratorSet INTERNAL_CONVERT_COMPRESSED_OOP = UCONST64(1) << 1;
69 const DecoratorSet INTERNAL_VALUE_IS_OOP = UCONST64(1) << 2;
70
71 // == Internal build-time Decorators ==
72 // * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
73 // * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
74 // no GC is bundled in the build that is to-space invariant.
75 const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
76 const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT = UCONST64(1) << 4;
77
78 // == Internal run-time Decorators ==
79 // * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
287 void store(P* addr, T value);
288
289 template <DecoratorSet decorators, typename P, typename T>
290 T load(P* addr);
291
292 template <DecoratorSet decorators, typename P, typename T>
293 T atomic_cmpxchg(T new_value, P* addr, T compare_value);
294
295 template <DecoratorSet decorators, typename P, typename T>
296 T atomic_xchg(T new_value, P* addr);
297
298 template <DecoratorSet decorators, typename T>
299 bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length);
300
301 template <DecoratorSet decorators>
302 void clone(oop src, oop dst, size_t size);
303
304 template <DecoratorSet decorators>
305 oop resolve(oop src);
306
307 template <DecoratorSet decorators>
308 bool equals(oop o1, oop o2);
309
310 // Infer the type that should be returned from a load.
311 template <typename P, DecoratorSet decorators>
312 class LoadProxy: public StackObj {
313 private:
314 P *const _addr;
315 public:
316 LoadProxy(P* addr) : _addr(addr) {}
317
318 template <typename T>
319 inline operator T() {
320 return load<decorators, P, T>(_addr);
321 }
322
323 inline operator P() {
324 return load<decorators, P, P>(_addr);
325 }
326 };
327
328 // Infer the type that should be returned from a load_at.
329 template <DecoratorSet decorators>
497 template <typename P, typename T>
498 static inline T oop_atomic_cmpxchg(T new_value, P* addr, T compare_value) {
499 verify_oop_decorators<atomic_cmpxchg_mo_decorators>();
500 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
501 OopType new_oop_value = new_value;
502 OopType compare_oop_value = compare_value;
503 return AccessInternal::atomic_cmpxchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr, compare_oop_value);
504 }
505
506 template <typename P, typename T>
507 static inline T oop_atomic_xchg(T new_value, P* addr) {
508 verify_oop_decorators<atomic_xchg_mo_decorators>();
509 typedef typename AccessInternal::OopOrNarrowOop<T>::type OopType;
510 OopType new_oop_value = new_value;
511 return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
512 }
513
514 static oop resolve(oop obj) {
515 verify_decorators<INTERNAL_EMPTY>();
516 return AccessInternal::resolve<decorators>(obj);
517 }
518
519 static bool equals(oop o1, oop o2) {
520 verify_decorators<INTERNAL_EMPTY>();
521 return AccessInternal::equals<decorators>(o1, o2);
522 }
523 };
524
525 // Helper for performing raw accesses (knows only of memory ordering
526 // atomicity decorators as well as compressed oops)
527 template <DecoratorSet decorators = INTERNAL_EMPTY>
528 class RawAccess: public Access<AS_RAW | decorators> {};
529
530 // Helper for performing normal accesses on the heap. These accesses
531 // may resolve an accessor on a GC barrier set
532 template <DecoratorSet decorators = INTERNAL_EMPTY>
533 class HeapAccess: public Access<IN_HEAP | decorators> {};
534
535 // Helper for performing normal accesses in roots. These accesses
536 // may resolve an accessor on a GC barrier set
537 template <DecoratorSet decorators = INTERNAL_EMPTY>
538 class RootAccess: public Access<IN_ROOT | decorators> {};
539
540 #endif // SHARE_VM_RUNTIME_ACCESS_HPP
|