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