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   assert(_klass->is_constant_oop(), "should be constant java mirror oop");
154   int length = stream->read_int();
155   for (int i = 0; i < length; i++) {
156     ScopeValue* val = read_from(stream);
157     _field_values.append(val);
158   }
159 }
160 
161 void ObjectValue::write_on(DebugInfoWriteStream* stream) {
162   if (is_visited()) {
163     stream->write_int(OBJECT_ID_CODE);
164     stream->write_int(_id);
165   } else {
166     set_visited(true);
167     stream->write_int(is_auto_box() ? AUTO_BOX_OBJECT_CODE : OBJECT_CODE);
168     stream->write_int(_id);
169     _klass->write_on(stream);
170     int length = _field_values.length();
171     stream->write_int(length);
172     for (int i = 0; i < length; i++) {
173       _field_values.at(i)->write_on(stream);
174     }
175   }
176 }
177 
178 void ObjectValue::print_on(outputStream* st) const {
179   st->print("%s[%d]", is_auto_box() ? "box_obj" : "obj", _id);
180 }
181 
182 void ObjectValue::print_fields_on(outputStream* st) const {
183 #ifndef PRODUCT
184   if (_field_values.length() > 0) {
185     _field_values.at(0)->print_on(st);
186   }
187   for (int i = 1; i < _field_values.length(); i++) {
188     st->print(", ");
189     _field_values.at(i)->print_on(st);
190   }
191 #endif
192 }
193 
194 // ConstantIntValue
195 
196 ConstantIntValue::ConstantIntValue(DebugInfoReadStream* stream) {
197   _value = stream->read_signed_int();
198 }
199 
200 void ConstantIntValue::write_on(DebugInfoWriteStream* stream) {
201   stream->write_int(CONSTANT_INT_CODE);
202   stream->write_signed_int(value());
203 }
204 
205 void ConstantIntValue::print_on(outputStream* st) const {
206   st->print("%d", value());
207 }
208 
209 // ConstantLongValue
210 
211 ConstantLongValue::ConstantLongValue(DebugInfoReadStream* stream) {
212   _value = stream->read_long();
213 }
214 
215 void ConstantLongValue::write_on(DebugInfoWriteStream* stream) {
216   stream->write_int(CONSTANT_LONG_CODE);
217   stream->write_long(value());
218 }
219 
220 void ConstantLongValue::print_on(outputStream* st) const {
221   st->print(JLONG_FORMAT, value());
222 }
223 
224 // ConstantDoubleValue
225 
226 ConstantDoubleValue::ConstantDoubleValue(DebugInfoReadStream* stream) {
227   _value = stream->read_double();
228 }
229 
230 void ConstantDoubleValue::write_on(DebugInfoWriteStream* stream) {
231   stream->write_int(CONSTANT_DOUBLE_CODE);
232   stream->write_double(value());
233 }
234 
235 void ConstantDoubleValue::print_on(outputStream* st) const {
236   st->print("%f", value());
237 }
238 
239 // ConstantOopWriteValue
240 
241 void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
242 #ifdef ASSERT
243   {
244     // cannot use ThreadInVMfromNative here since in case of JVMCI compiler,
245     // thread is already in VM state.
246     ThreadInVMfromUnknown tiv;
247     assert(JNIHandles::resolve(value()) == NULL ||
248            Universe::heap()->is_in(JNIHandles::resolve(value())),
249            "Should be in heap");
250  }
251 #endif
252   stream->write_int(CONSTANT_OOP_CODE);
253   stream->write_handle(value());
254 }
255 
256 void ConstantOopWriteValue::print_on(outputStream* st) const {
257   // using ThreadInVMfromUnknown here since in case of JVMCI compiler,
258   // thread is already in VM state.
259   ThreadInVMfromUnknown tiv;
260   JNIHandles::resolve(value())->print_value_on(st);
261 }
262 
263 
264 // ConstantOopReadValue
265 
266 ConstantOopReadValue::ConstantOopReadValue(DebugInfoReadStream* stream) {
267   _value = Handle(Thread::current(), stream->read_oop());
268   assert(_value() == NULL ||
269          Universe::heap()->is_in(_value()), "Should be in heap");
270 }
271 
272 void ConstantOopReadValue::write_on(DebugInfoWriteStream* stream) {
273   ShouldNotReachHere();
274 }
275 
276 void ConstantOopReadValue::print_on(outputStream* st) const {
277   if (value()() != NULL) {
278     value()()->print_value_on(st);
279   } else {
280     st->print("NULL");
281   }
282 }
283 
284 
285 // MonitorValue
286 
287 MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated) {
288   _owner       = owner;
289   _basic_lock  = basic_lock;
290   _eliminated  = eliminated;
291 }
292 
293 MonitorValue::MonitorValue(DebugInfoReadStream* stream) {
294   _basic_lock  = Location(stream);
295   _owner       = ScopeValue::read_from(stream);
296   _eliminated  = (stream->read_bool() != 0);
297 }
298 
299 void MonitorValue::write_on(DebugInfoWriteStream* stream) {
300   _basic_lock.write_on(stream);
301   _owner->write_on(stream);
302   stream->write_bool(_eliminated);
303 }
304 
305 #ifndef PRODUCT
306 void MonitorValue::print_on(outputStream* st) const {
307   st->print("monitor{");
308   owner()->print_on(st);
309   st->print(",");
310   basic_lock().print_on(st);
311   st->print("}");
312   if (_eliminated) {
313     st->print(" (eliminated)");
314   }
315 }
316 #endif