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