24 #include "precompiled.hpp"
25 #include "gc/shenandoah/shenandoahAsserts.hpp"
26 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
28 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
30 #include "gc/shenandoah/shenandoahHeuristics.hpp"
31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
32 #include "memory/iterator.inline.hpp"
33 #include "runtime/interfaceSupport.inline.hpp"
34 #ifdef COMPILER1
35 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
36 #endif
37 #ifdef COMPILER2
38 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
39 #endif
40
41 class ShenandoahBarrierSetC1;
42 class ShenandoahBarrierSetC2;
43
44 template <bool STOREVAL_WRITE_BARRIER>
45 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
46 private:
47 ShenandoahHeap* _heap;
48 ShenandoahBarrierSet* _bs;
49
50 template <class T>
51 inline void do_oop_work(T* p) {
52 oop o;
53 if (STOREVAL_WRITE_BARRIER) {
54 o = _heap->evac_update_with_forwarded(p);
55 if (!CompressedOops::is_null(o)) {
56 _bs->enqueue(o);
57 }
58 } else {
59 _heap->maybe_update_with_forwarded(p);
60 }
61 }
62 public:
63 ShenandoahUpdateRefsForOopClosure() : _heap(ShenandoahHeap::heap()), _bs(ShenandoahBarrierSet::barrier_set()) {
64 assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
65 }
66
67 virtual void do_oop(oop* p) { do_oop_work(p); }
68 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
69 };
70
71 ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
72 BarrierSet(make_barrier_set_assembler<ShenandoahBarrierSetAssembler>(),
73 make_barrier_set_c1<ShenandoahBarrierSetC1>(),
79 {
80 }
81
82 ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() {
83 BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();
84 return reinterpret_cast<ShenandoahBarrierSetAssembler*>(bsa);
85 }
86
87 void ShenandoahBarrierSet::print_on(outputStream* st) const {
88 st->print("ShenandoahBarrierSet");
89 }
90
91 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
92 return bsn == BarrierSet::ShenandoahBarrierSet;
93 }
94
95 bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {
96 return true;
97 }
98
99 template <class T, bool STOREVAL_WRITE_BARRIER>
100 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
101 assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
102 ShenandoahUpdateRefsForOopClosure<STOREVAL_WRITE_BARRIER> cl;
103 T* dst = (T*) start;
104 for (size_t i = 0; i < count; i++) {
105 cl.do_oop(dst++);
106 }
107 }
108
109 void ShenandoahBarrierSet::write_ref_array(HeapWord* start, size_t count) {
110 assert(_heap->is_update_refs_in_progress(), "should not be here otherwise");
111 assert(count > 0, "Should have been filtered before");
112
113 if (_heap->is_concurrent_traversal_in_progress()) {
114 ShenandoahEvacOOMScope oom_evac_scope;
115 if (UseCompressedOops) {
116 write_ref_array_loop<narrowOop, /* wb = */ true>(start, count);
117 } else {
118 write_ref_array_loop<oop, /* wb = */ true>(start, count);
119 }
120 } else {
121 if (UseCompressedOops) {
122 write_ref_array_loop<narrowOop, /* wb = */ false>(start, count);
123 } else {
124 write_ref_array_loop<oop, /* wb = */ false>(start, count);
125 }
126 }
127 }
128
129 template <class T>
130 void ShenandoahBarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
131 shenandoah_assert_not_in_cset_loc_except(dst, _heap->cancelled_gc());
132 assert(ShenandoahThreadLocalData::satb_mark_queue(Thread::current()).is_active(), "Shouldn't be here otherwise");
133 assert(ShenandoahSATBBarrier, "Shouldn't be here otherwise");
134 assert(count > 0, "Should have been filtered before");
135
136 Thread* thread = Thread::current();
137 ShenandoahMarkingContext* ctx = _heap->marking_context();
138 bool has_forwarded = _heap->has_forwarded_objects();
139 T* elem_ptr = dst;
140 for (size_t i = 0; i < count; i++, elem_ptr++) {
141 T heap_oop = RawAccess<>::oop_load(elem_ptr);
142 if (!CompressedOops::is_null(heap_oop)) {
143 oop obj = CompressedOops::decode_not_null(heap_oop);
144 if (has_forwarded) {
189
190 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
191 shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
192 shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
193 shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
194 }
195
196 void ShenandoahBarrierSet::write_region(MemRegion mr) {
197 if (!ShenandoahCloneBarrier) return;
198 if (!_heap->is_update_refs_in_progress()) return;
199
200 // This is called for cloning an object (see jvm.cpp) after the clone
201 // has been made. We are not interested in any 'previous value' because
202 // it would be NULL in any case. But we *are* interested in any oop*
203 // that potentially need to be updated.
204
205 oop obj = oop(mr.start());
206 shenandoah_assert_correct(NULL, obj);
207 if (_heap->is_concurrent_traversal_in_progress()) {
208 ShenandoahEvacOOMScope oom_evac_scope;
209 ShenandoahUpdateRefsForOopClosure</* wb = */ true> cl;
210 obj->oop_iterate(&cl);
211 } else {
212 ShenandoahUpdateRefsForOopClosure</* wb = */ false> cl;
213 obj->oop_iterate(&cl);
214 }
215 }
216
217 oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {
218 if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {
219 return load_reference_barrier_impl(obj);
220 } else {
221 return obj;
222 }
223 }
224
225 oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
226 if (obj != NULL) {
227 return load_reference_barrier_not_null(obj);
228 } else {
229 return obj;
230 }
231 }
232
|
24 #include "precompiled.hpp"
25 #include "gc/shenandoah/shenandoahAsserts.hpp"
26 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
28 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
29 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
30 #include "gc/shenandoah/shenandoahHeuristics.hpp"
31 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
32 #include "memory/iterator.inline.hpp"
33 #include "runtime/interfaceSupport.inline.hpp"
34 #ifdef COMPILER1
35 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
36 #endif
37 #ifdef COMPILER2
38 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
39 #endif
40
41 class ShenandoahBarrierSetC1;
42 class ShenandoahBarrierSetC2;
43
44 template <bool STOREVAL_EVAC_BARRIER>
45 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
46 private:
47 ShenandoahHeap* _heap;
48 ShenandoahBarrierSet* _bs;
49
50 template <class T>
51 inline void do_oop_work(T* p) {
52 oop o;
53 if (STOREVAL_EVAC_BARRIER) {
54 o = _heap->evac_update_with_forwarded(p);
55 if (!CompressedOops::is_null(o)) {
56 _bs->enqueue(o);
57 }
58 } else {
59 _heap->maybe_update_with_forwarded(p);
60 }
61 }
62 public:
63 ShenandoahUpdateRefsForOopClosure() : _heap(ShenandoahHeap::heap()), _bs(ShenandoahBarrierSet::barrier_set()) {
64 assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
65 }
66
67 virtual void do_oop(oop* p) { do_oop_work(p); }
68 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
69 };
70
71 ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
72 BarrierSet(make_barrier_set_assembler<ShenandoahBarrierSetAssembler>(),
73 make_barrier_set_c1<ShenandoahBarrierSetC1>(),
79 {
80 }
81
82 ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() {
83 BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();
84 return reinterpret_cast<ShenandoahBarrierSetAssembler*>(bsa);
85 }
86
87 void ShenandoahBarrierSet::print_on(outputStream* st) const {
88 st->print("ShenandoahBarrierSet");
89 }
90
91 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
92 return bsn == BarrierSet::ShenandoahBarrierSet;
93 }
94
95 bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {
96 return true;
97 }
98
99 template <class T, bool STOREVAL_EVAC_BARRIER>
100 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
101 assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
102 ShenandoahUpdateRefsForOopClosure<STOREVAL_EVAC_BARRIER> cl;
103 T* dst = (T*) start;
104 for (size_t i = 0; i < count; i++) {
105 cl.do_oop(dst++);
106 }
107 }
108
109 void ShenandoahBarrierSet::write_ref_array(HeapWord* start, size_t count) {
110 assert(_heap->is_update_refs_in_progress(), "should not be here otherwise");
111 assert(count > 0, "Should have been filtered before");
112
113 if (_heap->is_concurrent_traversal_in_progress()) {
114 ShenandoahEvacOOMScope oom_evac_scope;
115 if (UseCompressedOops) {
116 write_ref_array_loop<narrowOop, /* evac = */ true>(start, count);
117 } else {
118 write_ref_array_loop<oop, /* evac = */ true>(start, count);
119 }
120 } else {
121 if (UseCompressedOops) {
122 write_ref_array_loop<narrowOop, /* evac = */ false>(start, count);
123 } else {
124 write_ref_array_loop<oop, /* evac = */ false>(start, count);
125 }
126 }
127 }
128
129 template <class T>
130 void ShenandoahBarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
131 shenandoah_assert_not_in_cset_loc_except(dst, _heap->cancelled_gc());
132 assert(ShenandoahThreadLocalData::satb_mark_queue(Thread::current()).is_active(), "Shouldn't be here otherwise");
133 assert(ShenandoahSATBBarrier, "Shouldn't be here otherwise");
134 assert(count > 0, "Should have been filtered before");
135
136 Thread* thread = Thread::current();
137 ShenandoahMarkingContext* ctx = _heap->marking_context();
138 bool has_forwarded = _heap->has_forwarded_objects();
139 T* elem_ptr = dst;
140 for (size_t i = 0; i < count; i++, elem_ptr++) {
141 T heap_oop = RawAccess<>::oop_load(elem_ptr);
142 if (!CompressedOops::is_null(heap_oop)) {
143 oop obj = CompressedOops::decode_not_null(heap_oop);
144 if (has_forwarded) {
189
190 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
191 shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
192 shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
193 shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
194 }
195
196 void ShenandoahBarrierSet::write_region(MemRegion mr) {
197 if (!ShenandoahCloneBarrier) return;
198 if (!_heap->is_update_refs_in_progress()) return;
199
200 // This is called for cloning an object (see jvm.cpp) after the clone
201 // has been made. We are not interested in any 'previous value' because
202 // it would be NULL in any case. But we *are* interested in any oop*
203 // that potentially need to be updated.
204
205 oop obj = oop(mr.start());
206 shenandoah_assert_correct(NULL, obj);
207 if (_heap->is_concurrent_traversal_in_progress()) {
208 ShenandoahEvacOOMScope oom_evac_scope;
209 ShenandoahUpdateRefsForOopClosure</* evac = */ true> cl;
210 obj->oop_iterate(&cl);
211 } else {
212 ShenandoahUpdateRefsForOopClosure</* evac = */ false> cl;
213 obj->oop_iterate(&cl);
214 }
215 }
216
217 oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {
218 if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {
219 return load_reference_barrier_impl(obj);
220 } else {
221 return obj;
222 }
223 }
224
225 oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
226 if (obj != NULL) {
227 return load_reference_barrier_not_null(obj);
228 } else {
229 return obj;
230 }
231 }
232
|