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>(),
74 make_barrier_set_c2<ShenandoahBarrierSetC2>(),
75 NULL /* barrier_set_nmethod */,
76 BarrierSet::FakeRtti(BarrierSet::ShenandoahBarrierSet)),
77 _heap(heap),
78 _satb_mark_queue_buffer_allocator("SATB Buffer Allocator", ShenandoahSATBBufferSize),
79 _satb_mark_queue_set(&_satb_mark_queue_buffer_allocator)
80 {
81 }
82
83 ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() {
84 BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();
85 return reinterpret_cast<ShenandoahBarrierSetAssembler*>(bsa);
86 }
87
88 void ShenandoahBarrierSet::print_on(outputStream* st) const {
89 st->print("ShenandoahBarrierSet");
90 }
91
92 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
93 return bsn == BarrierSet::ShenandoahBarrierSet;
94 }
95
96 bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {
97 return true;
98 }
99
100 template <class T, bool STOREVAL_EVAC_BARRIER>
101 void ShenandoahBarrierSet::write_ref_array_loop(HeapWord* start, size_t count) {
102 assert(UseShenandoahGC && ShenandoahCloneBarrier, "should be enabled");
103 ShenandoahUpdateRefsForOopClosure<STOREVAL_EVAC_BARRIER> cl;
104 T* dst = (T*) start;
105 for (size_t i = 0; i < count; i++) {
106 cl.do_oop(dst++);
107 }
108 }
109
110 void ShenandoahBarrierSet::write_ref_array(HeapWord* start, size_t count) {
111 assert(_heap->is_update_refs_in_progress(), "should not be here otherwise");
112 assert(count > 0, "Should have been filtered before");
113
114 if (_heap->is_concurrent_traversal_in_progress()) {
115 ShenandoahEvacOOMScope oom_evac_scope;
116 if (UseCompressedOops) {
117 write_ref_array_loop<narrowOop, /* evac = */ true>(start, count);
118 } else {
119 write_ref_array_loop<oop, /* evac = */ true>(start, count);
120 }
121 } else {
122 if (UseCompressedOops) {
123 write_ref_array_loop<narrowOop, /* evac = */ false>(start, count);
124 } else {
125 write_ref_array_loop<oop, /* evac = */ false>(start, count);
126 }
127 }
128 }
129
130 template <class T>
131 void ShenandoahBarrierSet::write_ref_array_pre_work(T* dst, size_t count) {
132 shenandoah_assert_not_in_cset_loc_except(dst, _heap->cancelled_gc());
133 assert(ShenandoahThreadLocalData::satb_mark_queue(Thread::current()).is_active(), "Shouldn't be here otherwise");
134 assert(ShenandoahSATBBarrier, "Shouldn't be here otherwise");
135 assert(count > 0, "Should have been filtered before");
136
137 Thread* thread = Thread::current();
138 ShenandoahMarkingContext* ctx = _heap->marking_context();
139 bool has_forwarded = _heap->has_forwarded_objects();
140 T* elem_ptr = dst;
141 for (size_t i = 0; i < count; i++, elem_ptr++) {
142 T heap_oop = RawAccess<>::oop_load(elem_ptr);
143 if (!CompressedOops::is_null(heap_oop)) {
144 oop obj = CompressedOops::decode_not_null(heap_oop);
145 if (has_forwarded) {
146 obj = resolve_forwarded_not_null(obj);
147 }
148 if (!ctx->is_marked(obj)) {
149 ShenandoahThreadLocalData::satb_mark_queue(thread).enqueue_known_active(obj);
150 }
151 }
152 }
153 }
154
155 void ShenandoahBarrierSet::write_ref_array_pre(oop* dst, size_t count, bool dest_uninitialized) {
156 if (! dest_uninitialized) {
157 write_ref_array_pre_work(dst, count);
158 }
159 }
160
161 void ShenandoahBarrierSet::write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized) {
162 if (! dest_uninitialized) {
163 write_ref_array_pre_work(dst, count);
164 }
165 }
166
167 template <class T>
168 inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop new_val) {
169 shenandoah_assert_not_in_cset_loc_except(field, _heap->cancelled_gc());
170 if (_heap->is_concurrent_mark_in_progress()) {
171 T heap_oop = RawAccess<>::oop_load(field);
172 if (!CompressedOops::is_null(heap_oop)) {
173 enqueue(CompressedOops::decode(heap_oop));
174 }
175 }
176 }
177
178 // These are the more general virtual versions.
179 void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {
180 inline_write_ref_field_pre(field, new_val);
181 }
182
183 void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {
184 inline_write_ref_field_pre(field, new_val);
185 }
186
187 void ShenandoahBarrierSet::write_ref_field_pre_work(void* field, oop new_val) {
188 guarantee(false, "Not needed");
189 }
190
191 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
192 shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
193 shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
194 shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
195 }
196
197 void ShenandoahBarrierSet::write_region(MemRegion mr) {
198 if (!ShenandoahCloneBarrier) return;
199 if (!_heap->is_update_refs_in_progress()) return;
200
201 // This is called for cloning an object (see jvm.cpp) after the clone
202 // has been made. We are not interested in any 'previous value' because
203 // it would be NULL in any case. But we *are* interested in any oop*
204 // that potentially need to be updated.
205
206 oop obj = oop(mr.start());
207 shenandoah_assert_correct(NULL, obj);
208 if (_heap->is_concurrent_traversal_in_progress()) {
209 ShenandoahEvacOOMScope oom_evac_scope;
210 ShenandoahUpdateRefsForOopClosure</* evac = */ true> cl;
211 obj->oop_iterate(&cl);
212 } else {
213 ShenandoahUpdateRefsForOopClosure</* evac = */ false> cl;
214 obj->oop_iterate(&cl);
215 }
216 }
217
218 oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {
219 if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {
220 return load_reference_barrier_impl(obj);
221 } else {
222 return obj;
223 }
224 }
225
226 oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
227 if (obj != NULL) {
228 return load_reference_barrier_not_null(obj);
229 } else {
230 return obj;
231 }
232 }
233
234
235 oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj) {
|
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 ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
45 BarrierSet(make_barrier_set_assembler<ShenandoahBarrierSetAssembler>(),
46 make_barrier_set_c1<ShenandoahBarrierSetC1>(),
47 make_barrier_set_c2<ShenandoahBarrierSetC2>(),
48 NULL /* barrier_set_nmethod */,
49 BarrierSet::FakeRtti(BarrierSet::ShenandoahBarrierSet)),
50 _heap(heap),
51 _satb_mark_queue_buffer_allocator("SATB Buffer Allocator", ShenandoahSATBBufferSize),
52 _satb_mark_queue_set(&_satb_mark_queue_buffer_allocator)
53 {
54 }
55
56 ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() {
57 BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler();
58 return reinterpret_cast<ShenandoahBarrierSetAssembler*>(bsa);
59 }
60
61 void ShenandoahBarrierSet::print_on(outputStream* st) const {
62 st->print("ShenandoahBarrierSet");
63 }
64
65 bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
66 return bsn == BarrierSet::ShenandoahBarrierSet;
67 }
68
69 bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {
70 return true;
71 }
72
73 template <class T>
74 inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop new_val) {
75 shenandoah_assert_not_in_cset_loc_except(field, _heap->cancelled_gc());
76 if (_heap->is_concurrent_mark_in_progress()) {
77 T heap_oop = RawAccess<>::oop_load(field);
78 if (!CompressedOops::is_null(heap_oop)) {
79 enqueue(CompressedOops::decode(heap_oop));
80 }
81 }
82 }
83
84 // These are the more general virtual versions.
85 void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {
86 inline_write_ref_field_pre(field, new_val);
87 }
88
89 void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {
90 inline_write_ref_field_pre(field, new_val);
91 }
92
93 void ShenandoahBarrierSet::write_ref_field_pre_work(void* field, oop new_val) {
94 guarantee(false, "Not needed");
95 }
96
97 void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
98 shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
99 shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
100 shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
101 }
102
103 oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {
104 if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {
105 return load_reference_barrier_impl(obj);
106 } else {
107 return obj;
108 }
109 }
110
111 oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
112 if (obj != NULL) {
113 return load_reference_barrier_not_null(obj);
114 } else {
115 return obj;
116 }
117 }
118
119
120 oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj) {
|