< prev index next > src/hotspot/share/gc/x/xBarrierSet.inline.hpp
Print this page
#include "gc/x/xBarrierSet.hpp"
#include "gc/shared/accessBarrierSupport.inline.hpp"
#include "gc/x/xBarrier.inline.hpp"
+ #include "oops/inlineKlass.inline.hpp"
#include "utilities/debug.hpp"
template <DecoratorSet decorators, typename BarrierSetT>
template <DecoratorSet expected>
inline void XBarrierSet::AccessBarrier<decorators, BarrierSetT>::verify_decorators_present() {
return XBarrier::load_barrier_on_oop(o);
}
template <DecoratorSet decorators, typename BarrierSetT>
template <typename T>
- inline bool XBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ inline void XBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
size_t length) {
T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
- if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
+ if ((!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) &&
+ (!HasDecorator<decorators, ARRAYCOPY_NOTNULL>::value)) {
// No check cast, bulk barrier and bulk copy
XBarrier::load_barrier_on_oop_array(src, length);
- return Raw::oop_arraycopy_in_heap(nullptr, 0, src, nullptr, 0, dst, length);
+ Raw::oop_arraycopy_in_heap(nullptr, 0, src, nullptr, 0, dst, length);
+ return;
}
// Check cast and copy each elements
Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();
for (const T* const end = src + length; src < end; src++, dst++) {
const oop elem = XBarrier::load_barrier_on_oop_field(src);
- if (!oopDesc::is_instanceof_or_null(elem, dst_klass)) {
+ if (HasDecorator<decorators, ARRAYCOPY_NOTNULL>::value && elem == nullptr) {
+ throw_array_null_pointer_store_exception(src_obj, dst_obj, JavaThread::current());
+ return;
+ }
+ if (HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value &&
+ (!oopDesc::is_instanceof_or_null(elem, dst_klass))) {
// Check cast failed
- return false;
+ throw_array_store_exception(src_obj, dst_obj, JavaThread::current());
+ return;
}
// Cast is safe, since we know it's never a narrowOop
*(oop*)dst = elem;
}
-
- return true;
}
template <DecoratorSet decorators, typename BarrierSetT>
inline void XBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap(oop src, oop dst, size_t size) {
XBarrier::load_barrier_on_oop_fields(src);
Raw::clone_in_heap(src, dst, size);
}
+ template <DecoratorSet decorators, typename BarrierSetT>
+ inline void XBarrierSet::AccessBarrier<decorators, BarrierSetT>::value_copy_in_heap(void* src, void* dst, InlineKlass* md, LayoutKind lk) {
+ if (md->contains_oops()) {
+ // src/dst aren't oops, need offset to adjust oop map offset
+ const address src_oop_addr_offset = ((address) src) - md->first_field_offset();
+
+ OopMapBlock* map = md->start_of_nonstatic_oop_maps();
+ OopMapBlock* const end = map + md->nonstatic_oop_map_count();
+ while (map != end) {
+ address soop_address = src_oop_addr_offset + map->offset();
+ XBarrier::load_barrier_on_oop_array((oop*) soop_address, map->count());
+ map++;
+ }
+ }
+ Raw::value_copy_in_heap(src, dst, md, lk);
+ }
+
//
// Not in heap
//
template <DecoratorSet decorators, typename BarrierSetT>
template <typename T>
< prev index next >