Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp
40957 views
1
/*
2
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "gc/shared/cardTable.hpp"
27
#include "gc/shared/cardTableBarrierSetAssembler.hpp"
28
#include "gc/shared/cardTableBarrierSet.inline.hpp"
29
#include "gc/shared/collectedHeap.hpp"
30
#include "gc/shared/space.inline.hpp"
31
#include "logging/log.hpp"
32
#include "memory/virtualspace.hpp"
33
#include "oops/oop.inline.hpp"
34
#include "runtime/thread.hpp"
35
#include "services/memTracker.hpp"
36
#include "utilities/align.hpp"
37
#include "utilities/macros.hpp"
38
#ifdef COMPILER1
39
#include "gc/shared/c1/cardTableBarrierSetC1.hpp"
40
#endif
41
#ifdef COMPILER2
42
#include "gc/shared/c2/cardTableBarrierSetC2.hpp"
43
#endif
44
45
class CardTableBarrierSetC1;
46
class CardTableBarrierSetC2;
47
48
// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
49
// enumerate ref fields that have been modified (since the last
50
// enumeration.)
51
52
CardTableBarrierSet::CardTableBarrierSet(BarrierSetAssembler* barrier_set_assembler,
53
BarrierSetC1* barrier_set_c1,
54
BarrierSetC2* barrier_set_c2,
55
CardTable* card_table,
56
const BarrierSet::FakeRtti& fake_rtti) :
57
ModRefBarrierSet(barrier_set_assembler,
58
barrier_set_c1,
59
barrier_set_c2,
60
fake_rtti.add_tag(BarrierSet::CardTableBarrierSet)),
61
_defer_initial_card_mark(false),
62
_card_table(card_table)
63
{}
64
65
CardTableBarrierSet::CardTableBarrierSet(CardTable* card_table) :
66
ModRefBarrierSet(make_barrier_set_assembler<CardTableBarrierSetAssembler>(),
67
make_barrier_set_c1<CardTableBarrierSetC1>(),
68
make_barrier_set_c2<CardTableBarrierSetC2>(),
69
BarrierSet::FakeRtti(BarrierSet::CardTableBarrierSet)),
70
_defer_initial_card_mark(false),
71
_card_table(card_table)
72
{}
73
74
void CardTableBarrierSet::initialize() {
75
initialize_deferred_card_mark_barriers();
76
}
77
78
CardTableBarrierSet::~CardTableBarrierSet() {
79
delete _card_table;
80
}
81
82
void CardTableBarrierSet::write_ref_array_work(MemRegion mr) {
83
_card_table->dirty_MemRegion(mr);
84
}
85
86
void CardTableBarrierSet::invalidate(MemRegion mr) {
87
_card_table->invalidate(mr);
88
}
89
90
void CardTableBarrierSet::print_on(outputStream* st) const {
91
_card_table->print_on(st);
92
}
93
94
// Helper for ReduceInitialCardMarks. For performance,
95
// compiled code may elide card-marks for initializing stores
96
// to a newly allocated object along the fast-path. We
97
// compensate for such elided card-marks as follows:
98
// (a) Generational, non-concurrent collectors, such as
99
// GenCollectedHeap(DefNew,Tenured) and
100
// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
101
// need the card-mark if and only if the region is
102
// in the old gen, and do not care if the card-mark
103
// succeeds or precedes the initializing stores themselves,
104
// so long as the card-mark is completed before the next
105
// scavenge. For all these cases, we can do a card mark
106
// at the point at which we do a slow path allocation
107
// in the old gen, i.e. in this call.
108
// (b) G1CollectedHeap(G1) uses two kinds of write barriers. When a
109
// G1 concurrent marking is in progress an SATB (pre-write-)barrier
110
// is used to remember the pre-value of any store. Initializing
111
// stores will not need this barrier, so we need not worry about
112
// compensating for the missing pre-barrier here. Turning now
113
// to the post-barrier, we note that G1 needs a RS update barrier
114
// which simply enqueues a (sequence of) dirty cards which may
115
// optionally be refined by the concurrent update threads. Note
116
// that this barrier need only be applied to a non-young write,
117
// but, because of the presence of concurrent refinement,
118
// must strictly follow the oop-store.
119
//
120
// For any future collector, this code should be reexamined with
121
// that specific collector in mind, and the documentation above suitably
122
// extended and updated.
123
void CardTableBarrierSet::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {
124
#if COMPILER2_OR_JVMCI
125
if (!ReduceInitialCardMarks) {
126
return;
127
}
128
// If a previous card-mark was deferred, flush it now.
129
flush_deferred_card_mark_barrier(thread);
130
if (new_obj->is_typeArray() || _card_table->is_in_young(new_obj)) {
131
// Arrays of non-references don't need a post-barrier.
132
// The deferred_card_mark region should be empty
133
// following the flush above.
134
assert(thread->deferred_card_mark().is_empty(), "Error");
135
} else {
136
MemRegion mr(cast_from_oop<HeapWord*>(new_obj), new_obj->size());
137
assert(!mr.is_empty(), "Error");
138
if (_defer_initial_card_mark) {
139
// Defer the card mark
140
thread->set_deferred_card_mark(mr);
141
} else {
142
// Do the card mark
143
invalidate(mr);
144
}
145
}
146
#endif // COMPILER2_OR_JVMCI
147
}
148
149
void CardTableBarrierSet::initialize_deferred_card_mark_barriers() {
150
// Used for ReduceInitialCardMarks (when COMPILER2 or JVMCI is used);
151
// otherwise remains unused.
152
#if COMPILER2_OR_JVMCI
153
_defer_initial_card_mark = CompilerConfig::is_c2_or_jvmci_compiler_enabled() && ReduceInitialCardMarks
154
&& (DeferInitialCardMark || card_mark_must_follow_store());
155
#else
156
assert(_defer_initial_card_mark == false, "Who would set it?");
157
#endif
158
}
159
160
void CardTableBarrierSet::flush_deferred_card_mark_barrier(JavaThread* thread) {
161
#if COMPILER2_OR_JVMCI
162
MemRegion deferred = thread->deferred_card_mark();
163
if (!deferred.is_empty()) {
164
assert(_defer_initial_card_mark, "Otherwise should be empty");
165
{
166
// Verify that the storage points to a parsable object in heap
167
DEBUG_ONLY(oop old_obj = cast_to_oop(deferred.start());)
168
assert(!_card_table->is_in_young(old_obj),
169
"Else should have been filtered in on_slowpath_allocation_exit()");
170
assert(oopDesc::is_oop(old_obj, true), "Not an oop");
171
assert(deferred.word_size() == (size_t)(old_obj->size()),
172
"Mismatch: multiple objects?");
173
}
174
write_region(deferred);
175
// "Clear" the deferred_card_mark field
176
thread->set_deferred_card_mark(MemRegion());
177
}
178
assert(thread->deferred_card_mark().is_empty(), "invariant");
179
#else
180
assert(!_defer_initial_card_mark, "Should be false");
181
assert(thread->deferred_card_mark().is_empty(), "Should be empty");
182
#endif
183
}
184
185
void CardTableBarrierSet::on_thread_detach(Thread* thread) {
186
// The deferred store barriers must all have been flushed to the
187
// card-table (or other remembered set structure) before GC starts
188
// processing the card-table (or other remembered set).
189
if (thread->is_Java_thread()) { // Only relevant for Java threads.
190
flush_deferred_card_mark_barrier(thread->as_Java_thread());
191
}
192
}
193
194
bool CardTableBarrierSet::card_mark_must_follow_store() const {
195
return false;
196
}
197
198