Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/runtime/interfaceSupport.cpp
40951 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 "gc/shared/collectedHeap.hpp"
27
#include "gc/shared/collectedHeap.inline.hpp"
28
#include "logging/log.hpp"
29
#include "memory/resourceArea.hpp"
30
#include "memory/universe.hpp"
31
#include "runtime/atomic.hpp"
32
#include "runtime/frame.inline.hpp"
33
#include "runtime/handles.inline.hpp"
34
#include "runtime/init.hpp"
35
#include "runtime/interfaceSupport.inline.hpp"
36
#include "runtime/os.hpp"
37
#include "runtime/thread.inline.hpp"
38
#include "runtime/safepointVerifiers.hpp"
39
#include "runtime/stackFrameStream.inline.hpp"
40
#include "runtime/vframe.hpp"
41
#include "runtime/vmOperations.hpp"
42
#include "runtime/vmThread.hpp"
43
#include "utilities/preserveException.hpp"
44
45
// Implementation of InterfaceSupport
46
47
#ifdef ASSERT
48
VMEntryWrapper::VMEntryWrapper() {
49
if (VerifyLastFrame) {
50
InterfaceSupport::verify_last_frame();
51
}
52
}
53
54
VMEntryWrapper::~VMEntryWrapper() {
55
InterfaceSupport::check_gc_alot();
56
if (WalkStackALot) {
57
InterfaceSupport::walk_stack();
58
}
59
if (DeoptimizeALot || DeoptimizeRandom) {
60
InterfaceSupport::deoptimizeAll();
61
}
62
if (ZombieALot) {
63
InterfaceSupport::zombieAll();
64
}
65
// do verification AFTER potential deoptimization
66
if (VerifyStack) {
67
InterfaceSupport::verify_stack();
68
}
69
}
70
71
VMNativeEntryWrapper::VMNativeEntryWrapper() {
72
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
73
}
74
75
VMNativeEntryWrapper::~VMNativeEntryWrapper() {
76
if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
77
}
78
79
unsigned int InterfaceSupport::_scavenge_alot_counter = 1;
80
unsigned int InterfaceSupport::_fullgc_alot_counter = 1;
81
int InterfaceSupport::_fullgc_alot_invocation = 0;
82
83
void InterfaceSupport::gc_alot() {
84
Thread *thread = Thread::current();
85
if (!thread->is_Java_thread()) return; // Avoid concurrent calls
86
// Check for new, not quite initialized thread. A thread in new mode cannot initiate a GC.
87
JavaThread *current_thread = thread->as_Java_thread();
88
if (current_thread->active_handles() == NULL) return;
89
90
// Short-circuit any possible re-entrant gc-a-lot attempt
91
if (thread->skip_gcalot()) return;
92
93
if (Threads::is_vm_complete()) {
94
95
if (++_fullgc_alot_invocation < FullGCALotStart) {
96
return;
97
}
98
99
// Use this line if you want to block at a specific point,
100
// e.g. one number_of_calls/scavenge/gc before you got into problems
101
if (FullGCALot) _fullgc_alot_counter--;
102
103
// Check if we should force a full gc
104
if (_fullgc_alot_counter == 0) {
105
// Release dummy so objects are forced to move
106
if (!Universe::release_fullgc_alot_dummy()) {
107
warning("FullGCALot: Unable to release more dummies at bottom of heap");
108
}
109
HandleMark hm(thread);
110
Universe::heap()->collect(GCCause::_full_gc_alot);
111
unsigned int invocations = Universe::heap()->total_full_collections();
112
// Compute new interval
113
if (FullGCALotInterval > 1) {
114
_fullgc_alot_counter = 1+(unsigned int)((double)FullGCALotInterval*os::random()/(max_jint+1.0));
115
log_trace(gc)("Full gc no: %u\tInterval: %u", invocations, _fullgc_alot_counter);
116
} else {
117
_fullgc_alot_counter = 1;
118
}
119
// Print progress message
120
if (invocations % 100 == 0) {
121
log_trace(gc)("Full gc no: %u", invocations);
122
}
123
} else {
124
if (ScavengeALot) _scavenge_alot_counter--;
125
// Check if we should force a scavenge
126
if (_scavenge_alot_counter == 0) {
127
HandleMark hm(thread);
128
Universe::heap()->collect(GCCause::_scavenge_alot);
129
unsigned int invocations = Universe::heap()->total_collections() - Universe::heap()->total_full_collections();
130
// Compute new interval
131
if (ScavengeALotInterval > 1) {
132
_scavenge_alot_counter = 1+(unsigned int)((double)ScavengeALotInterval*os::random()/(max_jint+1.0));
133
log_trace(gc)("Scavenge no: %u\tInterval: %u", invocations, _scavenge_alot_counter);
134
} else {
135
_scavenge_alot_counter = 1;
136
}
137
// Print progress message
138
if (invocations % 1000 == 0) {
139
log_trace(gc)("Scavenge no: %u", invocations);
140
}
141
}
142
}
143
}
144
}
145
146
147
vframe* vframe_array[50];
148
int walk_stack_counter = 0;
149
150
void InterfaceSupport::walk_stack_from(vframe* start_vf) {
151
// walk
152
int i = 0;
153
for (vframe* f = start_vf; f; f = f->sender() ) {
154
if (i < 50) vframe_array[i++] = f;
155
}
156
}
157
158
159
void InterfaceSupport::walk_stack() {
160
JavaThread* thread = JavaThread::current();
161
walk_stack_counter++;
162
if (!thread->has_last_Java_frame()) return;
163
ResourceMark rm(thread);
164
RegisterMap reg_map(thread);
165
walk_stack_from(thread->last_java_vframe(&reg_map));
166
}
167
168
// invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions
169
int deoptimizeAllCounter = 0;
170
int zombieAllCounter = 0;
171
172
void InterfaceSupport::zombieAll() {
173
// This method is called by all threads when a thread make
174
// transition to VM state (for example, runtime calls).
175
// Divide number of calls by number of threads to avoid
176
// dependence of ZombieAll events frequency on number of threads.
177
int value = zombieAllCounter / Threads::number_of_threads();
178
if (is_init_completed() && value > ZombieALotInterval) {
179
zombieAllCounter = 0;
180
VM_ZombieAll op;
181
VMThread::execute(&op);
182
}
183
zombieAllCounter++;
184
}
185
186
void InterfaceSupport::deoptimizeAll() {
187
// This method is called by all threads when a thread make
188
// transition to VM state (for example, runtime calls).
189
// Divide number of calls by number of threads to avoid
190
// dependence of DeoptimizeAll events frequency on number of threads.
191
int value = deoptimizeAllCounter / Threads::number_of_threads();
192
if (is_init_completed()) {
193
if (DeoptimizeALot && value > DeoptimizeALotInterval) {
194
deoptimizeAllCounter = 0;
195
VM_DeoptimizeAll op;
196
VMThread::execute(&op);
197
} else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) {
198
VM_DeoptimizeAll op;
199
VMThread::execute(&op);
200
}
201
}
202
deoptimizeAllCounter++;
203
}
204
205
206
void InterfaceSupport::verify_stack() {
207
JavaThread* thread = JavaThread::current();
208
ResourceMark rm(thread);
209
// disabled because it throws warnings that oop maps should only be accessed
210
// in VM thread or during debugging
211
212
if (!thread->has_pending_exception()) {
213
// verification does not work if there are pending exceptions
214
StackFrameStream sfs(thread, true /* update */, true /* process_frames */);
215
CodeBlob* cb = sfs.current()->cb();
216
// In case of exceptions we might not have a runtime_stub on
217
// top of stack, hence, all callee-saved registers are not going
218
// to be setup correctly, hence, we cannot do stack verify
219
if (cb != NULL && !(cb->is_runtime_stub() || cb->is_uncommon_trap_stub())) return;
220
221
for (; !sfs.is_done(); sfs.next()) {
222
sfs.current()->verify(sfs.register_map());
223
}
224
}
225
}
226
227
228
void InterfaceSupport::verify_last_frame() {
229
JavaThread* thread = JavaThread::current();
230
ResourceMark rm(thread);
231
RegisterMap reg_map(thread);
232
frame fr = thread->last_frame();
233
fr.verify(&reg_map);
234
}
235
236
237
#endif // ASSERT
238
239
240
void InterfaceSupport_init() {
241
#ifdef ASSERT
242
if (ScavengeALot || FullGCALot) {
243
srand(ScavengeALotInterval * FullGCALotInterval);
244
}
245
#endif
246
}
247
248