Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/gc/serial/markSweep.cpp
41152 views
1
/*
2
* Copyright (c) 1997, 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 "compiler/compileBroker.hpp"
27
#include "gc/serial/markSweep.inline.hpp"
28
#include "gc/shared/collectedHeap.inline.hpp"
29
#include "gc/shared/gcTimer.hpp"
30
#include "gc/shared/gcTrace.hpp"
31
#include "gc/shared/gc_globals.hpp"
32
#include "memory/iterator.inline.hpp"
33
#include "memory/universe.hpp"
34
#include "oops/access.inline.hpp"
35
#include "oops/compressedOops.inline.hpp"
36
#include "oops/instanceClassLoaderKlass.inline.hpp"
37
#include "oops/instanceKlass.inline.hpp"
38
#include "oops/instanceMirrorKlass.inline.hpp"
39
#include "oops/instanceRefKlass.inline.hpp"
40
#include "oops/methodData.hpp"
41
#include "oops/objArrayKlass.inline.hpp"
42
#include "oops/oop.inline.hpp"
43
#include "oops/typeArrayOop.inline.hpp"
44
#include "utilities/macros.hpp"
45
#include "utilities/stack.inline.hpp"
46
47
uint MarkSweep::_total_invocations = 0;
48
49
Stack<oop, mtGC> MarkSweep::_marking_stack;
50
Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack;
51
52
Stack<oop, mtGC> MarkSweep::_preserved_oop_stack;
53
Stack<markWord, mtGC> MarkSweep::_preserved_mark_stack;
54
size_t MarkSweep::_preserved_count = 0;
55
size_t MarkSweep::_preserved_count_max = 0;
56
PreservedMark* MarkSweep::_preserved_marks = NULL;
57
ReferenceProcessor* MarkSweep::_ref_processor = NULL;
58
STWGCTimer* MarkSweep::_gc_timer = NULL;
59
SerialOldTracer* MarkSweep::_gc_tracer = NULL;
60
61
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
62
63
MarkAndPushClosure MarkSweep::mark_and_push_closure;
64
CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong);
65
CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure, ClassLoaderData::_claim_strong);
66
67
template <class T> inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) {
68
mark_and_push(p);
69
}
70
71
void MarkSweep::push_objarray(oop obj, size_t index) {
72
ObjArrayTask task(obj, index);
73
assert(task.is_valid(), "bad ObjArrayTask");
74
_objarray_stack.push(task);
75
}
76
77
inline void MarkSweep::follow_array(objArrayOop array) {
78
MarkSweep::follow_klass(array->klass());
79
// Don't push empty arrays to avoid unnecessary work.
80
if (array->length() > 0) {
81
MarkSweep::push_objarray(array, 0);
82
}
83
}
84
85
inline void MarkSweep::follow_object(oop obj) {
86
assert(obj->is_gc_marked(), "should be marked");
87
if (obj->is_objArray()) {
88
// Handle object arrays explicitly to allow them to
89
// be split into chunks if needed.
90
MarkSweep::follow_array((objArrayOop)obj);
91
} else {
92
obj->oop_iterate(&mark_and_push_closure);
93
}
94
}
95
96
void MarkSweep::follow_array_chunk(objArrayOop array, int index) {
97
const int len = array->length();
98
const int beg_index = index;
99
assert(beg_index < len || len == 0, "index too large");
100
101
const int stride = MIN2(len - beg_index, (int) ObjArrayMarkingStride);
102
const int end_index = beg_index + stride;
103
104
array->oop_iterate_range(&mark_and_push_closure, beg_index, end_index);
105
106
if (end_index < len) {
107
MarkSweep::push_objarray(array, end_index); // Push the continuation.
108
}
109
}
110
111
void MarkSweep::follow_stack() {
112
do {
113
while (!_marking_stack.is_empty()) {
114
oop obj = _marking_stack.pop();
115
assert (obj->is_gc_marked(), "p must be marked");
116
follow_object(obj);
117
}
118
// Process ObjArrays one at a time to avoid marking stack bloat.
119
if (!_objarray_stack.is_empty()) {
120
ObjArrayTask task = _objarray_stack.pop();
121
follow_array_chunk(objArrayOop(task.obj()), task.index());
122
}
123
} while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
124
}
125
126
MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
127
128
void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
129
130
template <class T> inline void MarkSweep::follow_root(T* p) {
131
assert(!Universe::heap()->is_in(p),
132
"roots shouldn't be things within the heap");
133
T heap_oop = RawAccess<>::oop_load(p);
134
if (!CompressedOops::is_null(heap_oop)) {
135
oop obj = CompressedOops::decode_not_null(heap_oop);
136
if (!obj->mark().is_marked()) {
137
mark_object(obj);
138
follow_object(obj);
139
}
140
}
141
follow_stack();
142
}
143
144
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
145
void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
146
147
void PreservedMark::adjust_pointer() {
148
MarkSweep::adjust_pointer(&_obj);
149
}
150
151
void PreservedMark::restore() {
152
_obj->set_mark(_mark);
153
}
154
155
// We preserve the mark which should be replaced at the end and the location
156
// that it will go. Note that the object that this markWord belongs to isn't
157
// currently at that address but it will be after phase4
158
void MarkSweep::preserve_mark(oop obj, markWord mark) {
159
// We try to store preserved marks in the to space of the new generation since
160
// this is storage which should be available. Most of the time this should be
161
// sufficient space for the marks we need to preserve but if it isn't we fall
162
// back to using Stacks to keep track of the overflow.
163
if (_preserved_count < _preserved_count_max) {
164
_preserved_marks[_preserved_count++].init(obj, mark);
165
} else {
166
_preserved_mark_stack.push(mark);
167
_preserved_oop_stack.push(obj);
168
}
169
}
170
171
void MarkSweep::set_ref_processor(ReferenceProcessor* rp) {
172
_ref_processor = rp;
173
mark_and_push_closure.set_ref_discoverer(_ref_processor);
174
}
175
176
AdjustPointerClosure MarkSweep::adjust_pointer_closure;
177
178
void MarkSweep::adjust_marks() {
179
assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
180
"inconsistent preserved oop stacks");
181
182
// adjust the oops we saved earlier
183
for (size_t i = 0; i < _preserved_count; i++) {
184
_preserved_marks[i].adjust_pointer();
185
}
186
187
// deal with the overflow stack
188
StackIterator<oop, mtGC> iter(_preserved_oop_stack);
189
while (!iter.is_empty()) {
190
oop* p = iter.next_addr();
191
adjust_pointer(p);
192
}
193
}
194
195
void MarkSweep::restore_marks() {
196
assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
197
"inconsistent preserved oop stacks");
198
log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_oop_stack.size());
199
200
// restore the marks we saved earlier
201
for (size_t i = 0; i < _preserved_count; i++) {
202
_preserved_marks[i].restore();
203
}
204
205
// deal with the overflow
206
while (!_preserved_oop_stack.is_empty()) {
207
oop obj = _preserved_oop_stack.pop();
208
markWord mark = _preserved_mark_stack.pop();
209
obj->set_mark(mark);
210
}
211
}
212
213
MarkSweep::IsAliveClosure MarkSweep::is_alive;
214
215
bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
216
217
MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
218
219
void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
220
void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
221
222
void MarkSweep::initialize() {
223
MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
224
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
225
}
226
227