89 } |
89 } |
90 |
90 |
91 template <DecoratorSet decorators, typename BarrierSetT> |
91 template <DecoratorSet decorators, typename BarrierSetT> |
92 template <typename T> |
92 template <typename T> |
93 inline bool ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT>:: |
93 inline bool ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT>:: |
94 oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { |
94 oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, |
|
95 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, |
|
96 size_t length) { |
95 BarrierSetT *bs = barrier_set_cast<BarrierSetT>(barrier_set()); |
97 BarrierSetT *bs = barrier_set_cast<BarrierSetT>(barrier_set()); |
|
98 |
|
99 src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw); |
|
100 dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw); |
96 |
101 |
97 if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) { |
102 if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) { |
98 // Optimized covariant case |
103 // Optimized covariant case |
99 bs->write_ref_array_pre(dst, length, |
104 bs->write_ref_array_pre(dst_raw, length, |
100 HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value); |
105 HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value); |
101 Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); |
106 Raw::oop_arraycopy(NULL, 0, src_raw, NULL, 0, dst_raw, length); |
102 bs->write_ref_array((HeapWord*)dst, length); |
107 bs->write_ref_array((HeapWord*)dst_raw, length); |
103 } else { |
108 } else { |
|
109 assert(dst_obj != NULL, "better have an actual oop"); |
104 Klass* bound = objArrayOop(dst_obj)->element_klass(); |
110 Klass* bound = objArrayOop(dst_obj)->element_klass(); |
105 T* from = src; |
111 T* from = const_cast<T*>(src_raw); |
106 T* end = from + length; |
112 T* end = from + length; |
107 for (T* p = dst; from < end; from++, p++) { |
113 for (T* p = dst_raw; from < end; from++, p++) { |
108 T element = *from; |
114 T element = *from; |
109 if (oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound)) { |
115 if (oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound)) { |
110 bs->template write_ref_field_pre<decorators>(p); |
116 bs->template write_ref_field_pre<decorators>(p); |
111 *p = element; |
117 *p = element; |
112 } else { |
118 } else { |
113 // We must do a barrier to cover the partial copy. |
119 // We must do a barrier to cover the partial copy. |
114 const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize); |
120 const size_t pd = pointer_delta(p, dst_raw, (size_t)heapOopSize); |
115 // pointer delta is scaled to number of elements (length field in |
121 // pointer delta is scaled to number of elements (length field in |
116 // objArrayOop) which we assume is 32 bit. |
122 // objArrayOop) which we assume is 32 bit. |
117 assert(pd == (size_t)(int)pd, "length field overflow"); |
123 assert(pd == (size_t)(int)pd, "length field overflow"); |
118 bs->write_ref_array((HeapWord*)dst, pd); |
124 bs->write_ref_array((HeapWord*)dst_raw, pd); |
119 return false; |
125 return false; |
120 } |
126 } |
121 } |
127 } |
122 bs->write_ref_array((HeapWord*)dst, length); |
128 bs->write_ref_array((HeapWord*)dst_raw, length); |
123 } |
129 } |
124 return true; |
130 return true; |
125 } |
131 } |
126 |
132 |
127 template <DecoratorSet decorators, typename BarrierSetT> |
133 template <DecoratorSet decorators, typename BarrierSetT> |