< prev index next >
src/hotspot/share/oops/accessBackend.hpp
Print this page
rev 50331 : 8198285: More consistent Access API for arraycopy
rev 50333 : [mq]: JDK-8198285-3.patch
*** 108,126 ****
typedef T (*load_func_t)(void* addr);
typedef void (*store_func_t)(void* addr, T value);
typedef T (*atomic_cmpxchg_func_t)(T new_value, void* addr, T compare_value);
typedef T (*atomic_xchg_func_t)(T new_value, void* addr);
! typedef bool (*arraycopy_func_t)(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);
typedef void (*clone_func_t)(oop src, oop dst, size_t size);
typedef oop (*resolve_func_t)(oop obj);
typedef bool (*equals_func_t)(oop o1, oop o2);
};
template <DecoratorSet decorators>
struct AccessFunctionTypes<decorators, void> {
! typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, const void* src, arrayOop dst_obj, size_t dst_offset_in_bytes, void* dst, size_t length);
};
template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
#define ACCESS_GENERATE_ACCESS_FUNCTION(bt, func) \
--- 108,130 ----
typedef T (*load_func_t)(void* addr);
typedef void (*store_func_t)(void* addr, T value);
typedef T (*atomic_cmpxchg_func_t)(T new_value, void* addr, T compare_value);
typedef T (*atomic_xchg_func_t)(T new_value, void* addr);
! typedef bool (*arraycopy_func_t)(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);
typedef void (*clone_func_t)(oop src, oop dst, size_t size);
typedef oop (*resolve_func_t)(oop obj);
typedef bool (*equals_func_t)(oop o1, oop o2);
};
template <DecoratorSet decorators>
struct AccessFunctionTypes<decorators, void> {
! typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, const void* src,
! arrayOop dst_obj, size_t dst_offset_in_bytes, void* dst,
! size_t length);
};
template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
#define ACCESS_GENERATE_ACCESS_FUNCTION(bt, func) \
*** 351,361 ****
static inline T atomic_xchg(T new_value, void* addr) {
return atomic_xchg_maybe_locked<decorators>(new_value, addr);
}
template <typename T>
! static bool 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);
template <typename T>
static void oop_store(void* addr, T value);
template <typename T>
static void oop_store_at(oop base, ptrdiff_t offset, T value);
--- 355,367 ----
static inline T atomic_xchg(T new_value, void* addr) {
return atomic_xchg_maybe_locked<decorators>(new_value, addr);
}
template <typename T>
! static bool 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);
template <typename T>
static void oop_store(void* addr, T value);
template <typename T>
static void oop_store_at(oop base, ptrdiff_t offset, T value);
*** 394,404 ****
static T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
return atomic_xchg(new_value, field_addr(base, offset));
}
template <typename T>
! static 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);
static void clone(oop src, oop dst, size_t size);
static oop resolve(oop obj) { return obj; }
--- 400,412 ----
static T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset) {
return atomic_xchg(new_value, field_addr(base, offset));
}
template <typename T>
! static 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);
static void clone(oop src, oop dst, size_t size);
static oop resolve(oop obj) { return obj; }
*** 557,570 ****
template <DecoratorSet decorators, typename T>
struct RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>: AllStatic {
typedef typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type func_t;
static func_t _arraycopy_func;
! static bool arraycopy_init(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);
!
! static inline bool 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) {
! return _arraycopy_func(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
};
template <DecoratorSet decorators, typename T>
struct RuntimeDispatch<decorators, T, BARRIER_CLONE>: AllStatic {
--- 565,584 ----
template <DecoratorSet decorators, typename T>
struct RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>: AllStatic {
typedef typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type func_t;
static func_t _arraycopy_func;
! static bool arraycopy_init(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);
!
! static inline bool 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) {
! return _arraycopy_func(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
};
template <DecoratorSet decorators, typename T>
struct RuntimeDispatch<decorators, T, BARRIER_CLONE>: AllStatic {
*** 898,938 ****
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, bool>::type
! 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) {
typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
! return Raw::oop_arraycopy(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
} else {
! return Raw::arraycopy(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, bool>::type
! 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) {
if (UseCompressedOops) {
const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
} else {
const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
!HasDecorator<decorators, AS_RAW>::value, bool>::type
! 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) {
if (is_hardwired_primitive<decorators>()) {
const DecoratorSet expanded_decorators = decorators | AS_RAW;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
} else {
! return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
}
template <DecoratorSet decorators>
inline static typename EnableIf<
--- 912,970 ----
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, bool>::type
! 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) {
typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
! return Raw::oop_arraycopy(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
} else {
! return Raw::arraycopy(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, bool>::type
! 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) {
if (UseCompressedOops) {
const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
} else {
const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
!HasDecorator<decorators, AS_RAW>::value, bool>::type
! 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) {
if (is_hardwired_primitive<decorators>()) {
const DecoratorSet expanded_decorators = decorators | AS_RAW;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
} else {
! return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
}
template <DecoratorSet decorators>
inline static typename EnableIf<
*** 1090,1114 ****
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
return PreRuntimeDispatch::load<expanded_decorators, oop>(addr);
}
template <DecoratorSet decorators, typename T>
! inline bool arraycopy_reduce_types(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) {
! return PreRuntimeDispatch::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
template <DecoratorSet decorators>
! inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, const HeapWord* src_raw, arrayOop dst_obj, size_t dst_offset_in_bytes, HeapWord* dst_raw, size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
template <DecoratorSet decorators>
! inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, const narrowOop* src_raw, arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw, size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
INTERNAL_RT_USE_COMPRESSED_OOPS;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
}
// Step 1: Set default decorators. This step remembers if a type was volatile
// and then sets the MO_VOLATILE decorator by default. Otherwise, a default
// memory ordering is set for the access, and the implied decorator rules
--- 1122,1158 ----
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
return PreRuntimeDispatch::load<expanded_decorators, oop>(addr);
}
template <DecoratorSet decorators, typename T>
! inline bool arraycopy_reduce_types(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) {
! return PreRuntimeDispatch::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
template <DecoratorSet decorators>
! inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, const HeapWord* src_raw,
! arrayOop dst_obj, size_t dst_offset_in_bytes, HeapWord* dst_raw,
! size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
template <DecoratorSet decorators>
! inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, const narrowOop* src_raw,
! arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw,
! size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
INTERNAL_RT_USE_COMPRESSED_OOPS;
! return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
! dst_obj, dst_offset_in_bytes, dst_raw,
! length);
}
// Step 1: Set default decorators. This step remembers if a type was volatile
// and then sets the MO_VOLATILE decorator by default. Otherwise, a default
// memory ordering is set for the access, and the implied decorator rules
*** 1237,1247 ****
INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(new_decayed_value, base, offset);
}
template <DecoratorSet decorators, typename T>
! inline bool 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) {
STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
(IsSame<T, void>::value || IsIntegral<T>::value) ||
IsFloatingPoint<T>::value)); // arraycopy allows type erased void elements
typedef typename Decay<T>::type DecayedT;
const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IN_HEAP_ARRAY | IN_HEAP>::value;
--- 1281,1293 ----
INTERNAL_CONVERT_COMPRESSED_OOP : INTERNAL_EMPTY)>::value;
return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(new_decayed_value, base, offset);
}
template <DecoratorSet decorators, typename T>
! inline bool 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) {
STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
(IsSame<T, void>::value || IsIntegral<T>::value) ||
IsFloatingPoint<T>::value)); // arraycopy allows type erased void elements
typedef typename Decay<T>::type DecayedT;
const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IN_HEAP_ARRAY | IN_HEAP>::value;
< prev index next >