Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/cpu/zero/frame_zero.cpp
40931 views
1
/*
2
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#include "precompiled.hpp"
27
#include "gc/shared/collectedHeap.hpp"
28
#include "interpreter/interpreter.hpp"
29
#include "interpreter/interpreterRuntime.hpp"
30
#include "memory/resourceArea.hpp"
31
#include "memory/universe.hpp"
32
#include "oops/method.hpp"
33
#include "oops/oop.inline.hpp"
34
#include "runtime/frame.inline.hpp"
35
#include "runtime/handles.inline.hpp"
36
#include "runtime/signature.hpp"
37
#include "vmreg_zero.inline.hpp"
38
39
#ifdef ASSERT
40
void RegisterMap::check_location_valid() {
41
ShouldNotCallThis();
42
}
43
#endif
44
45
bool frame::is_interpreted_frame() const {
46
return zeroframe()->is_interpreter_frame();
47
}
48
49
bool frame::is_fake_stub_frame() const {
50
return zeroframe()->is_fake_stub_frame();
51
}
52
53
frame frame::sender_for_entry_frame(RegisterMap *map) const {
54
assert(zeroframe()->is_entry_frame(), "wrong type of frame");
55
assert(map != NULL, "map must be set");
56
assert(!entry_frame_is_first(), "next Java fp must be non zero");
57
assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
58
"sender should be next Java frame");
59
map->clear();
60
assert(map->include_argument_oops(), "should be set by clear");
61
return frame(zeroframe()->next(), sender_sp());
62
}
63
64
frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
65
assert(zeroframe()->is_interpreter_frame() ||
66
zeroframe()->is_fake_stub_frame(), "wrong type of frame");
67
return frame(zeroframe()->next(), sender_sp());
68
}
69
70
frame frame::sender(RegisterMap* map) const {
71
// Default is not to follow arguments; the various
72
// sender_for_xxx methods update this accordingly.
73
map->set_include_argument_oops(false);
74
75
if (is_entry_frame())
76
return sender_for_entry_frame(map);
77
else
78
return sender_for_nonentry_frame(map);
79
}
80
81
BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
82
return get_interpreterState()->monitor_base();
83
}
84
85
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
86
return (BasicObjectLock*) get_interpreterState()->stack_base();
87
}
88
89
void frame::patch_pc(Thread* thread, address pc) {
90
if (pc != NULL) {
91
assert(_cb == CodeCache::find_blob(pc), "unexpected pc");
92
_pc = pc;
93
_deopt_state = is_deoptimized;
94
} else {
95
// We borrow this call to set the thread pointer in the interpreter
96
// state; the hook to set up deoptimized frames isn't supplied it.
97
assert(pc == NULL, "should be");
98
get_interpreterState()->set_thread(thread->as_Java_thread());
99
}
100
}
101
102
bool frame::safe_for_sender(JavaThread *thread) {
103
ShouldNotCallThis();
104
return false;
105
}
106
107
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
108
ShouldNotCallThis();
109
return false;
110
}
111
112
BasicType frame::interpreter_frame_result(oop* oop_result,
113
jvalue* value_result) {
114
assert(is_interpreted_frame(), "interpreted frame expected");
115
Method* method = interpreter_frame_method();
116
BasicType type = method->result_type();
117
intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();
118
oop obj;
119
120
switch (type) {
121
case T_VOID:
122
break;
123
case T_BOOLEAN:
124
value_result->z = *(jboolean *) tos_addr;
125
break;
126
case T_BYTE:
127
value_result->b = *(jbyte *) tos_addr;
128
break;
129
case T_CHAR:
130
value_result->c = *(jchar *) tos_addr;
131
break;
132
case T_SHORT:
133
value_result->s = *(jshort *) tos_addr;
134
break;
135
case T_INT:
136
value_result->i = *(jint *) tos_addr;
137
break;
138
case T_LONG:
139
value_result->j = *(jlong *) tos_addr;
140
break;
141
case T_FLOAT:
142
value_result->f = *(jfloat *) tos_addr;
143
break;
144
case T_DOUBLE:
145
value_result->d = *(jdouble *) tos_addr;
146
break;
147
148
case T_OBJECT:
149
case T_ARRAY:
150
if (method->is_native()) {
151
obj = get_interpreterState()->oop_temp();
152
}
153
else {
154
oop* obj_p = (oop *) tos_addr;
155
obj = (obj_p == NULL) ? (oop) NULL : *obj_p;
156
}
157
assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
158
*oop_result = obj;
159
break;
160
161
default:
162
ShouldNotReachHere();
163
}
164
165
return type;
166
}
167
168
int frame::frame_size(RegisterMap* map) const {
169
#ifdef PRODUCT
170
ShouldNotCallThis();
171
#endif // PRODUCT
172
return 0; // make javaVFrame::print_value work
173
}
174
175
intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
176
int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
177
return &interpreter_frame_tos_address()[index];
178
}
179
180
void frame::zero_print_on_error(int frame_index,
181
outputStream* st,
182
char* buf,
183
int buflen) const {
184
// Divide the buffer between the field and the value
185
buflen >>= 1;
186
char *fieldbuf = buf;
187
char *valuebuf = buf + buflen;
188
189
// Print each word of the frame
190
for (intptr_t *addr = sp(); addr <= fp(); addr++) {
191
int offset = fp() - addr;
192
193
// Fill in default values, then try and improve them
194
snprintf(fieldbuf, buflen, "word[%d]", offset);
195
snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
196
zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
197
fieldbuf[buflen - 1] = '\0';
198
valuebuf[buflen - 1] = '\0';
199
200
// Print the result
201
st->print_cr(" " PTR_FORMAT ": %-21s = %s", p2i(addr), fieldbuf, valuebuf);
202
}
203
}
204
205
void ZeroFrame::identify_word(int frame_index,
206
int offset,
207
char* fieldbuf,
208
char* valuebuf,
209
int buflen) const {
210
switch (offset) {
211
case next_frame_off:
212
strncpy(fieldbuf, "next_frame", buflen);
213
break;
214
215
case frame_type_off:
216
strncpy(fieldbuf, "frame_type", buflen);
217
if (is_entry_frame())
218
strncpy(valuebuf, "ENTRY_FRAME", buflen);
219
else if (is_interpreter_frame())
220
strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
221
else if (is_fake_stub_frame())
222
strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
223
break;
224
225
default:
226
if (is_entry_frame()) {
227
as_entry_frame()->identify_word(
228
frame_index, offset, fieldbuf, valuebuf, buflen);
229
}
230
else if (is_interpreter_frame()) {
231
as_interpreter_frame()->identify_word(
232
frame_index, offset, fieldbuf, valuebuf, buflen);
233
}
234
else if (is_fake_stub_frame()) {
235
as_fake_stub_frame()->identify_word(
236
frame_index, offset, fieldbuf, valuebuf, buflen);
237
}
238
}
239
}
240
241
void EntryFrame::identify_word(int frame_index,
242
int offset,
243
char* fieldbuf,
244
char* valuebuf,
245
int buflen) const {
246
switch (offset) {
247
case call_wrapper_off:
248
strncpy(fieldbuf, "call_wrapper", buflen);
249
break;
250
251
default:
252
snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
253
}
254
}
255
256
void InterpreterFrame::identify_word(int frame_index,
257
int offset,
258
char* fieldbuf,
259
char* valuebuf,
260
int buflen) const {
261
interpreterState istate = interpreter_state();
262
bool is_valid = istate->self_link() == istate;
263
intptr_t *addr = addr_of_word(offset);
264
265
// Fixed part
266
if (addr >= (intptr_t *) istate) {
267
const char *field = istate->name_of_field_at_address((address) addr);
268
if (field) {
269
if (is_valid && !strcmp(field, "_method")) {
270
istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
271
}
272
else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
273
snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
274
(intptr_t) istate->bcp(),
275
istate->method()->bci_from(istate->bcp()));
276
}
277
snprintf(fieldbuf, buflen, "%sistate->%s",
278
field[strlen(field) - 1] == ')' ? "(": "", field);
279
}
280
else if (addr == (intptr_t *) istate) {
281
strncpy(fieldbuf, "(vtable for istate)", buflen);
282
}
283
return;
284
}
285
286
// Variable part
287
if (!is_valid)
288
return;
289
290
// JNI stuff
291
if (istate->method()->is_native() && addr < istate->stack_base()) {
292
address hA = istate->method()->signature_handler();
293
if (hA != NULL) {
294
if (hA != (address) InterpreterRuntime::slow_signature_handler) {
295
InterpreterRuntime::SignatureHandler *handler =
296
InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
297
298
intptr_t *params = istate->stack_base() - handler->argument_count();
299
if (addr >= params) {
300
int param = addr - params;
301
const char *desc = "";
302
if (param == 0)
303
desc = " (JNIEnv)";
304
else if (param == 1) {
305
if (istate->method()->is_static())
306
desc = " (mirror)";
307
else
308
desc = " (this)";
309
}
310
snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
311
return;
312
}
313
314
for (int i = 0; i < handler->argument_count(); i++) {
315
if (params[i] == (intptr_t) addr) {
316
snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
317
return;
318
}
319
}
320
}
321
}
322
return;
323
}
324
325
// Monitors and stack
326
identify_vp_word(frame_index, addr,
327
(intptr_t *) istate->monitor_base(),
328
istate->stack_base(),
329
fieldbuf, buflen);
330
}
331
332
void ZeroFrame::identify_vp_word(int frame_index,
333
intptr_t* addr,
334
intptr_t* monitor_base,
335
intptr_t* stack_base,
336
char* fieldbuf,
337
int buflen) const {
338
// Monitors
339
if (addr >= stack_base && addr < monitor_base) {
340
int monitor_size = frame::interpreter_frame_monitor_size();
341
int last_index = (monitor_base - stack_base) / monitor_size - 1;
342
int index = last_index - (addr - stack_base) / monitor_size;
343
intptr_t monitor = (intptr_t) (
344
(BasicObjectLock *) monitor_base - 1 - index);
345
intptr_t offset = (intptr_t) addr - monitor;
346
347
if (offset == BasicObjectLock::obj_offset_in_bytes())
348
snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
349
else if (offset == BasicObjectLock::lock_offset_in_bytes())
350
snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
351
352
return;
353
}
354
355
// Expression stack
356
if (addr < stack_base) {
357
snprintf(fieldbuf, buflen, "%s[%d]",
358
frame_index == 0 ? "stack_word" : "local",
359
(int) (stack_base - addr - 1));
360
return;
361
}
362
}
363
364
#ifndef PRODUCT
365
366
void frame::describe_pd(FrameValues& values, int frame_no) {
367
368
}
369
370
#endif
371
372
intptr_t *frame::initial_deoptimization_info() {
373
// unused... but returns fp() to minimize changes introduced by 7087445
374
return fp();
375
}
376
377
#ifndef PRODUCT
378
// This is a generic constructor which is only used by pns() in debug.cpp.
379
frame::frame(void* sp, void* fp, void* pc) {
380
Unimplemented();
381
}
382
383
void frame::pd_ps() {}
384
#endif
385
386