23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP |
25 #ifndef SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP |
26 #define SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP |
26 #define SHARE_VM_GC_SHARED_MODREFBARRIERSET_INLINE_HPP |
27 |
27 |
28 #include "gc/shared/barrierSet.inline.hpp" |
28 #include "gc/shared/barrierSet.hpp" |
29 #include "gc/shared/modRefBarrierSet.hpp" |
29 #include "gc/shared/modRefBarrierSet.hpp" |
30 #include "oops/klass.inline.hpp" |
30 #include "oops/klass.inline.hpp" |
31 #include "oops/objArrayOop.hpp" |
31 #include "oops/objArrayOop.hpp" |
32 #include "oops/oop.hpp" |
32 #include "oops/oop.hpp" |
|
33 |
|
34 // count is number of array elements being written |
|
35 void ModRefBarrierSet::write_ref_array(HeapWord* start, size_t count) { |
|
36 HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize)); |
|
37 // In the case of compressed oops, start and end may potentially be misaligned; |
|
38 // so we need to conservatively align the first downward (this is not |
|
39 // strictly necessary for current uses, but a case of good hygiene and, |
|
40 // if you will, aesthetics) and the second upward (this is essential for |
|
41 // current uses) to a HeapWord boundary, so we mark all cards overlapping |
|
42 // this write. If this evolves in the future to calling a |
|
43 // logging barrier of narrow oop granularity, like the pre-barrier for G1 |
|
44 // (mentioned here merely by way of example), we will need to change this |
|
45 // interface, so it is "exactly precise" (if i may be allowed the adverbial |
|
46 // redundancy for emphasis) and does not include narrow oop slots not |
|
47 // included in the original write interval. |
|
48 HeapWord* aligned_start = align_down(start, HeapWordSize); |
|
49 HeapWord* aligned_end = align_up (end, HeapWordSize); |
|
50 // If compressed oops were not being used, these should already be aligned |
|
51 assert(UseCompressedOops || (aligned_start == start && aligned_end == end), |
|
52 "Expected heap word alignment of start and end"); |
|
53 write_ref_array_work(MemRegion(aligned_start, aligned_end)); |
|
54 } |
33 |
55 |
34 template <DecoratorSet decorators, typename BarrierSetT> |
56 template <DecoratorSet decorators, typename BarrierSetT> |
35 template <typename T> |
57 template <typename T> |
36 inline void ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT>:: |
58 inline void ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT>:: |
37 oop_store_in_heap(T* addr, oop value) { |
59 oop_store_in_heap(T* addr, oop value) { |
71 oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { |
93 oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { |
72 BarrierSetT *bs = barrier_set_cast<BarrierSetT>(barrier_set()); |
94 BarrierSetT *bs = barrier_set_cast<BarrierSetT>(barrier_set()); |
73 |
95 |
74 if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) { |
96 if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) { |
75 // Optimized covariant case |
97 // Optimized covariant case |
76 bs->write_ref_array_pre(dst, (int)length, |
98 bs->write_ref_array_pre(dst, length, |
77 HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value); |
99 HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value); |
78 Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); |
100 Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); |
79 bs->write_ref_array((HeapWord*)dst, length); |
101 bs->write_ref_array((HeapWord*)dst, length); |
80 } else { |
102 } else { |
81 Klass* bound = objArrayOop(dst_obj)->element_klass(); |
103 Klass* bound = objArrayOop(dst_obj)->element_klass(); |