< prev index next >

src/hotspot/share/gc/x/xBarrierSet.inline.hpp

Print this page
@@ -26,10 +26,11 @@
  
  #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() {

@@ -173,44 +174,67 @@
    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) {
+   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);
+ }
+ 
  //
  // Not in heap
  //
  template <DecoratorSet decorators, typename BarrierSetT>
  template <typename T>
< prev index next >