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/preservedMarks.cpp
38920 views
1
/*
2
* Copyright (c) 2016, 2018, 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_implementation/shenandoah/preservedMarks.inline.hpp"
27
#include "utilities/workgroup.hpp"
28
#include "memory/allocation.inline.hpp"
29
#include "memory/resourceArea.hpp"
30
#include "oops/oop.inline.hpp"
31
#include "utilities/macros.hpp"
32
33
void PreservedMarks::restore() {
34
while (!_stack.is_empty()) {
35
const OopAndMarkOop elem = _stack.pop();
36
elem.set_mark();
37
}
38
assert_empty();
39
}
40
41
void PreservedMarks::adjust_during_full_gc() {
42
StackIterator<OopAndMarkOop, mtGC> iter(_stack);
43
while (!iter.is_empty()) {
44
OopAndMarkOop* elem = iter.next_addr();
45
46
oop obj = elem->get_oop();
47
if (obj->is_forwarded()) {
48
elem->set_oop(obj->forwardee());
49
}
50
}
51
}
52
53
void PreservedMarks::restore_and_increment(volatile size_t* const total_size_addr) {
54
const size_t stack_size = size();
55
restore();
56
// Only do the atomic add if the size is > 0.
57
if (stack_size > 0) {
58
Atomic::add(stack_size, (volatile jlong*)total_size_addr);
59
}
60
}
61
62
#ifndef PRODUCT
63
void PreservedMarks::assert_empty() {
64
assert(_stack.is_empty(), err_msg("stack expected to be empty, size = " SIZE_FORMAT,
65
_stack.size()));
66
assert(_stack.cache_size() == 0,
67
err_msg("stack expected to have no cached segments, cache size = " SIZE_FORMAT,
68
_stack.cache_size()));
69
}
70
#endif // ndef PRODUCT
71
72
void RemoveForwardedPointerClosure::do_object(oop obj) {
73
if (obj->is_forwarded()) {
74
PreservedMarks::init_forwarded_mark(obj);
75
}
76
}
77
78
void PreservedMarksSet::init(uint num) {
79
assert(_stacks == NULL && _num == 0, "do not re-initialize");
80
assert(num > 0, "pre-condition");
81
if (_in_c_heap) {
82
_stacks = NEW_C_HEAP_ARRAY(Padded<PreservedMarks>, num, mtGC);
83
} else {
84
_stacks = NEW_RESOURCE_ARRAY(Padded<PreservedMarks>, num);
85
}
86
for (uint i = 0; i < num; i += 1) {
87
::new (_stacks + i) PreservedMarks();
88
}
89
_num = num;
90
91
assert_empty();
92
}
93
94
class ParRestoreTask : public AbstractGangTask {
95
private:
96
PreservedMarksSet* const _preserved_marks_set;
97
SequentialSubTasksDone _sub_tasks;
98
volatile size_t* const _total_size_addr;
99
100
public:
101
virtual void work(uint worker_id) {
102
uint task_id = 0;
103
while (!_sub_tasks.is_task_claimed(/* reference */ task_id)) {
104
_preserved_marks_set->get(task_id)->restore_and_increment(_total_size_addr);
105
}
106
_sub_tasks.all_tasks_completed();
107
}
108
109
ParRestoreTask(uint worker_num,
110
PreservedMarksSet* preserved_marks_set,
111
volatile size_t* total_size_addr)
112
: AbstractGangTask("Parallel Preserved Mark Restoration"),
113
_preserved_marks_set(preserved_marks_set),
114
_total_size_addr(total_size_addr) {
115
_sub_tasks.set_n_threads(worker_num);
116
_sub_tasks.set_n_tasks(preserved_marks_set->num());
117
}
118
};
119
120
void PreservedMarksSet::reclaim() {
121
assert_empty();
122
123
for (uint i = 0; i < _num; i += 1) {
124
_stacks[i].~Padded<PreservedMarks>();
125
}
126
127
if (_in_c_heap) {
128
FREE_C_HEAP_ARRAY(Padded<PreservedMarks>, _stacks, mtGC);
129
} else {
130
// the array was resource-allocated, so nothing to do
131
}
132
_stacks = NULL;
133
_num = 0;
134
}
135
136
#ifndef PRODUCT
137
void PreservedMarksSet::assert_empty() {
138
assert(_stacks != NULL && _num > 0, "should have been initialized");
139
for (uint i = 0; i < _num; i += 1) {
140
get(i)->assert_empty();
141
}
142
}
143
#endif // ndef PRODUCT
144
145
void SharedRestorePreservedMarksTaskExecutor::restore(PreservedMarksSet* preserved_marks_set,
146
volatile size_t* total_size_addr) {
147
if (_workers == NULL) {
148
for (uint i = 0; i < preserved_marks_set->num(); i += 1) {
149
*total_size_addr += preserved_marks_set->get(i)->size();
150
preserved_marks_set->get(i)->restore();
151
}
152
} else {
153
ParRestoreTask task(_workers->active_workers(), preserved_marks_set, total_size_addr);
154
_workers->run_task(&task);
155
}
156
}
157
158