debugInfo.cpp revision 9149:a8a8604f890f
1/*
2 * Copyright (c) 1997, 2015, 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 "oops/oop.inline.hpp"
30#include "runtime/handles.inline.hpp"
31
32// Constructors
33
34DebugInfoWriteStream::DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size)
35: CompressedWriteStream(initial_size) {
36  _recorder = recorder;
37}
38
39// Serializing oops
40
41void DebugInfoWriteStream::write_handle(jobject h) {
42  write_int(recorder()->oop_recorder()->find_index(h));
43}
44
45void DebugInfoWriteStream::write_metadata(Metadata* h) {
46  write_int(recorder()->oop_recorder()->find_index(h));
47}
48
49oop DebugInfoReadStream::read_oop() {
50  oop o = code()->oop_at(read_int());
51  assert(o->is_oop_or_null(), "oop only");
52  return o;
53}
54
55ScopeValue* DebugInfoReadStream::read_object_value() {
56  int id = read_int();
57#ifdef ASSERT
58  assert(_obj_pool != NULL, "object pool does not exist");
59  for (int i = _obj_pool->length() - 1; i >= 0; i--) {
60    assert(_obj_pool->at(i)->as_ObjectValue()->id() != id, "should not be read twice");
61  }
62#endif
63  ObjectValue* result = new ObjectValue(id);
64  // Cache the object since an object field could reference it.
65  _obj_pool->push(result);
66  result->read_object(this);
67  return result;
68}
69
70ScopeValue* DebugInfoReadStream::get_cached_object() {
71  int id = read_int();
72  assert(_obj_pool != NULL, "object pool does not exist");
73  for (int i = _obj_pool->length() - 1; i >= 0; i--) {
74    ObjectValue* ov = _obj_pool->at(i)->as_ObjectValue();
75    if (ov->id() == id) {
76      return ov;
77    }
78  }
79  ShouldNotReachHere();
80  return NULL;
81}
82
83// Serializing scope values
84
85enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1,  CONSTANT_OOP_CODE = 2,
86                          CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4,
87                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6 };
88
89ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
90  ScopeValue* result = NULL;
91  switch(stream->read_int()) {
92   case LOCATION_CODE:        result = new LocationValue(stream);        break;
93   case CONSTANT_INT_CODE:    result = new ConstantIntValue(stream);     break;
94   case CONSTANT_OOP_CODE:    result = new ConstantOopReadValue(stream); break;
95   case CONSTANT_LONG_CODE:   result = new ConstantLongValue(stream);    break;
96   case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream);  break;
97   case OBJECT_CODE:          result = stream->read_object_value();      break;
98   case OBJECT_ID_CODE:       result = stream->get_cached_object();      break;
99   default: ShouldNotReachHere();
100  }
101  return result;
102}
103
104// LocationValue
105
106LocationValue::LocationValue(DebugInfoReadStream* stream) {
107  _location = Location(stream);
108}
109
110void LocationValue::write_on(DebugInfoWriteStream* stream) {
111  stream->write_int(LOCATION_CODE);
112  location().write_on(stream);
113}
114
115void LocationValue::print_on(outputStream* st) const {
116  location().print_on(st);
117}
118
119// ObjectValue
120
121void ObjectValue::read_object(DebugInfoReadStream* stream) {
122  _klass = read_from(stream);
123  assert(_klass->is_constant_oop(), "should be constant java mirror oop");
124  int length = stream->read_int();
125  for (int i = 0; i < length; i++) {
126    ScopeValue* val = read_from(stream);
127    _field_values.append(val);
128  }
129}
130
131void ObjectValue::write_on(DebugInfoWriteStream* stream) {
132  if (_visited) {
133    stream->write_int(OBJECT_ID_CODE);
134    stream->write_int(_id);
135  } else {
136    _visited = true;
137    stream->write_int(OBJECT_CODE);
138    stream->write_int(_id);
139    _klass->write_on(stream);
140    int length = _field_values.length();
141    stream->write_int(length);
142    for (int i = 0; i < length; i++) {
143      _field_values.at(i)->write_on(stream);
144    }
145  }
146}
147
148void ObjectValue::print_on(outputStream* st) const {
149  st->print("obj[%d]", _id);
150}
151
152void ObjectValue::print_fields_on(outputStream* st) const {
153#ifndef PRODUCT
154  if (_field_values.length() > 0) {
155    _field_values.at(0)->print_on(st);
156  }
157  for (int i = 1; i < _field_values.length(); i++) {
158    st->print(", ");
159    _field_values.at(i)->print_on(st);
160  }
161#endif
162}
163
164// ConstantIntValue
165
166ConstantIntValue::ConstantIntValue(DebugInfoReadStream* stream) {
167  _value = stream->read_signed_int();
168}
169
170void ConstantIntValue::write_on(DebugInfoWriteStream* stream) {
171  stream->write_int(CONSTANT_INT_CODE);
172  stream->write_signed_int(value());
173}
174
175void ConstantIntValue::print_on(outputStream* st) const {
176  st->print("%d", value());
177}
178
179// ConstantLongValue
180
181ConstantLongValue::ConstantLongValue(DebugInfoReadStream* stream) {
182  _value = stream->read_long();
183}
184
185void ConstantLongValue::write_on(DebugInfoWriteStream* stream) {
186  stream->write_int(CONSTANT_LONG_CODE);
187  stream->write_long(value());
188}
189
190void ConstantLongValue::print_on(outputStream* st) const {
191  st->print(INT64_FORMAT, value());
192}
193
194// ConstantDoubleValue
195
196ConstantDoubleValue::ConstantDoubleValue(DebugInfoReadStream* stream) {
197  _value = stream->read_double();
198}
199
200void ConstantDoubleValue::write_on(DebugInfoWriteStream* stream) {
201  stream->write_int(CONSTANT_DOUBLE_CODE);
202  stream->write_double(value());
203}
204
205void ConstantDoubleValue::print_on(outputStream* st) const {
206  st->print("%f", value());
207}
208
209// ConstantOopWriteValue
210
211void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
212  assert(JNIHandles::resolve(value()) == NULL ||
213         Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
214         "Should be in heap");
215  stream->write_int(CONSTANT_OOP_CODE);
216  stream->write_handle(value());
217}
218
219void ConstantOopWriteValue::print_on(outputStream* st) const {
220  JNIHandles::resolve(value())->print_value_on(st);
221}
222
223
224// ConstantOopReadValue
225
226ConstantOopReadValue::ConstantOopReadValue(DebugInfoReadStream* stream) {
227  _value = Handle(stream->read_oop());
228  assert(_value() == NULL ||
229         Universe::heap()->is_in_reserved(_value()), "Should be in heap");
230}
231
232void ConstantOopReadValue::write_on(DebugInfoWriteStream* stream) {
233  ShouldNotReachHere();
234}
235
236void ConstantOopReadValue::print_on(outputStream* st) const {
237  value()()->print_value_on(st);
238}
239
240
241// MonitorValue
242
243MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated) {
244  _owner       = owner;
245  _basic_lock  = basic_lock;
246  _eliminated  = eliminated;
247}
248
249MonitorValue::MonitorValue(DebugInfoReadStream* stream) {
250  _basic_lock  = Location(stream);
251  _owner       = ScopeValue::read_from(stream);
252  _eliminated  = (stream->read_bool() != 0);
253}
254
255void MonitorValue::write_on(DebugInfoWriteStream* stream) {
256  _basic_lock.write_on(stream);
257  _owner->write_on(stream);
258  stream->write_bool(_eliminated);
259}
260
261#ifndef PRODUCT
262void MonitorValue::print_on(outputStream* st) const {
263  st->print("monitor{");
264  owner()->print_on(st);
265  st->print(",");
266  basic_lock().print_on(st);
267  st->print("}");
268  if (_eliminated) {
269    st->print(" (eliminated)");
270  }
271}
272#endif
273