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