1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/scopeDesc.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,237 @@ 1.4 +/* 1.5 + * Copyright 1997-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_scopeDesc.cpp.incl" 1.30 + 1.31 + 1.32 +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset) { 1.33 + _code = code; 1.34 + _decode_offset = decode_offset; 1.35 + _objects = decode_object_values(obj_decode_offset); 1.36 + decode_body(); 1.37 +} 1.38 + 1.39 +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset) { 1.40 + _code = code; 1.41 + _decode_offset = decode_offset; 1.42 + _objects = decode_object_values(DebugInformationRecorder::serialized_null); 1.43 + decode_body(); 1.44 +} 1.45 + 1.46 + 1.47 +ScopeDesc::ScopeDesc(const ScopeDesc* parent) { 1.48 + _code = parent->_code; 1.49 + _decode_offset = parent->_sender_decode_offset; 1.50 + _objects = parent->_objects; 1.51 + decode_body(); 1.52 +} 1.53 + 1.54 + 1.55 +void ScopeDesc::decode_body() { 1.56 + if (decode_offset() == DebugInformationRecorder::serialized_null) { 1.57 + // This is a sentinel record, which is only relevant to 1.58 + // approximate queries. Decode a reasonable frame. 1.59 + _sender_decode_offset = DebugInformationRecorder::serialized_null; 1.60 + _method = methodHandle(_code->method()); 1.61 + _bci = InvocationEntryBci; 1.62 + _locals_decode_offset = DebugInformationRecorder::serialized_null; 1.63 + _expressions_decode_offset = DebugInformationRecorder::serialized_null; 1.64 + _monitors_decode_offset = DebugInformationRecorder::serialized_null; 1.65 + } else { 1.66 + // decode header 1.67 + DebugInfoReadStream* stream = stream_at(decode_offset()); 1.68 + 1.69 + _sender_decode_offset = stream->read_int(); 1.70 + _method = methodHandle((methodOop) stream->read_oop()); 1.71 + _bci = stream->read_bci(); 1.72 + // decode offsets for body and sender 1.73 + _locals_decode_offset = stream->read_int(); 1.74 + _expressions_decode_offset = stream->read_int(); 1.75 + _monitors_decode_offset = stream->read_int(); 1.76 + } 1.77 +} 1.78 + 1.79 + 1.80 +GrowableArray<ScopeValue*>* ScopeDesc::decode_scope_values(int decode_offset) { 1.81 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.82 + DebugInfoReadStream* stream = stream_at(decode_offset); 1.83 + int length = stream->read_int(); 1.84 + GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*> (length); 1.85 + for (int index = 0; index < length; index++) { 1.86 + result->push(ScopeValue::read_from(stream)); 1.87 + } 1.88 + return result; 1.89 +} 1.90 + 1.91 +GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) { 1.92 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.93 + GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>(); 1.94 + DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); 1.95 + int length = stream->read_int(); 1.96 + for (int index = 0; index < length; index++) { 1.97 + result->push(ScopeValue::read_from(stream)); 1.98 + } 1.99 + assert(result->length() == length, "inconsistent debug information"); 1.100 + return result; 1.101 +} 1.102 + 1.103 + 1.104 +GrowableArray<MonitorValue*>* ScopeDesc::decode_monitor_values(int decode_offset) { 1.105 + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; 1.106 + DebugInfoReadStream* stream = stream_at(decode_offset); 1.107 + int length = stream->read_int(); 1.108 + GrowableArray<MonitorValue*>* result = new GrowableArray<MonitorValue*> (length); 1.109 + for (int index = 0; index < length; index++) { 1.110 + result->push(new MonitorValue(stream)); 1.111 + } 1.112 + return result; 1.113 +} 1.114 + 1.115 +DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { 1.116 + return new DebugInfoReadStream(_code, decode_offset, _objects); 1.117 +} 1.118 + 1.119 +GrowableArray<ScopeValue*>* ScopeDesc::locals() { 1.120 + return decode_scope_values(_locals_decode_offset); 1.121 +} 1.122 + 1.123 +GrowableArray<ScopeValue*>* ScopeDesc::expressions() { 1.124 + return decode_scope_values(_expressions_decode_offset); 1.125 +} 1.126 + 1.127 +GrowableArray<MonitorValue*>* ScopeDesc::monitors() { 1.128 + return decode_monitor_values(_monitors_decode_offset); 1.129 +} 1.130 + 1.131 +GrowableArray<ScopeValue*>* ScopeDesc::objects() { 1.132 + return _objects; 1.133 +} 1.134 + 1.135 +bool ScopeDesc::is_top() const { 1.136 + return _sender_decode_offset == DebugInformationRecorder::serialized_null; 1.137 +} 1.138 + 1.139 +ScopeDesc* ScopeDesc::sender() const { 1.140 + if (is_top()) return NULL; 1.141 + return new ScopeDesc(this); 1.142 +} 1.143 + 1.144 + 1.145 +#ifndef PRODUCT 1.146 + 1.147 +void ScopeDesc::print_value_on(outputStream* st) const { 1.148 + tty->print(" "); 1.149 + method()()->print_short_name(st); 1.150 + int lineno = method()->line_number_from_bci(bci()); 1.151 + if (lineno != -1) { 1.152 + st->print_cr("@%d (line %d)", bci(), lineno); 1.153 + } else { 1.154 + st->print_cr("@%d", bci()); 1.155 + } 1.156 +} 1.157 + 1.158 +void ScopeDesc::print_on(outputStream* st) const { 1.159 + print_on(st, NULL); 1.160 +} 1.161 + 1.162 +void ScopeDesc::print_on(outputStream* st, PcDesc* pd) const { 1.163 + // header 1.164 + if (pd != NULL) { 1.165 + tty->print_cr("ScopeDesc(pc=" PTR_FORMAT " offset=%x):", pd->real_pc(_code), pd->pc_offset()); 1.166 + } 1.167 + 1.168 + print_value_on(st); 1.169 + // decode offsets 1.170 + if (WizardMode) { 1.171 + st->print("ScopeDesc[%d]@" PTR_FORMAT " ", _decode_offset, _code->instructions_begin()); 1.172 + st->print_cr(" offset: %d", _decode_offset); 1.173 + st->print_cr(" bci: %d", bci()); 1.174 + st->print_cr(" locals: %d", _locals_decode_offset); 1.175 + st->print_cr(" stack: %d", _expressions_decode_offset); 1.176 + st->print_cr(" monitor: %d", _monitors_decode_offset); 1.177 + st->print_cr(" sender: %d", _sender_decode_offset); 1.178 + } 1.179 + // locals 1.180 + { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals(); 1.181 + if (l != NULL) { 1.182 + tty->print_cr(" Locals"); 1.183 + for (int index = 0; index < l->length(); index++) { 1.184 + st->print(" - l%d: ", index); 1.185 + l->at(index)->print_on(st); 1.186 + st->cr(); 1.187 + } 1.188 + } 1.189 + } 1.190 + // expressions 1.191 + { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions(); 1.192 + if (l != NULL) { 1.193 + st->print_cr(" Expression stack"); 1.194 + for (int index = 0; index < l->length(); index++) { 1.195 + st->print(" - @%d: ", index); 1.196 + l->at(index)->print_on(st); 1.197 + st->cr(); 1.198 + } 1.199 + } 1.200 + } 1.201 + // monitors 1.202 + { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors(); 1.203 + if (l != NULL) { 1.204 + st->print_cr(" Monitor stack"); 1.205 + for (int index = 0; index < l->length(); index++) { 1.206 + st->print(" - @%d: ", index); 1.207 + l->at(index)->print_on(st); 1.208 + st->cr(); 1.209 + } 1.210 + } 1.211 + } 1.212 + 1.213 +#ifdef COMPILER2 1.214 + if (DoEscapeAnalysis && is_top() && _objects != NULL) { 1.215 + tty->print_cr("Objects"); 1.216 + for (int i = 0; i < _objects->length(); i++) { 1.217 + ObjectValue* sv = (ObjectValue*) _objects->at(i); 1.218 + tty->print(" - %d: ", sv->id()); 1.219 + sv->print_fields_on(tty); 1.220 + tty->cr(); 1.221 + } 1.222 + } 1.223 +#endif // COMPILER2 1.224 +} 1.225 + 1.226 +#endif 1.227 + 1.228 +void ScopeDesc::verify() { 1.229 + ResourceMark rm; 1.230 + guarantee(method()->is_method(), "type check"); 1.231 + 1.232 + // check if we have any illegal elements on the expression stack 1.233 + { GrowableArray<ScopeValue*>* l = expressions(); 1.234 + if (l != NULL) { 1.235 + for (int index = 0; index < l->length(); index++) { 1.236 + //guarantee(!l->at(index)->is_illegal(), "expression element cannot be illegal"); 1.237 + } 1.238 + } 1.239 + } 1.240 +}