< prev index next > src/hotspot/share/oops/access.hpp
Print this page
// * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
// * atomic_xchg: Atomically swap a new value at an address without checking the previous value.
// * atomic_xchg_at: Atomically swap a new value at an internal pointer address without checking the previous value.
// * arraycopy: Copy data from one heap array to another heap array. The ArrayAccess class has convenience functions for this.
// * clone: Clone the contents of an object to a newly allocated object.
+ // * value_copy: Copy the contents of a value type from one heap address to another
//
// == IMPLEMENTATION ==
// Each access goes through the following steps in a template pipeline.
// There are essentially 5 steps for each access:
// * Step 1: Set default decorators and decay types. This step gets rid of CV qualifiers
// accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
// Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
// include the various GC backend .inline.hpp headers. Their implementation resides in
// access.inline.hpp.
+ class InlineKlass;
+
template <DecoratorSet decorators = DECORATORS_NONE>
class Access: public AllStatic {
// This function asserts that if an access gets passed in a decorator outside
// of the expected_decorators, then something is wrong. It additionally checks
// the consistency of the decorators so that supposedly disjoint decorators are indeed
const DecoratorSet heap_oop_decorators = AS_DECORATOR_MASK | ON_DECORATOR_MASK |
IN_HEAP | IS_ARRAY | IS_NOT_NULL | IS_DEST_UNINITIALIZED;
verify_decorators<expected_mo_decorators | heap_oop_decorators>();
}
static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;
static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;
static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
protected:
template <typename T>
! static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
size_t length) {
verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
AS_DECORATOR_MASK | IS_ARRAY | IS_DEST_UNINITIALIZED>();
! return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
template <typename T>
static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
const DecoratorSet heap_oop_decorators = AS_DECORATOR_MASK | ON_DECORATOR_MASK |
IN_HEAP | IS_ARRAY | IS_NOT_NULL | IS_DEST_UNINITIALIZED;
verify_decorators<expected_mo_decorators | heap_oop_decorators>();
}
+ template <DecoratorSet expected_mo_decorators>
+ static void verify_heap_value_decorators() {
+ const DecoratorSet heap_value_decorators = IN_HEAP | IS_DEST_UNINITIALIZED;
+ verify_decorators<expected_mo_decorators | heap_value_decorators>();
+ }
+
static const DecoratorSet load_mo_decorators = MO_UNORDERED | MO_RELAXED | MO_ACQUIRE | MO_SEQ_CST;
static const DecoratorSet store_mo_decorators = MO_UNORDERED | MO_RELAXED | MO_RELEASE | MO_SEQ_CST;
static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
protected:
template <typename T>
! static inline void oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
size_t length) {
verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
AS_DECORATOR_MASK | IS_ARRAY | IS_DEST_UNINITIALIZED>();
! AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
template <typename T>
static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
static inline void clone(oop src, oop dst, size_t size) {
verify_decorators<IN_HEAP>();
AccessInternal::clone<decorators>(src, dst, size);
}
+ // inline type heap access (when flat)...
+
+ // Copy value type data from src to dst
+ static inline void value_copy(void* src, void* dst, InlineKlass* md) {
+ verify_heap_value_decorators<IN_HEAP>();
+ AccessInternal::value_copy<decorators>(src, dst, md);
+ }
+
// Primitive accesses
template <typename P>
static inline P load(P* addr) {
verify_primitive_decorators<load_mo_decorators>();
return AccessInternal::load<decorators, P, P>(addr);
AccessT::arraycopy(nullptr, 0, src,
dst_obj, dst_offset_in_bytes, static_cast<T*>(nullptr),
length);
}
! static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
arrayOop dst_obj, size_t dst_offset_in_bytes,
size_t length) {
! return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, static_cast<const HeapWord*>(nullptr),
! dst_obj, dst_offset_in_bytes, static_cast<HeapWord*>(nullptr),
! length);
}
template <typename T>
! static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {
! return AccessT::oop_arraycopy(nullptr, 0, src,
! nullptr, 0, dst,
! length);
}
};
template <DecoratorSet decorators>
AccessT::arraycopy(nullptr, 0, src,
dst_obj, dst_offset_in_bytes, static_cast<T*>(nullptr),
length);
}
! static inline void oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
arrayOop dst_obj, size_t dst_offset_in_bytes,
size_t length) {
! AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, static_cast<const HeapWord*>(nullptr),
! dst_obj, dst_offset_in_bytes, static_cast<HeapWord*>(nullptr),
! length);
}
template <typename T>
! static inline void oop_arraycopy_raw(T* src, T* dst, size_t length) {
! AccessT::oop_arraycopy(nullptr, 0, src,
! nullptr, 0, dst,
! length);
}
};
template <DecoratorSet decorators>
< prev index next >