debugInfo.hpp revision 5776:de6a9e811145
1/*
2 * Copyright (c) 1997, 2013, 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#ifndef SHARE_VM_CODE_DEBUGINFO_HPP
26#define SHARE_VM_CODE_DEBUGINFO_HPP
27
28#include "code/compressedStream.hpp"
29#include "code/location.hpp"
30#include "code/nmethod.hpp"
31#include "code/oopRecorder.hpp"
32#include "runtime/stackValue.hpp"
33#include "utilities/growableArray.hpp"
34
35// Classes used for serializing debugging information.
36// These abstractions are introducted to provide symmetric
37// read and write operations.
38
39// ScopeValue        describes the value of a variable/expression in a scope
40// - LocationValue   describes a value in a given location (in frame or register)
41// - ConstantValue   describes a constant
42
43class ConstantOopReadValue;
44
45class ScopeValue: public ResourceObj {
46 public:
47  // Testers
48  virtual bool is_location() const { return false; }
49  virtual bool is_object() const { return false; }
50  virtual bool is_constant_int() const { return false; }
51  virtual bool is_constant_double() const { return false; }
52  virtual bool is_constant_long() const { return false; }
53  virtual bool is_constant_oop() const { return false; }
54  virtual bool equals(ScopeValue* other) const { return false; }
55
56  ConstantOopReadValue* as_ConstantOopReadValue() {
57    assert(is_constant_oop(), "must be");
58    return (ConstantOopReadValue*) this;
59  }
60
61  // Serialization of debugging information
62  virtual void write_on(DebugInfoWriteStream* stream) = 0;
63  static ScopeValue* read_from(DebugInfoReadStream* stream);
64};
65
66
67// A Location value describes a value in a given location; i.e. the corresponding
68// logical entity (e.g., a method temporary) lives in this location.
69
70class LocationValue: public ScopeValue {
71 private:
72  Location  _location;
73 public:
74  LocationValue(Location location)           { _location = location; }
75  bool      is_location() const              { return true; }
76  Location  location() const                 { return _location; }
77
78  // Serialization of debugging information
79  LocationValue(DebugInfoReadStream* stream);
80  void write_on(DebugInfoWriteStream* stream);
81
82  // Printing
83  void print_on(outputStream* st) const;
84};
85
86
87// An ObjectValue describes an object eliminated by escape analysis.
88
89class ObjectValue: public ScopeValue {
90 private:
91  int                        _id;
92  ScopeValue*                _klass;
93  GrowableArray<ScopeValue*> _field_values;
94  Handle                     _value;
95  bool                       _visited;
96
97 public:
98  ObjectValue(int id, ScopeValue* klass)
99     : _id(id)
100     , _klass(klass)
101     , _field_values()
102     , _value()
103     , _visited(false) {
104    assert(klass->is_constant_oop(), "should be constant java mirror oop");
105  }
106
107  ObjectValue(int id)
108     : _id(id)
109     , _klass(NULL)
110     , _field_values()
111     , _value()
112     , _visited(false) {}
113
114  // Accessors
115  bool                        is_object() const         { return true; }
116  int                         id() const                { return _id; }
117  ScopeValue*                 klass() const             { return _klass; }
118  GrowableArray<ScopeValue*>* field_values()            { return &_field_values; }
119  ScopeValue*                 field_at(int i) const     { return _field_values.at(i); }
120  int                         field_size()              { return _field_values.length(); }
121  Handle                      value() const             { return _value; }
122  bool                        is_visited() const        { return _visited; }
123
124  void                        set_value(oop value)      { _value = Handle(value); }
125  void                        set_visited(bool visited) { _visited = false; }
126
127  // Serialization of debugging information
128  void read_object(DebugInfoReadStream* stream);
129  void write_on(DebugInfoWriteStream* stream);
130
131  // Printing
132  void print_on(outputStream* st) const;
133  void print_fields_on(outputStream* st) const;
134};
135
136
137// A ConstantIntValue describes a constant int; i.e., the corresponding logical entity
138// is either a source constant or its computation has been constant-folded.
139
140class ConstantIntValue: public ScopeValue {
141 private:
142  jint _value;
143 public:
144  ConstantIntValue(jint value)         { _value = value; }
145  jint value() const                   { return _value;  }
146  bool is_constant_int() const         { return true;    }
147  bool equals(ScopeValue* other) const { return false;   }
148
149  // Serialization of debugging information
150  ConstantIntValue(DebugInfoReadStream* stream);
151  void write_on(DebugInfoWriteStream* stream);
152
153  // Printing
154  void print_on(outputStream* st) const;
155};
156
157class ConstantLongValue: public ScopeValue {
158 private:
159  jlong _value;
160 public:
161  ConstantLongValue(jlong value)       { _value = value; }
162  jlong value() const                  { return _value;  }
163  bool is_constant_long() const        { return true;    }
164  bool equals(ScopeValue* other) const { return false;   }
165
166  // Serialization of debugging information
167  ConstantLongValue(DebugInfoReadStream* stream);
168  void write_on(DebugInfoWriteStream* stream);
169
170  // Printing
171  void print_on(outputStream* st) const;
172};
173
174class ConstantDoubleValue: public ScopeValue {
175 private:
176  jdouble _value;
177 public:
178  ConstantDoubleValue(jdouble value)   { _value = value; }
179  jdouble value() const                { return _value;  }
180  bool is_constant_double() const      { return true;    }
181  bool equals(ScopeValue* other) const { return false;   }
182
183  // Serialization of debugging information
184  ConstantDoubleValue(DebugInfoReadStream* stream);
185  void write_on(DebugInfoWriteStream* stream);
186
187  // Printing
188  void print_on(outputStream* st) const;
189};
190
191// A ConstantOopWriteValue is created by the compiler to
192// be written as debugging information.
193
194class ConstantOopWriteValue: public ScopeValue {
195 private:
196  jobject _value;
197 public:
198  ConstantOopWriteValue(jobject value) { _value = value; }
199  jobject value() const                { return _value;  }
200  bool is_constant_oop() const         { return true;    }
201  bool equals(ScopeValue* other) const { return false;   }
202
203  // Serialization of debugging information
204  void write_on(DebugInfoWriteStream* stream);
205
206  // Printing
207  void print_on(outputStream* st) const;
208};
209
210// A ConstantOopReadValue is created by the VM when reading
211// debug information
212
213class ConstantOopReadValue: public ScopeValue {
214 private:
215  Handle _value;
216 public:
217  Handle value() const                 { return _value;  }
218  bool is_constant_oop() const         { return true;    }
219  bool equals(ScopeValue* other) const { return false;   }
220
221  // Serialization of debugging information
222  ConstantOopReadValue(DebugInfoReadStream* stream);
223  void write_on(DebugInfoWriteStream* stream);
224
225  // Printing
226  void print_on(outputStream* st) const;
227};
228
229// MonitorValue describes the pair used for monitor_enter and monitor_exit.
230
231class MonitorValue: public ResourceObj {
232 private:
233  ScopeValue* _owner;
234  Location    _basic_lock;
235  bool        _eliminated;
236 public:
237  // Constructor
238  MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated = false);
239
240  // Accessors
241  ScopeValue*  owner()      const { return _owner; }
242  Location     basic_lock() const { return _basic_lock;  }
243  bool         eliminated() const { return _eliminated; }
244
245  // Serialization of debugging information
246  MonitorValue(DebugInfoReadStream* stream);
247  void write_on(DebugInfoWriteStream* stream);
248
249  // Printing
250  void print_on(outputStream* st) const;
251};
252
253// DebugInfoReadStream specializes CompressedReadStream for reading
254// debugging information. Used by ScopeDesc.
255
256class DebugInfoReadStream : public CompressedReadStream {
257 private:
258  const nmethod* _code;
259  const nmethod* code() const { return _code; }
260  GrowableArray<ScopeValue*>* _obj_pool;
261 public:
262  DebugInfoReadStream(const nmethod* code, int offset, GrowableArray<ScopeValue*>* obj_pool = NULL) :
263    CompressedReadStream(code->scopes_data_begin(), offset) {
264    _code = code;
265    _obj_pool = obj_pool;
266
267  } ;
268
269  oop read_oop() {
270    oop o = code()->oop_at(read_int());
271    assert(o == NULL || o->is_oop(), "oop only");
272    return o;
273  }
274  Method* read_method() {
275    Method* o = (Method*)(code()->metadata_at(read_int()));
276    assert(o == NULL ||
277           o->is_metaspace_object(), "meta data only");
278    return o;
279  }
280  ScopeValue* read_object_value();
281  ScopeValue* get_cached_object();
282  // BCI encoding is mostly unsigned, but -1 is a distinguished value
283  int read_bci() { return read_int() + InvocationEntryBci; }
284};
285
286// DebugInfoWriteStream specializes CompressedWriteStream for
287// writing debugging information. Used by ScopeDescRecorder.
288
289class DebugInfoWriteStream : public CompressedWriteStream {
290 private:
291  DebugInformationRecorder* _recorder;
292  DebugInformationRecorder* recorder() const { return _recorder; }
293 public:
294  DebugInfoWriteStream(DebugInformationRecorder* recorder, int initial_size);
295  void write_handle(jobject h);
296  void write_bci(int bci) { write_int(bci - InvocationEntryBci); }
297
298  void write_metadata(Metadata* m);
299};
300
301#endif // SHARE_VM_CODE_DEBUGINFO_HPP
302