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