Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp
38920 views
1
/*
2
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation.
7
*
8
* This code is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11
* version 2 for more details (a copy is included in the LICENSE file that
12
* accompanied this code).
13
*
14
* You should have received a copy of the GNU General Public License version
15
* 2 along with this work; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*
18
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19
* or visit www.oracle.com if you need additional information or have any
20
* questions.
21
*
22
*/
23
24
#include "precompiled.hpp"
25
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
26
#include "gc_implementation/shenandoah/shenandoahAsserts.hpp"
27
#include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
28
#include "gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp"
29
#include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp"
30
#include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
31
#include "gc_implementation/shenandoah/heuristics/shenandoahHeuristics.hpp"
32
#include "runtime/interfaceSupport.hpp"
33
#include "utilities/macros.hpp"
34
35
#ifdef COMPILER1
36
#include "gc_implementation/shenandoah/c1/shenandoahBarrierSetC1.hpp"
37
#endif
38
#ifdef COMPILER2
39
#include "gc_implementation/shenandoah/c2/shenandoahBarrierSetC2.hpp"
40
#endif
41
42
#if defined(TARGET_ARCH_aarch64)
43
#include "shenandoahBarrierSetAssembler_aarch64.hpp"
44
#elif defined(TARGET_ARCH_x86)
45
#include "shenandoahBarrierSetAssembler_x86.hpp"
46
#else
47
#include "shenandoahBarrierSetAssembler_stub.hpp"
48
#endif
49
50
ShenandoahBarrierSet::ShenandoahBarrierSet(ShenandoahHeap* heap) :
51
BarrierSet(),
52
_heap(heap),
53
_bsasm(new ShenandoahBarrierSetAssembler()),
54
_bsc1(COMPILER1_PRESENT(new ShenandoahBarrierSetC1()) NOT_COMPILER1(NULL)),
55
_bsc2(COMPILER2_PRESENT(new ShenandoahBarrierSetC2()) NOT_COMPILER2(NULL))
56
{
57
_kind = BarrierSet::ShenandoahBarrierSet;
58
}
59
60
ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::bsasm() const {
61
return _bsasm;
62
}
63
64
ShenandoahBarrierSetC1* ShenandoahBarrierSet::bsc1() const {
65
return _bsc1;
66
}
67
68
ShenandoahBarrierSetC2* ShenandoahBarrierSet::bsc2() const {
69
return _bsc2;
70
}
71
72
void ShenandoahBarrierSet::print_on(outputStream* st) const {
73
st->print("ShenandoahBarrierSet");
74
}
75
76
bool ShenandoahBarrierSet::is_a(BarrierSet::Name bsn) {
77
return bsn == BarrierSet::ShenandoahBarrierSet;
78
}
79
80
bool ShenandoahBarrierSet::has_read_prim_array_opt() {
81
return true;
82
}
83
84
bool ShenandoahBarrierSet::has_read_prim_barrier() {
85
return false;
86
}
87
88
bool ShenandoahBarrierSet::has_read_ref_array_opt() {
89
return true;
90
}
91
92
bool ShenandoahBarrierSet::has_read_ref_barrier() {
93
return false;
94
}
95
96
bool ShenandoahBarrierSet::has_read_region_opt() {
97
return true;
98
}
99
100
bool ShenandoahBarrierSet::has_write_prim_array_opt() {
101
return true;
102
}
103
104
bool ShenandoahBarrierSet::has_write_prim_barrier() {
105
return false;
106
}
107
108
bool ShenandoahBarrierSet::has_write_ref_array_opt() {
109
return true;
110
}
111
112
bool ShenandoahBarrierSet::has_write_ref_barrier() {
113
return true;
114
}
115
116
bool ShenandoahBarrierSet::has_write_ref_pre_barrier() {
117
return true;
118
}
119
120
bool ShenandoahBarrierSet::has_write_region_opt() {
121
return true;
122
}
123
124
bool ShenandoahBarrierSet::is_aligned(HeapWord* hw) {
125
return true;
126
}
127
128
bool ShenandoahBarrierSet::read_prim_needs_barrier(HeapWord* hw, size_t s) {
129
return false;
130
}
131
132
void ShenandoahBarrierSet::read_ref_field(void* v) {
133
// tty->print_cr("read_ref_field: v = "PTR_FORMAT, v);
134
// return *v;
135
}
136
137
template <class T>
138
inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop newVal) {
139
newVal = load_reference_barrier(newVal);
140
storeval_barrier(newVal);
141
if (ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) {
142
T heap_oop = oopDesc::load_heap_oop(field);
143
shenandoah_assert_not_in_cset_loc_except(field, ShenandoahHeap::heap()->cancelled_gc());
144
if (!oopDesc::is_null(heap_oop)) {
145
ShenandoahBarrierSet::barrier_set()->enqueue(oopDesc::decode_heap_oop(heap_oop));
146
}
147
}
148
}
149
150
// These are the more general virtual versions.
151
void ShenandoahBarrierSet::write_ref_field_pre_work(oop* field, oop new_val) {
152
inline_write_ref_field_pre(field, new_val);
153
}
154
155
void ShenandoahBarrierSet::write_ref_field_pre_work(narrowOop* field, oop new_val) {
156
inline_write_ref_field_pre(field, new_val);
157
}
158
159
void ShenandoahBarrierSet::write_ref_field_work(void* v, oop o, bool release) {
160
shenandoah_assert_not_in_cset_loc_except(v, _heap->cancelled_gc());
161
shenandoah_assert_not_forwarded_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
162
shenandoah_assert_not_in_cset_except (v, o, o == NULL || _heap->cancelled_gc() || !_heap->is_concurrent_mark_in_progress());
163
}
164
165
oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) {
166
assert(obj != NULL, "");
167
if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) {
168
return load_reference_barrier_impl(obj);
169
} else {
170
return obj;
171
}
172
}
173
174
oop ShenandoahBarrierSet::load_reference_barrier(oop obj) {
175
if (obj != NULL) {
176
return load_reference_barrier_not_null(obj);
177
} else {
178
return obj;
179
}
180
}
181
182
183
oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) {
184
assert(ShenandoahLoadRefBarrier, "should be enabled");
185
if (!oopDesc::is_null(obj)) {
186
oop fwd = resolve_forwarded_not_null(obj);
187
if (_heap->is_evacuation_in_progress() &&
188
_heap->in_collection_set(obj) &&
189
obj == fwd) {
190
Thread *t = Thread::current();
191
ShenandoahEvacOOMScope oom_evac_scope;
192
return _heap->evacuate_object(obj, t);
193
} else {
194
return fwd;
195
}
196
} else {
197
return obj;
198
}
199
}
200
201
void ShenandoahBarrierSet::storeval_barrier(oop obj) {
202
if (ShenandoahStoreValEnqueueBarrier && !oopDesc::is_null(obj) && _heap->is_concurrent_mark_in_progress()) {
203
enqueue(obj);
204
}
205
}
206
207
void ShenandoahBarrierSet::keep_alive_barrier(oop obj) {
208
if (_heap->is_concurrent_mark_in_progress()) {
209
enqueue(obj);
210
}
211
}
212
213
void ShenandoahBarrierSet::enqueue(oop obj) {
214
assert(JavaThread::satb_mark_queue_set().shared_satb_queue()->is_active(), "only get here when SATB active");
215
216
// Filter marked objects before hitting the SATB queues. The same predicate would
217
// be used by SATBMQ::filter to eliminate already marked objects downstream, but
218
// filtering here helps to avoid wasteful SATB queueing work to begin with.
219
if (!_heap->requires_marking(obj)) return;
220
221
Thread* thr = Thread::current();
222
if (thr->is_Java_thread()) {
223
JavaThread* jt = (JavaThread*)thr;
224
jt->satb_mark_queue().enqueue_known_active(obj);
225
} else {
226
MutexLockerEx x(Shared_SATB_Q_lock, Mutex::_no_safepoint_check_flag);
227
JavaThread::satb_mark_queue_set().shared_satb_queue()->enqueue_known_active(obj);
228
}
229
}
230
231
oop ShenandoahBarrierSet::atomic_compare_exchange_oop(oop exchange_value,
232
volatile HeapWord *dest,
233
oop compare_value) {
234
if (UseCompressedOops) {
235
// encode exchange and compare value from oop to T
236
narrowOop val = oopDesc::encode_heap_oop(exchange_value);
237
narrowOop cmp = oopDesc::encode_heap_oop(compare_value);
238
239
narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);
240
// decode old from T to oop
241
return oopDesc::decode_heap_oop(old);
242
} else {
243
return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);
244
}
245
}
246
247
oop ShenandoahBarrierSet::oop_atomic_cmpxchg_in_heap(oop new_value, volatile HeapWord* dest, oop compare_value) {
248
oop expected;
249
bool success;
250
do {
251
expected = compare_value;
252
compare_value = atomic_compare_exchange_oop(new_value, dest, expected);
253
success = (compare_value == expected);
254
} while ((! success) && resolve_forwarded(compare_value) == resolve_forwarded(expected));
255
oop result = load_reference_barrier(compare_value);
256
if (ShenandoahSATBBarrier && success && result != NULL &&
257
ShenandoahHeap::heap()->is_concurrent_mark_in_progress()) {
258
enqueue(result);
259
}
260
if (new_value != NULL) {
261
storeval_barrier(new_value);
262
}
263
return result;
264
}
265
266
void ShenandoahBarrierSet::clone_barrier_runtime(oop src) {
267
if (_heap->has_forwarded_objects() || (ShenandoahStoreValEnqueueBarrier && _heap->is_concurrent_mark_in_progress())) {
268
clone_barrier(src);
269
}
270
}
271
272