1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/vframe_hp.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,337 @@ 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/_vframe_hp.cpp.incl" 1.30 + 1.31 + 1.32 +// ------------- compiledVFrame -------------- 1.33 + 1.34 +StackValueCollection* compiledVFrame::locals() const { 1.35 + // Natives has no scope 1.36 + if (scope() == NULL) return new StackValueCollection(0); 1.37 + GrowableArray<ScopeValue*>* scv_list = scope()->locals(); 1.38 + if (scv_list == NULL) return new StackValueCollection(0); 1.39 + 1.40 + // scv_list is the list of ScopeValues describing the JVM stack state. 1.41 + // There is one scv_list entry for every JVM stack state in use. 1.42 + int length = scv_list->length(); 1.43 + StackValueCollection* result = new StackValueCollection(length); 1.44 + // In rare instances set_locals may have occurred in which case 1.45 + // there are local values that are not described by the ScopeValue anymore 1.46 + GrowableArray<jvmtiDeferredLocalVariable*>* deferred = NULL; 1.47 + GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals(); 1.48 + if (list != NULL ) { 1.49 + // In real life this never happens or is typically a single element search 1.50 + for (int i = 0; i < list->length(); i++) { 1.51 + if (list->at(i)->matches((vframe*)this)) { 1.52 + deferred = list->at(i)->locals(); 1.53 + break; 1.54 + } 1.55 + } 1.56 + } 1.57 + 1.58 + for( int i = 0; i < length; i++ ) { 1.59 + result->add( create_stack_value(scv_list->at(i)) ); 1.60 + } 1.61 + 1.62 + // Replace specified locals with any deferred writes that are present 1.63 + if (deferred != NULL) { 1.64 + for ( int l = 0; l < deferred->length() ; l ++) { 1.65 + jvmtiDeferredLocalVariable* val = deferred->at(l); 1.66 + switch (val->type()) { 1.67 + case T_BOOLEAN: 1.68 + result->set_int_at(val->index(), val->value().z); 1.69 + break; 1.70 + case T_CHAR: 1.71 + result->set_int_at(val->index(), val->value().c); 1.72 + break; 1.73 + case T_FLOAT: 1.74 + result->set_float_at(val->index(), val->value().f); 1.75 + break; 1.76 + case T_DOUBLE: 1.77 + result->set_double_at(val->index(), val->value().d); 1.78 + break; 1.79 + case T_BYTE: 1.80 + result->set_int_at(val->index(), val->value().b); 1.81 + break; 1.82 + case T_SHORT: 1.83 + result->set_int_at(val->index(), val->value().s); 1.84 + break; 1.85 + case T_INT: 1.86 + result->set_int_at(val->index(), val->value().i); 1.87 + break; 1.88 + case T_LONG: 1.89 + result->set_long_at(val->index(), val->value().j); 1.90 + break; 1.91 + case T_OBJECT: 1.92 + { 1.93 + Handle obj((oop)val->value().l); 1.94 + result->set_obj_at(val->index(), obj); 1.95 + } 1.96 + break; 1.97 + default: 1.98 + ShouldNotReachHere(); 1.99 + } 1.100 + } 1.101 + } 1.102 + 1.103 + return result; 1.104 +} 1.105 + 1.106 + 1.107 +void compiledVFrame::set_locals(StackValueCollection* values) const { 1.108 + 1.109 + fatal("Should use update_local for each local update"); 1.110 +} 1.111 + 1.112 +void compiledVFrame::update_local(BasicType type, int index, jvalue value) { 1.113 + 1.114 +#ifdef ASSERT 1.115 + 1.116 + assert(fr().is_deoptimized_frame(), "frame must be scheduled for deoptimization"); 1.117 +#endif /* ASSERT */ 1.118 + GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = thread()->deferred_locals(); 1.119 + if (deferred != NULL ) { 1.120 + // See if this vframe has already had locals with deferred writes 1.121 + int f; 1.122 + for ( f = 0 ; f < deferred->length() ; f++ ) { 1.123 + if (deferred->at(f)->matches(this)) { 1.124 + // Matching, vframe now see if the local already had deferred write 1.125 + GrowableArray<jvmtiDeferredLocalVariable*>* locals = deferred->at(f)->locals(); 1.126 + int l; 1.127 + for (l = 0 ; l < locals->length() ; l++ ) { 1.128 + if (locals->at(l)->index() == index) { 1.129 + locals->at(l)->set_value(value); 1.130 + return; 1.131 + } 1.132 + } 1.133 + // No matching local already present. Push a new value onto the deferred collection 1.134 + locals->push(new jvmtiDeferredLocalVariable(index, type, value)); 1.135 + return; 1.136 + } 1.137 + } 1.138 + // No matching vframe must push a new vframe 1.139 + } else { 1.140 + // No deferred updates pending for this thread. 1.141 + // allocate in C heap 1.142 + deferred = new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true); 1.143 + thread()->set_deferred_locals(deferred); 1.144 + } 1.145 + deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id())); 1.146 + assert(deferred->top()->id() == fr().id(), "Huh? Must match"); 1.147 + deferred->top()->set_local_at(index, type, value); 1.148 +} 1.149 + 1.150 +StackValueCollection* compiledVFrame::expressions() const { 1.151 + // Natives has no scope 1.152 + if (scope() == NULL) return new StackValueCollection(0); 1.153 + GrowableArray<ScopeValue*>* scv_list = scope()->expressions(); 1.154 + if (scv_list == NULL) return new StackValueCollection(0); 1.155 + 1.156 + // scv_list is the list of ScopeValues describing the JVM stack state. 1.157 + // There is one scv_list entry for every JVM stack state in use. 1.158 + int length = scv_list->length(); 1.159 + StackValueCollection* result = new StackValueCollection(length); 1.160 + for( int i = 0; i < length; i++ ) 1.161 + result->add( create_stack_value(scv_list->at(i)) ); 1.162 + 1.163 + return result; 1.164 +} 1.165 + 1.166 + 1.167 +// The implementation of the following two methods was factorized into the 1.168 +// class StackValue because it is also used from within deoptimization.cpp for 1.169 +// rematerialization and relocking of non-escaping objects. 1.170 + 1.171 +StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const { 1.172 + return StackValue::create_stack_value(&_fr, register_map(), sv); 1.173 +} 1.174 + 1.175 +BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const { 1.176 + return StackValue::resolve_monitor_lock(&_fr, location); 1.177 +} 1.178 + 1.179 + 1.180 +GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const { 1.181 + // Natives has no scope 1.182 + if (scope() == NULL) { 1.183 + nmethod* nm = code(); 1.184 + methodOop method = nm->method(); 1.185 + assert(method->is_native(), ""); 1.186 + if (!method->is_synchronized()) { 1.187 + return new GrowableArray<MonitorInfo*>(0); 1.188 + } 1.189 + // This monitor is really only needed for UseBiasedLocking, but 1.190 + // return it in all cases for now as it might be useful for stack 1.191 + // traces and tools as well 1.192 + GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1); 1.193 + // Casting away const 1.194 + frame& fr = (frame&) _fr; 1.195 + MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm), 1.196 + fr.compiled_synchronized_native_monitor(nm)); 1.197 + monitors->push(info); 1.198 + return monitors; 1.199 + } 1.200 + GrowableArray<MonitorValue*>* monitors = scope()->monitors(); 1.201 + if (monitors == NULL) { 1.202 + return new GrowableArray<MonitorInfo*>(0); 1.203 + } 1.204 + GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length()); 1.205 + for (int index = 0; index < monitors->length(); index++) { 1.206 + MonitorValue* mv = monitors->at(index); 1.207 + StackValue *owner_sv = create_stack_value(mv->owner()); // it is an oop 1.208 + result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()))); 1.209 + } 1.210 + return result; 1.211 +} 1.212 + 1.213 + 1.214 +compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm) 1.215 +: javaVFrame(fr, reg_map, thread) { 1.216 + _scope = NULL; 1.217 + // Compiled method (native stub or Java code) 1.218 + // native wrappers have no scope data, it is implied 1.219 + if (!nm->is_native_method()) { 1.220 + _scope = nm->scope_desc_at(_fr.pc()); 1.221 + } 1.222 +} 1.223 + 1.224 +compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope) 1.225 +: javaVFrame(fr, reg_map, thread) { 1.226 + _scope = scope; 1.227 + guarantee(_scope != NULL, "scope must be present"); 1.228 +} 1.229 + 1.230 + 1.231 +bool compiledVFrame::is_top() const { 1.232 + // FIX IT: Remove this when new native stubs are in place 1.233 + if (scope() == NULL) return true; 1.234 + return scope()->is_top(); 1.235 +} 1.236 + 1.237 + 1.238 +nmethod* compiledVFrame::code() const { 1.239 + return CodeCache::find_nmethod(_fr.pc()); 1.240 +} 1.241 + 1.242 + 1.243 +methodOop compiledVFrame::method() const { 1.244 + if (scope() == NULL) { 1.245 + // native nmethods have no scope the method is implied 1.246 + nmethod* nm = code(); 1.247 + assert(nm->is_native_method(), "must be native"); 1.248 + return nm->method(); 1.249 + } 1.250 + return scope()->method()(); 1.251 +} 1.252 + 1.253 + 1.254 +int compiledVFrame::bci() const { 1.255 + int raw = raw_bci(); 1.256 + return raw == SynchronizationEntryBCI ? 0 : raw; 1.257 +} 1.258 + 1.259 + 1.260 +int compiledVFrame::raw_bci() const { 1.261 + if (scope() == NULL) { 1.262 + // native nmethods have no scope the method/bci is implied 1.263 + nmethod* nm = code(); 1.264 + assert(nm->is_native_method(), "must be native"); 1.265 + return 0; 1.266 + } 1.267 + return scope()->bci(); 1.268 +} 1.269 + 1.270 + 1.271 +vframe* compiledVFrame::sender() const { 1.272 + const frame f = fr(); 1.273 + if (scope() == NULL) { 1.274 + // native nmethods have no scope the method/bci is implied 1.275 + nmethod* nm = code(); 1.276 + assert(nm->is_native_method(), "must be native"); 1.277 + return vframe::sender(); 1.278 + } else { 1.279 + return scope()->is_top() 1.280 + ? vframe::sender() 1.281 + : new compiledVFrame(&f, register_map(), thread(), scope()->sender()); 1.282 + } 1.283 +} 1.284 + 1.285 +jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(methodOop method, int bci, intptr_t* id) { 1.286 + _method = method; 1.287 + _bci = bci; 1.288 + _id = id; 1.289 + // Alway will need at least one, must be on C heap 1.290 + _locals = new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariable*> (1, true); 1.291 +} 1.292 + 1.293 +jvmtiDeferredLocalVariableSet::~jvmtiDeferredLocalVariableSet() { 1.294 + for (int i = 0; i < _locals->length() ; i++ ) { 1.295 + delete _locals->at(i); 1.296 + } 1.297 + // Free growableArray and c heap for elements 1.298 + delete _locals; 1.299 +} 1.300 + 1.301 +bool jvmtiDeferredLocalVariableSet::matches(vframe* vf) { 1.302 + if (!vf->is_compiled_frame()) return false; 1.303 + compiledVFrame* cvf = (compiledVFrame*)vf; 1.304 + return cvf->fr().id() == id() && cvf->method() == method() && cvf->bci() == bci(); 1.305 +} 1.306 + 1.307 +void jvmtiDeferredLocalVariableSet::set_local_at(int idx, BasicType type, jvalue val) { 1.308 + int i; 1.309 + for ( i = 0 ; i < locals()->length() ; i++ ) { 1.310 + if ( locals()->at(i)->index() == idx) { 1.311 + assert(locals()->at(i)->type() == type, "Wrong type"); 1.312 + locals()->at(i)->set_value(val); 1.313 + return; 1.314 + } 1.315 + } 1.316 + locals()->push(new jvmtiDeferredLocalVariable(idx, type, val)); 1.317 +} 1.318 + 1.319 +void jvmtiDeferredLocalVariableSet::oops_do(OopClosure* f) { 1.320 + 1.321 + f->do_oop((oop*) &_method); 1.322 + for ( int i = 0; i < locals()->length(); i++ ) { 1.323 + if ( locals()->at(i)->type() == T_OBJECT) { 1.324 + f->do_oop(locals()->at(i)->oop_addr()); 1.325 + } 1.326 + } 1.327 +} 1.328 + 1.329 +jvmtiDeferredLocalVariable::jvmtiDeferredLocalVariable(int index, BasicType type, jvalue value) { 1.330 + _index = index; 1.331 + _type = type; 1.332 + _value = value; 1.333 +} 1.334 + 1.335 + 1.336 +#ifndef PRODUCT 1.337 +void compiledVFrame::verify() const { 1.338 + Unimplemented(); 1.339 +} 1.340 +#endif // PRODUCT