Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/code/debugInfo.cpp
40931 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 "code/debugInfo.hpp"
27
#include "code/debugInfoRec.hpp"
28
#include "code/nmethod.hpp"
29
#include "gc/shared/collectedHeap.hpp"
30
#include "memory/universe.hpp"
31
#include "oops/oop.inline.hpp"
32
#include "runtime/handles.inline.hpp"
33
#include "runtime/interfaceSupport.inline.hpp"
34
#include "runtime/jniHandles.inline.hpp"
35
#include "runtime/thread.hpp"
36
37
// Constructors
38
39
DebugInfoWriteStream::DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size)
40
: CompressedWriteStream(initial_size) {
41
_recorder = recorder;
42
}
43
44
// Serializing oops
45
46
void DebugInfoWriteStream::write_handle(jobject h) {
47
write_int(recorder()->oop_recorder()->find_index(h));
48
}
49
50
void DebugInfoWriteStream::write_metadata(Metadata* h) {
51
write_int(recorder()->oop_recorder()->find_index(h));
52
}
53
54
oop DebugInfoReadStream::read_oop() {
55
nmethod* nm = const_cast<CompiledMethod*>(code())->as_nmethod_or_null();
56
oop o;
57
if (nm != NULL) {
58
// Despite these oops being found inside nmethods that are on-stack,
59
// they are not kept alive by all GCs (e.g. G1 and Shenandoah).
60
o = nm->oop_at_phantom(read_int());
61
} else {
62
o = code()->oop_at(read_int());
63
}
64
assert(oopDesc::is_oop_or_null(o), "oop only");
65
return o;
66
}
67
68
ScopeValue* DebugInfoReadStream::read_object_value(bool is_auto_box) {
69
int id = read_int();
70
#ifdef ASSERT
71
assert(_obj_pool != NULL, "object pool does not exist");
72
for (int i = _obj_pool->length() - 1; i >= 0; i--) {
73
assert(_obj_pool->at(i)->as_ObjectValue()->id() != id, "should not be read twice");
74
}
75
#endif
76
ObjectValue* result = is_auto_box ? new AutoBoxObjectValue(id) : new ObjectValue(id);
77
// Cache the object since an object field could reference it.
78
_obj_pool->push(result);
79
result->read_object(this);
80
return result;
81
}
82
83
ScopeValue* DebugInfoReadStream::get_cached_object() {
84
int id = read_int();
85
assert(_obj_pool != NULL, "object pool does not exist");
86
for (int i = _obj_pool->length() - 1; i >= 0; i--) {
87
ObjectValue* ov = _obj_pool->at(i)->as_ObjectValue();
88
if (ov->id() == id) {
89
return ov;
90
}
91
}
92
ShouldNotReachHere();
93
return NULL;
94
}
95
96
// Serializing scope values
97
98
enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1, CONSTANT_OOP_CODE = 2,
99
CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4,
100
OBJECT_CODE = 5, OBJECT_ID_CODE = 6,
101
AUTO_BOX_OBJECT_CODE = 7, MARKER_CODE = 8 };
102
103
ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
104
ScopeValue* result = NULL;
105
switch(stream->read_int()) {
106
case LOCATION_CODE: result = new LocationValue(stream); break;
107
case CONSTANT_INT_CODE: result = new ConstantIntValue(stream); break;
108
case CONSTANT_OOP_CODE: result = new ConstantOopReadValue(stream); break;
109
case CONSTANT_LONG_CODE: result = new ConstantLongValue(stream); break;
110
case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream); break;
111
case OBJECT_CODE: result = stream->read_object_value(false /*is_auto_box*/); break;
112
case AUTO_BOX_OBJECT_CODE: result = stream->read_object_value(true /*is_auto_box*/); break;
113
case OBJECT_ID_CODE: result = stream->get_cached_object(); break;
114
case MARKER_CODE: result = new MarkerValue(); break;
115
default: ShouldNotReachHere();
116
}
117
return result;
118
}
119
120
// LocationValue
121
122
LocationValue::LocationValue(DebugInfoReadStream* stream) {
123
_location = Location(stream);
124
}
125
126
void LocationValue::write_on(DebugInfoWriteStream* stream) {
127
stream->write_int(LOCATION_CODE);
128
location().write_on(stream);
129
}
130
131
void LocationValue::print_on(outputStream* st) const {
132
location().print_on(st);
133
}
134
135
// MarkerValue
136
137
void MarkerValue::write_on(DebugInfoWriteStream* stream) {
138
stream->write_int(MARKER_CODE);
139
}
140
141
void MarkerValue::print_on(outputStream* st) const {
142
st->print("marker");
143
}
144
145
// ObjectValue
146
147
void ObjectValue::set_value(oop value) {
148
_value = Handle(Thread::current(), value);
149
}
150
151
void ObjectValue::read_object(DebugInfoReadStream* stream) {
152
_klass = read_from(stream);
153
assert(_klass->is_constant_oop(), "should be constant java mirror oop");
154
int length = stream->read_int();
155
for (int i = 0; i < length; i++) {
156
ScopeValue* val = read_from(stream);
157
_field_values.append(val);
158
}
159
}
160
161
void ObjectValue::write_on(DebugInfoWriteStream* stream) {
162
if (is_visited()) {
163
stream->write_int(OBJECT_ID_CODE);
164
stream->write_int(_id);
165
} else {
166
set_visited(true);
167
stream->write_int(is_auto_box() ? AUTO_BOX_OBJECT_CODE : OBJECT_CODE);
168
stream->write_int(_id);
169
_klass->write_on(stream);
170
int length = _field_values.length();
171
stream->write_int(length);
172
for (int i = 0; i < length; i++) {
173
_field_values.at(i)->write_on(stream);
174
}
175
}
176
}
177
178
void ObjectValue::print_on(outputStream* st) const {
179
st->print("%s[%d]", is_auto_box() ? "box_obj" : "obj", _id);
180
}
181
182
void ObjectValue::print_fields_on(outputStream* st) const {
183
#ifndef PRODUCT
184
if (_field_values.length() > 0) {
185
_field_values.at(0)->print_on(st);
186
}
187
for (int i = 1; i < _field_values.length(); i++) {
188
st->print(", ");
189
_field_values.at(i)->print_on(st);
190
}
191
#endif
192
}
193
194
// ConstantIntValue
195
196
ConstantIntValue::ConstantIntValue(DebugInfoReadStream* stream) {
197
_value = stream->read_signed_int();
198
}
199
200
void ConstantIntValue::write_on(DebugInfoWriteStream* stream) {
201
stream->write_int(CONSTANT_INT_CODE);
202
stream->write_signed_int(value());
203
}
204
205
void ConstantIntValue::print_on(outputStream* st) const {
206
st->print("%d", value());
207
}
208
209
// ConstantLongValue
210
211
ConstantLongValue::ConstantLongValue(DebugInfoReadStream* stream) {
212
_value = stream->read_long();
213
}
214
215
void ConstantLongValue::write_on(DebugInfoWriteStream* stream) {
216
stream->write_int(CONSTANT_LONG_CODE);
217
stream->write_long(value());
218
}
219
220
void ConstantLongValue::print_on(outputStream* st) const {
221
st->print(JLONG_FORMAT, value());
222
}
223
224
// ConstantDoubleValue
225
226
ConstantDoubleValue::ConstantDoubleValue(DebugInfoReadStream* stream) {
227
_value = stream->read_double();
228
}
229
230
void ConstantDoubleValue::write_on(DebugInfoWriteStream* stream) {
231
stream->write_int(CONSTANT_DOUBLE_CODE);
232
stream->write_double(value());
233
}
234
235
void ConstantDoubleValue::print_on(outputStream* st) const {
236
st->print("%f", value());
237
}
238
239
// ConstantOopWriteValue
240
241
void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
242
#ifdef ASSERT
243
{
244
// cannot use ThreadInVMfromNative here since in case of JVMCI compiler,
245
// thread is already in VM state.
246
ThreadInVMfromUnknown tiv;
247
assert(JNIHandles::resolve(value()) == NULL ||
248
Universe::heap()->is_in(JNIHandles::resolve(value())),
249
"Should be in heap");
250
}
251
#endif
252
stream->write_int(CONSTANT_OOP_CODE);
253
stream->write_handle(value());
254
}
255
256
void ConstantOopWriteValue::print_on(outputStream* st) const {
257
// using ThreadInVMfromUnknown here since in case of JVMCI compiler,
258
// thread is already in VM state.
259
ThreadInVMfromUnknown tiv;
260
JNIHandles::resolve(value())->print_value_on(st);
261
}
262
263
264
// ConstantOopReadValue
265
266
ConstantOopReadValue::ConstantOopReadValue(DebugInfoReadStream* stream) {
267
_value = Handle(Thread::current(), stream->read_oop());
268
assert(_value() == NULL ||
269
Universe::heap()->is_in(_value()), "Should be in heap");
270
}
271
272
void ConstantOopReadValue::write_on(DebugInfoWriteStream* stream) {
273
ShouldNotReachHere();
274
}
275
276
void ConstantOopReadValue::print_on(outputStream* st) const {
277
if (value()() != NULL) {
278
value()()->print_value_on(st);
279
} else {
280
st->print("NULL");
281
}
282
}
283
284
285
// MonitorValue
286
287
MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated) {
288
_owner = owner;
289
_basic_lock = basic_lock;
290
_eliminated = eliminated;
291
}
292
293
MonitorValue::MonitorValue(DebugInfoReadStream* stream) {
294
_basic_lock = Location(stream);
295
_owner = ScopeValue::read_from(stream);
296
_eliminated = (stream->read_bool() != 0);
297
}
298
299
void MonitorValue::write_on(DebugInfoWriteStream* stream) {
300
_basic_lock.write_on(stream);
301
_owner->write_on(stream);
302
stream->write_bool(_eliminated);
303
}
304
305
#ifndef PRODUCT
306
void MonitorValue::print_on(outputStream* st) const {
307
st->print("monitor{");
308
owner()->print_on(st);
309
st->print(",");
310
basic_lock().print_on(st);
311
st->print("}");
312
if (_eliminated) {
313
st->print(" (eliminated)");
314
}
315
}
316
#endif
317
318