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