1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/scopeDesc.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,253 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "code/debugInfoRec.hpp" 1.30 +#include "code/pcDesc.hpp" 1.31 +#include "code/scopeDesc.hpp" 1.32 +#include "memory/resourceArea.hpp" 1.33 +#include "oops/oop.inline.hpp" 1.34 +#include "runtime/handles.inline.hpp" 1.35 + 1.36 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.37 + 1.38 +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { 1.39 + _code = code; 1.40 + _decode_offset = decode_offset; 1.41 + _objects = decode_object_values(obj_decode_offset); 1.42 + _reexecute = reexecute; 1.43 + _return_oop = return_oop; 1.44 + decode_body(); 1.45 +} 1.46 + 1.47 +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) { 1.48 + _code = code; 1.49 + _decode_offset = decode_offset; 1.50 + _objects = decode_object_values(DebugInformationRecorder::serialized_null); 1.51 + _reexecute = reexecute; 1.52 + _return_oop = return_oop; 1.53 + decode_body(); 1.54 +} 1.55 + 1.56 + 1.57 +ScopeDesc::ScopeDesc(const ScopeDesc* parent) { 1.58 + _code = parent->_code; 1.59 + _decode_offset = parent->_sender_decode_offset; 1.60 + _objects = parent->_objects; 1.61 + _reexecute = false; //reexecute only applies to the first scope 1.62 + _return_oop = false; 1.63 + decode_body(); 1.64 +} 1.65 + 1.66 + 1.67 +void ScopeDesc::decode_body() { 1.68 + if (decode_offset() == DebugInformationRecorder::serialized_null) { 1.69 + // This is a sentinel record, which is only relevant to 1.70 + // approximate queries. Decode a reasonable frame. 1.71 + _sender_decode_offset = DebugInformationRecorder::serialized_null; 1.72 + _method = _code->method(); 1.73 + _bci = InvocationEntryBci; 1.74 + _locals_decode_offset = DebugInformationRecorder::serialized_null; 1.75 + _expressions_decode_offset = DebugInformationRecorder::serialized_null; 1.76 + _monitors_decode_offset = DebugInformationRecorder::serialized_null; 1.77 + } else { 1.78 + // decode header 1.79 + DebugInfoReadStream* stream = stream_at(decode_offset()); 1.80 + 1.81 + _sender_decode_offset = stream->read_int(); 1.82 + _method = stream->read_method(); 1.83 + _bci = stream->read_bci(); 1.84 + 1.85 + // decode offsets for body and sender 1.86 + _locals_decode_offset = stream->read_int(); 1.87 + _expressions_decode_offset = stream->read_int(); 1.88 + _monitors_decode_offset = stream->read_int(); 1.89 + } 1.90 +} 1.91 + 1.92 + 1.93 +GrowableArray<ScopeValue*>* ScopeDesc::decode_scope_values(int decode_offset) { 1.94 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.95 + DebugInfoReadStream* stream = stream_at(decode_offset); 1.96 + int length = stream->read_int(); 1.97 + GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*> (length); 1.98 + for (int index = 0; index < length; index++) { 1.99 + result->push(ScopeValue::read_from(stream)); 1.100 + } 1.101 + return result; 1.102 +} 1.103 + 1.104 +GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) { 1.105 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.106 + GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>(); 1.107 + DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); 1.108 + int length = stream->read_int(); 1.109 + for (int index = 0; index < length; index++) { 1.110 + // Objects values are pushed to 'result' array during read so that 1.111 + // object's fields could reference it (OBJECT_ID_CODE). 1.112 + (void)ScopeValue::read_from(stream); 1.113 + } 1.114 + assert(result->length() == length, "inconsistent debug information"); 1.115 + return result; 1.116 +} 1.117 + 1.118 + 1.119 +GrowableArray<MonitorValue*>* ScopeDesc::decode_monitor_values(int decode_offset) { 1.120 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.121 + DebugInfoReadStream* stream = stream_at(decode_offset); 1.122 + int length = stream->read_int(); 1.123 + GrowableArray<MonitorValue*>* result = new GrowableArray<MonitorValue*> (length); 1.124 + for (int index = 0; index < length; index++) { 1.125 + result->push(new MonitorValue(stream)); 1.126 + } 1.127 + return result; 1.128 +} 1.129 + 1.130 +DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { 1.131 + return new DebugInfoReadStream(_code, decode_offset, _objects); 1.132 +} 1.133 + 1.134 +GrowableArray<ScopeValue*>* ScopeDesc::locals() { 1.135 + return decode_scope_values(_locals_decode_offset); 1.136 +} 1.137 + 1.138 +GrowableArray<ScopeValue*>* ScopeDesc::expressions() { 1.139 + return decode_scope_values(_expressions_decode_offset); 1.140 +} 1.141 + 1.142 +GrowableArray<MonitorValue*>* ScopeDesc::monitors() { 1.143 + return decode_monitor_values(_monitors_decode_offset); 1.144 +} 1.145 + 1.146 +GrowableArray<ScopeValue*>* ScopeDesc::objects() { 1.147 + return _objects; 1.148 +} 1.149 + 1.150 +bool ScopeDesc::is_top() const { 1.151 + return _sender_decode_offset == DebugInformationRecorder::serialized_null; 1.152 +} 1.153 + 1.154 +ScopeDesc* ScopeDesc::sender() const { 1.155 + if (is_top()) return NULL; 1.156 + return new ScopeDesc(this); 1.157 +} 1.158 + 1.159 + 1.160 +#ifndef PRODUCT 1.161 + 1.162 +void ScopeDesc::print_value_on(outputStream* st) const { 1.163 + tty->print(" "); 1.164 + method()->print_short_name(st); 1.165 + int lineno = method()->line_number_from_bci(bci()); 1.166 + if (lineno != -1) { 1.167 + st->print_cr("@%d (line %d)", bci(), lineno); 1.168 + } else { 1.169 + st->print_cr("@%d", bci()); 1.170 + } 1.171 +} 1.172 + 1.173 +void ScopeDesc::print_on(outputStream* st) const { 1.174 + print_on(st, NULL); 1.175 +} 1.176 + 1.177 +void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const { 1.178 + // header 1.179 + if (pd != NULL) { 1.180 + tty->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset()); 1.181 + } 1.182 + 1.183 + print_value_on(st); 1.184 + // decode offsets 1.185 + if (WizardMode) { 1.186 + st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->content_begin()); 1.187 + st->print_cr(" offset: %d", _decode_offset); 1.188 + st->print_cr(" bci: %d", bci()); 1.189 + st->print_cr(" reexecute: %s", should_reexecute() ? "true" : "false"); 1.190 + st->print_cr(" locals: %d", _locals_decode_offset); 1.191 + st->print_cr(" stack: %d", _expressions_decode_offset); 1.192 + st->print_cr(" monitor: %d", _monitors_decode_offset); 1.193 + st->print_cr(" sender: %d", _sender_decode_offset); 1.194 + } 1.195 + // locals 1.196 + { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals(); 1.197 + if (l != NULL) { 1.198 + tty->print_cr(" Locals"); 1.199 + for (int index = 0; index < l->length(); index++) { 1.200 + st->print(" - l%d: ", index); 1.201 + l->at(index)->print_on(st); 1.202 + st->cr(); 1.203 + } 1.204 + } 1.205 + } 1.206 + // expressions 1.207 + { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions(); 1.208 + if (l != NULL) { 1.209 + st->print_cr(" Expression stack"); 1.210 + for (int index = 0; index < l->length(); index++) { 1.211 + st->print(" - @%d: ", index); 1.212 + l->at(index)->print_on(st); 1.213 + st->cr(); 1.214 + } 1.215 + } 1.216 + } 1.217 + // monitors 1.218 + { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors(); 1.219 + if (l != NULL) { 1.220 + st->print_cr(" Monitor stack"); 1.221 + for (int index = 0; index < l->length(); index++) { 1.222 + st->print(" - @%d: ", index); 1.223 + l->at(index)->print_on(st); 1.224 + st->cr(); 1.225 + } 1.226 + } 1.227 + } 1.228 + 1.229 +#ifdef COMPILER2 1.230 + if (DoEscapeAnalysis && is_top() && _objects != NULL) { 1.231 + tty->print_cr("Objects"); 1.232 + for (int i = 0; i < _objects->length(); i++) { 1.233 + ObjectValue* sv = (ObjectValue*) _objects->at(i); 1.234 + tty->print(" - %d: ", sv->id()); 1.235 + sv->print_fields_on(tty); 1.236 + tty->cr(); 1.237 + } 1.238 + } 1.239 +#endif // COMPILER2 1.240 +} 1.241 + 1.242 +#endif 1.243 + 1.244 +void ScopeDesc::verify() { 1.245 + ResourceMark rm; 1.246 + guarantee(method()->is_method(), "type check"); 1.247 + 1.248 + // check if we have any illegal elements on the expression stack 1.249 + { GrowableArray<ScopeValue*>* l = expressions(); 1.250 + if (l != NULL) { 1.251 + for (int index = 0; index < l->length(); index++) { 1.252 + //guarantee(!l->at(index)->is_illegal(), "expression element cannot be illegal"); 1.253 + } 1.254 + } 1.255 + } 1.256 +}