1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,912 @@ 1.4 +/* 1.5 + * Copyright 2003-2007 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/_jvmtiImpl.cpp.incl" 1.30 + 1.31 +GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true); 1.32 + 1.33 +void JvmtiPendingMonitors::transition_raw_monitors() { 1.34 + assert((Threads::number_of_threads()==1), 1.35 + "Java thread has not created yet or more than one java thread \ 1.36 +is running. Raw monitor transition will not work"); 1.37 + JavaThread *current_java_thread = JavaThread::current(); 1.38 + assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm"); 1.39 + { 1.40 + ThreadBlockInVM __tbivm(current_java_thread); 1.41 + for(int i=0; i< count(); i++) { 1.42 + JvmtiRawMonitor *rmonitor = monitors()->at(i); 1.43 + int r = rmonitor->raw_enter(current_java_thread); 1.44 + assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked"); 1.45 + } 1.46 + } 1.47 + // pending monitors are converted to real monitor so delete them all. 1.48 + dispose(); 1.49 +} 1.50 + 1.51 +// 1.52 +// class JvmtiAgentThread 1.53 +// 1.54 +// JavaThread used to wrap a thread started by an agent 1.55 +// using the JVMTI method RunAgentThread. 1.56 +// 1.57 + 1.58 +JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg) 1.59 + : JavaThread(start_function_wrapper) { 1.60 + _env = env; 1.61 + _start_fn = start_fn; 1.62 + _start_arg = start_arg; 1.63 +} 1.64 + 1.65 +void 1.66 +JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) { 1.67 + // It is expected that any Agent threads will be created as 1.68 + // Java Threads. If this is the case, notification of the creation 1.69 + // of the thread is given in JavaThread::thread_main(). 1.70 + assert(thread->is_Java_thread(), "debugger thread should be a Java Thread"); 1.71 + assert(thread == JavaThread::current(), "sanity check"); 1.72 + 1.73 + JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread; 1.74 + dthread->call_start_function(); 1.75 +} 1.76 + 1.77 +void 1.78 +JvmtiAgentThread::call_start_function() { 1.79 + ThreadToNativeFromVM transition(this); 1.80 + _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg); 1.81 +} 1.82 + 1.83 + 1.84 +// 1.85 +// class GrowableCache - private methods 1.86 +// 1.87 + 1.88 +void GrowableCache::recache() { 1.89 + int len = _elements->length(); 1.90 + 1.91 + FREE_C_HEAP_ARRAY(address, _cache); 1.92 + _cache = NEW_C_HEAP_ARRAY(address,len+1); 1.93 + 1.94 + for (int i=0; i<len; i++) { 1.95 + _cache[i] = _elements->at(i)->getCacheValue(); 1.96 + // 1.97 + // The cache entry has gone bad. Without a valid frame pointer 1.98 + // value, the entry is useless so we simply delete it in product 1.99 + // mode. The call to remove() will rebuild the cache again 1.100 + // without the bad entry. 1.101 + // 1.102 + if (_cache[i] == NULL) { 1.103 + assert(false, "cannot recache NULL elements"); 1.104 + remove(i); 1.105 + return; 1.106 + } 1.107 + } 1.108 + _cache[len] = NULL; 1.109 + 1.110 + _listener_fun(_this_obj,_cache); 1.111 +} 1.112 + 1.113 +bool GrowableCache::equals(void* v, GrowableElement *e2) { 1.114 + GrowableElement *e1 = (GrowableElement *) v; 1.115 + assert(e1 != NULL, "e1 != NULL"); 1.116 + assert(e2 != NULL, "e2 != NULL"); 1.117 + 1.118 + return e1->equals(e2); 1.119 +} 1.120 + 1.121 +// 1.122 +// class GrowableCache - public methods 1.123 +// 1.124 + 1.125 +GrowableCache::GrowableCache() { 1.126 + _this_obj = NULL; 1.127 + _listener_fun = NULL; 1.128 + _elements = NULL; 1.129 + _cache = NULL; 1.130 +} 1.131 + 1.132 +GrowableCache::~GrowableCache() { 1.133 + clear(); 1.134 + delete _elements; 1.135 + FREE_C_HEAP_ARRAY(address, _cache); 1.136 +} 1.137 + 1.138 +void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) { 1.139 + _this_obj = this_obj; 1.140 + _listener_fun = listener_fun; 1.141 + _elements = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true); 1.142 + recache(); 1.143 +} 1.144 + 1.145 +// number of elements in the collection 1.146 +int GrowableCache::length() { 1.147 + return _elements->length(); 1.148 +} 1.149 + 1.150 +// get the value of the index element in the collection 1.151 +GrowableElement* GrowableCache::at(int index) { 1.152 + GrowableElement *e = (GrowableElement *) _elements->at(index); 1.153 + assert(e != NULL, "e != NULL"); 1.154 + return e; 1.155 +} 1.156 + 1.157 +int GrowableCache::find(GrowableElement* e) { 1.158 + return _elements->find(e, GrowableCache::equals); 1.159 +} 1.160 + 1.161 +// append a copy of the element to the end of the collection 1.162 +void GrowableCache::append(GrowableElement* e) { 1.163 + GrowableElement *new_e = e->clone(); 1.164 + _elements->append(new_e); 1.165 + recache(); 1.166 +} 1.167 + 1.168 +// insert a copy of the element using lessthan() 1.169 +void GrowableCache::insert(GrowableElement* e) { 1.170 + GrowableElement *new_e = e->clone(); 1.171 + _elements->append(new_e); 1.172 + 1.173 + int n = length()-2; 1.174 + for (int i=n; i>=0; i--) { 1.175 + GrowableElement *e1 = _elements->at(i); 1.176 + GrowableElement *e2 = _elements->at(i+1); 1.177 + if (e2->lessThan(e1)) { 1.178 + _elements->at_put(i+1, e1); 1.179 + _elements->at_put(i, e2); 1.180 + } 1.181 + } 1.182 + 1.183 + recache(); 1.184 +} 1.185 + 1.186 +// remove the element at index 1.187 +void GrowableCache::remove (int index) { 1.188 + GrowableElement *e = _elements->at(index); 1.189 + assert(e != NULL, "e != NULL"); 1.190 + _elements->remove(e); 1.191 + delete e; 1.192 + recache(); 1.193 +} 1.194 + 1.195 +// clear out all elements, release all heap space and 1.196 +// let our listener know that things have changed. 1.197 +void GrowableCache::clear() { 1.198 + int len = _elements->length(); 1.199 + for (int i=0; i<len; i++) { 1.200 + delete _elements->at(i); 1.201 + } 1.202 + _elements->clear(); 1.203 + recache(); 1.204 +} 1.205 + 1.206 +void GrowableCache::oops_do(OopClosure* f) { 1.207 + int len = _elements->length(); 1.208 + for (int i=0; i<len; i++) { 1.209 + GrowableElement *e = _elements->at(i); 1.210 + e->oops_do(f); 1.211 + } 1.212 +} 1.213 + 1.214 +void GrowableCache::gc_epilogue() { 1.215 + int len = _elements->length(); 1.216 + // recompute the new cache value after GC 1.217 + for (int i=0; i<len; i++) { 1.218 + _cache[i] = _elements->at(i)->getCacheValue(); 1.219 + } 1.220 +} 1.221 + 1.222 + 1.223 +// 1.224 +// class JvmtiRawMonitor 1.225 +// 1.226 + 1.227 +JvmtiRawMonitor::JvmtiRawMonitor(const char *name) { 1.228 +#ifdef ASSERT 1.229 + _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name); 1.230 +#else 1.231 + _name = NULL; 1.232 +#endif 1.233 + _magic = JVMTI_RM_MAGIC; 1.234 +} 1.235 + 1.236 +JvmtiRawMonitor::~JvmtiRawMonitor() { 1.237 +#ifdef ASSERT 1.238 + FreeHeap(_name); 1.239 +#endif 1.240 + _magic = 0; 1.241 +} 1.242 + 1.243 + 1.244 +// 1.245 +// class JvmtiBreakpoint 1.246 +// 1.247 + 1.248 +JvmtiBreakpoint::JvmtiBreakpoint() { 1.249 + _method = NULL; 1.250 + _bci = 0; 1.251 +#ifdef CHECK_UNHANDLED_OOPS 1.252 + // This one is always allocated with new, but check it just in case. 1.253 + Thread *thread = Thread::current(); 1.254 + if (thread->is_in_stack((address)&_method)) { 1.255 + thread->allow_unhandled_oop((oop*)&_method); 1.256 + } 1.257 +#endif // CHECK_UNHANDLED_OOPS 1.258 +} 1.259 + 1.260 +JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) { 1.261 + _method = m_method; 1.262 + assert(_method != NULL, "_method != NULL"); 1.263 + _bci = (int) location; 1.264 +#ifdef CHECK_UNHANDLED_OOPS 1.265 + // Could be allocated with new and wouldn't be on the unhandled oop list. 1.266 + Thread *thread = Thread::current(); 1.267 + if (thread->is_in_stack((address)&_method)) { 1.268 + thread->allow_unhandled_oop(&_method); 1.269 + } 1.270 +#endif // CHECK_UNHANDLED_OOPS 1.271 + 1.272 + assert(_bci >= 0, "_bci >= 0"); 1.273 +} 1.274 + 1.275 +void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { 1.276 + _method = bp._method; 1.277 + _bci = bp._bci; 1.278 +} 1.279 + 1.280 +bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { 1.281 + Unimplemented(); 1.282 + return false; 1.283 +} 1.284 + 1.285 +bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) { 1.286 + return _method == bp._method 1.287 + && _bci == bp._bci; 1.288 +} 1.289 + 1.290 +bool JvmtiBreakpoint::is_valid() { 1.291 + return _method != NULL && 1.292 + _bci >= 0; 1.293 +} 1.294 + 1.295 +address JvmtiBreakpoint::getBcp() { 1.296 + return _method->bcp_from(_bci); 1.297 +} 1.298 + 1.299 +void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { 1.300 + ((methodOopDesc*)_method->*meth_act)(_bci); 1.301 + 1.302 + // add/remove breakpoint to/from versions of the method that 1.303 + // are EMCP. Directly or transitively obsolete methods are 1.304 + // not saved in the PreviousVersionInfo. 1.305 + Thread *thread = Thread::current(); 1.306 + instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); 1.307 + symbolOop m_name = _method->name(); 1.308 + symbolOop m_signature = _method->signature(); 1.309 + 1.310 + { 1.311 + ResourceMark rm(thread); 1.312 + // PreviousVersionInfo objects returned via PreviousVersionWalker 1.313 + // contain a GrowableArray of handles. We have to clean up the 1.314 + // GrowableArray _after_ the PreviousVersionWalker destructor 1.315 + // has destroyed the handles. 1.316 + { 1.317 + // search previous versions if they exist 1.318 + PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part()); 1.319 + for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); 1.320 + pv_info != NULL; pv_info = pvw.next_previous_version()) { 1.321 + GrowableArray<methodHandle>* methods = 1.322 + pv_info->prev_EMCP_method_handles(); 1.323 + 1.324 + if (methods == NULL) { 1.325 + // We have run into a PreviousVersion generation where 1.326 + // all methods were made obsolete during that generation's 1.327 + // RedefineClasses() operation. At the time of that 1.328 + // operation, all EMCP methods were flushed so we don't 1.329 + // have to go back any further. 1.330 + // 1.331 + // A NULL methods array is different than an empty methods 1.332 + // array. We cannot infer any optimizations about older 1.333 + // generations from an empty methods array for the current 1.334 + // generation. 1.335 + break; 1.336 + } 1.337 + 1.338 + for (int i = methods->length() - 1; i >= 0; i--) { 1.339 + methodHandle method = methods->at(i); 1.340 + if (method->name() == m_name && method->signature() == m_signature) { 1.341 + RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", 1.342 + meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear", 1.343 + method->name()->as_C_string(), 1.344 + method->signature()->as_C_string())); 1.345 + assert(!method->is_obsolete(), "only EMCP methods here"); 1.346 + 1.347 + ((methodOopDesc*)method()->*meth_act)(_bci); 1.348 + break; 1.349 + } 1.350 + } 1.351 + } 1.352 + } // pvw is cleaned up 1.353 + } // rm is cleaned up 1.354 +} 1.355 + 1.356 +void JvmtiBreakpoint::set() { 1.357 + each_method_version_do(&methodOopDesc::set_breakpoint); 1.358 +} 1.359 + 1.360 +void JvmtiBreakpoint::clear() { 1.361 + each_method_version_do(&methodOopDesc::clear_breakpoint); 1.362 +} 1.363 + 1.364 +void JvmtiBreakpoint::print() { 1.365 +#ifndef PRODUCT 1.366 + const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); 1.367 + const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string(); 1.368 + 1.369 + tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp()); 1.370 +#endif 1.371 +} 1.372 + 1.373 + 1.374 +// 1.375 +// class VM_ChangeBreakpoints 1.376 +// 1.377 +// Modify the Breakpoints data structure at a safepoint 1.378 +// 1.379 + 1.380 +void VM_ChangeBreakpoints::doit() { 1.381 + switch (_operation) { 1.382 + case SET_BREAKPOINT: 1.383 + _breakpoints->set_at_safepoint(*_bp); 1.384 + break; 1.385 + case CLEAR_BREAKPOINT: 1.386 + _breakpoints->clear_at_safepoint(*_bp); 1.387 + break; 1.388 + case CLEAR_ALL_BREAKPOINT: 1.389 + _breakpoints->clearall_at_safepoint(); 1.390 + break; 1.391 + default: 1.392 + assert(false, "Unknown operation"); 1.393 + } 1.394 +} 1.395 + 1.396 +void VM_ChangeBreakpoints::oops_do(OopClosure* f) { 1.397 + // This operation keeps breakpoints alive 1.398 + if (_breakpoints != NULL) { 1.399 + _breakpoints->oops_do(f); 1.400 + } 1.401 + if (_bp != NULL) { 1.402 + _bp->oops_do(f); 1.403 + } 1.404 +} 1.405 + 1.406 +// 1.407 +// class JvmtiBreakpoints 1.408 +// 1.409 +// a JVMTI internal collection of JvmtiBreakpoint 1.410 +// 1.411 + 1.412 +JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) { 1.413 + _bps.initialize(this,listener_fun); 1.414 +} 1.415 + 1.416 +JvmtiBreakpoints:: ~JvmtiBreakpoints() {} 1.417 + 1.418 +void JvmtiBreakpoints::oops_do(OopClosure* f) { 1.419 + _bps.oops_do(f); 1.420 +} 1.421 + 1.422 +void JvmtiBreakpoints::gc_epilogue() { 1.423 + _bps.gc_epilogue(); 1.424 +} 1.425 + 1.426 +void JvmtiBreakpoints::print() { 1.427 +#ifndef PRODUCT 1.428 + ResourceMark rm; 1.429 + 1.430 + int n = _bps.length(); 1.431 + for (int i=0; i<n; i++) { 1.432 + JvmtiBreakpoint& bp = _bps.at(i); 1.433 + tty->print("%d: ", i); 1.434 + bp.print(); 1.435 + tty->print_cr(""); 1.436 + } 1.437 +#endif 1.438 +} 1.439 + 1.440 + 1.441 +void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) { 1.442 + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.443 + 1.444 + int i = _bps.find(bp); 1.445 + if (i == -1) { 1.446 + _bps.append(bp); 1.447 + bp.set(); 1.448 + } 1.449 +} 1.450 + 1.451 +void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) { 1.452 + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.453 + 1.454 + int i = _bps.find(bp); 1.455 + if (i != -1) { 1.456 + _bps.remove(i); 1.457 + bp.clear(); 1.458 + } 1.459 +} 1.460 + 1.461 +void JvmtiBreakpoints::clearall_at_safepoint() { 1.462 + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.463 + 1.464 + int len = _bps.length(); 1.465 + for (int i=0; i<len; i++) { 1.466 + _bps.at(i).clear(); 1.467 + } 1.468 + _bps.clear(); 1.469 +} 1.470 + 1.471 +int JvmtiBreakpoints::length() { return _bps.length(); } 1.472 + 1.473 +int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) { 1.474 + if ( _bps.find(bp) != -1) { 1.475 + return JVMTI_ERROR_DUPLICATE; 1.476 + } 1.477 + VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp); 1.478 + VMThread::execute(&set_breakpoint); 1.479 + return JVMTI_ERROR_NONE; 1.480 +} 1.481 + 1.482 +int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) { 1.483 + if ( _bps.find(bp) == -1) { 1.484 + return JVMTI_ERROR_NOT_FOUND; 1.485 + } 1.486 + 1.487 + VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); 1.488 + VMThread::execute(&clear_breakpoint); 1.489 + return JVMTI_ERROR_NONE; 1.490 +} 1.491 + 1.492 +void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) { 1.493 + bool changed = true; 1.494 + // We are going to run thru the list of bkpts 1.495 + // and delete some. This deletion probably alters 1.496 + // the list in some implementation defined way such 1.497 + // that when we delete entry i, the next entry might 1.498 + // no longer be at i+1. To be safe, each time we delete 1.499 + // an entry, we'll just start again from the beginning. 1.500 + // We'll stop when we make a pass thru the whole list without 1.501 + // deleting anything. 1.502 + while (changed) { 1.503 + int len = _bps.length(); 1.504 + changed = false; 1.505 + for (int i = 0; i < len; i++) { 1.506 + JvmtiBreakpoint& bp = _bps.at(i); 1.507 + if (bp.method()->method_holder() == klass) { 1.508 + bp.clear(); 1.509 + _bps.remove(i); 1.510 + // This changed 'i' so we have to start over. 1.511 + changed = true; 1.512 + break; 1.513 + } 1.514 + } 1.515 + } 1.516 +} 1.517 + 1.518 +void JvmtiBreakpoints::clearall() { 1.519 + VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT); 1.520 + VMThread::execute(&clearall_breakpoint); 1.521 +} 1.522 + 1.523 +// 1.524 +// class JvmtiCurrentBreakpoints 1.525 +// 1.526 + 1.527 +JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL; 1.528 +address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL; 1.529 + 1.530 + 1.531 +JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() { 1.532 + if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints); 1.533 + _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun); 1.534 + assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL"); 1.535 + return (*_jvmti_breakpoints); 1.536 +} 1.537 + 1.538 +void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) { 1.539 + JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj; 1.540 + assert(this_jvmti != NULL, "this_jvmti != NULL"); 1.541 + 1.542 + debug_only(int n = this_jvmti->length();); 1.543 + assert(cache[n] == NULL, "cache must be NULL terminated"); 1.544 + 1.545 + set_breakpoint_list(cache); 1.546 +} 1.547 + 1.548 + 1.549 +void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) { 1.550 + if (_jvmti_breakpoints != NULL) { 1.551 + _jvmti_breakpoints->oops_do(f); 1.552 + } 1.553 +} 1.554 + 1.555 +void JvmtiCurrentBreakpoints::gc_epilogue() { 1.556 + if (_jvmti_breakpoints != NULL) { 1.557 + _jvmti_breakpoints->gc_epilogue(); 1.558 + } 1.559 +} 1.560 + 1.561 + 1.562 +/////////////////////////////////////////////////////////////// 1.563 +// 1.564 +// class VM_GetOrSetLocal 1.565 +// 1.566 + 1.567 +// Constructor for non-object getter 1.568 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type) 1.569 + : _thread(thread) 1.570 + , _calling_thread(NULL) 1.571 + , _depth(depth) 1.572 + , _index(index) 1.573 + , _type(type) 1.574 + , _set(false) 1.575 + , _jvf(NULL) 1.576 + , _result(JVMTI_ERROR_NONE) 1.577 +{ 1.578 +} 1.579 + 1.580 +// Constructor for object or non-object setter 1.581 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value) 1.582 + : _thread(thread) 1.583 + , _calling_thread(NULL) 1.584 + , _depth(depth) 1.585 + , _index(index) 1.586 + , _type(type) 1.587 + , _value(value) 1.588 + , _set(true) 1.589 + , _jvf(NULL) 1.590 + , _result(JVMTI_ERROR_NONE) 1.591 +{ 1.592 +} 1.593 + 1.594 +// Constructor for object getter 1.595 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index) 1.596 + : _thread(thread) 1.597 + , _calling_thread(calling_thread) 1.598 + , _depth(depth) 1.599 + , _index(index) 1.600 + , _type(T_OBJECT) 1.601 + , _set(false) 1.602 + , _jvf(NULL) 1.603 + , _result(JVMTI_ERROR_NONE) 1.604 +{ 1.605 +} 1.606 + 1.607 + 1.608 +vframe *VM_GetOrSetLocal::get_vframe() { 1.609 + if (!_thread->has_last_Java_frame()) { 1.610 + return NULL; 1.611 + } 1.612 + RegisterMap reg_map(_thread); 1.613 + vframe *vf = _thread->last_java_vframe(®_map); 1.614 + int d = 0; 1.615 + while ((vf != NULL) && (d < _depth)) { 1.616 + vf = vf->java_sender(); 1.617 + d++; 1.618 + } 1.619 + return vf; 1.620 +} 1.621 + 1.622 +javaVFrame *VM_GetOrSetLocal::get_java_vframe() { 1.623 + vframe* vf = get_vframe(); 1.624 + if (vf == NULL) { 1.625 + _result = JVMTI_ERROR_NO_MORE_FRAMES; 1.626 + return NULL; 1.627 + } 1.628 + javaVFrame *jvf = (javaVFrame*)vf; 1.629 + 1.630 + if (!vf->is_java_frame() || jvf->method()->is_native()) { 1.631 + _result = JVMTI_ERROR_OPAQUE_FRAME; 1.632 + return NULL; 1.633 + } 1.634 + return jvf; 1.635 +} 1.636 + 1.637 +// Check that the klass is assignable to a type with the given signature. 1.638 +// Another solution could be to use the function Klass::is_subtype_of(type). 1.639 +// But the type class can be forced to load/initialize eagerly in such a case. 1.640 +// This may cause unexpected consequences like CFLH or class-init JVMTI events. 1.641 +// It is better to avoid such a behavior. 1.642 +bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { 1.643 + assert(ty_sign != NULL, "type signature must not be NULL"); 1.644 + assert(thread != NULL, "thread must not be NULL"); 1.645 + assert(klass != NULL, "klass must not be NULL"); 1.646 + 1.647 + int len = (int) strlen(ty_sign); 1.648 + if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name 1.649 + ty_sign++; 1.650 + len -= 2; 1.651 + } 1.652 + symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread); 1.653 + if (klass->name() == ty_sym()) { 1.654 + return true; 1.655 + } 1.656 + // Compare primary supers 1.657 + int super_depth = klass->super_depth(); 1.658 + int idx; 1.659 + for (idx = 0; idx < super_depth; idx++) { 1.660 + if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) { 1.661 + return true; 1.662 + } 1.663 + } 1.664 + // Compare secondary supers 1.665 + objArrayOop sec_supers = klass->secondary_supers(); 1.666 + for (idx = 0; idx < sec_supers->length(); idx++) { 1.667 + if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) { 1.668 + return true; 1.669 + } 1.670 + } 1.671 + return false; 1.672 +} 1.673 + 1.674 +// Checks error conditions: 1.675 +// JVMTI_ERROR_INVALID_SLOT 1.676 +// JVMTI_ERROR_TYPE_MISMATCH 1.677 +// Returns: 'true' - everything is Ok, 'false' - error code 1.678 + 1.679 +bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) { 1.680 + methodOop method_oop = jvf->method(); 1.681 + if (!method_oop->has_localvariable_table()) { 1.682 + // Just to check index boundaries 1.683 + jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; 1.684 + if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { 1.685 + _result = JVMTI_ERROR_INVALID_SLOT; 1.686 + return false; 1.687 + } 1.688 + return true; 1.689 + } 1.690 + 1.691 + jint num_entries = method_oop->localvariable_table_length(); 1.692 + if (num_entries == 0) { 1.693 + _result = JVMTI_ERROR_INVALID_SLOT; 1.694 + return false; // There are no slots 1.695 + } 1.696 + int signature_idx = -1; 1.697 + int vf_bci = jvf->bci(); 1.698 + LocalVariableTableElement* table = method_oop->localvariable_table_start(); 1.699 + for (int i = 0; i < num_entries; i++) { 1.700 + int start_bci = table[i].start_bci; 1.701 + int end_bci = start_bci + table[i].length; 1.702 + 1.703 + // Here we assume that locations of LVT entries 1.704 + // with the same slot number cannot be overlapped 1.705 + if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) { 1.706 + signature_idx = (int) table[i].descriptor_cp_index; 1.707 + break; 1.708 + } 1.709 + } 1.710 + if (signature_idx == -1) { 1.711 + _result = JVMTI_ERROR_INVALID_SLOT; 1.712 + return false; // Incorrect slot index 1.713 + } 1.714 + symbolOop sign_sym = method_oop->constants()->symbol_at(signature_idx); 1.715 + const char* signature = (const char *) sign_sym->as_utf8(); 1.716 + BasicType slot_type = char2type(signature[0]); 1.717 + 1.718 + switch (slot_type) { 1.719 + case T_BYTE: 1.720 + case T_SHORT: 1.721 + case T_CHAR: 1.722 + case T_BOOLEAN: 1.723 + slot_type = T_INT; 1.724 + break; 1.725 + case T_ARRAY: 1.726 + slot_type = T_OBJECT; 1.727 + break; 1.728 + }; 1.729 + if (_type != slot_type) { 1.730 + _result = JVMTI_ERROR_TYPE_MISMATCH; 1.731 + return false; 1.732 + } 1.733 + 1.734 + jobject jobj = _value.l; 1.735 + if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed 1.736 + // Check that the jobject class matches the return type signature. 1.737 + JavaThread* cur_thread = JavaThread::current(); 1.738 + HandleMark hm(cur_thread); 1.739 + 1.740 + Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj)); 1.741 + NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); 1.742 + KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass()); 1.743 + NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); 1.744 + 1.745 + if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) { 1.746 + _result = JVMTI_ERROR_TYPE_MISMATCH; 1.747 + return false; 1.748 + } 1.749 + } 1.750 + return true; 1.751 +} 1.752 + 1.753 +static bool can_be_deoptimized(vframe* vf) { 1.754 + return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); 1.755 +} 1.756 + 1.757 +bool VM_GetOrSetLocal::doit_prologue() { 1.758 + _jvf = get_java_vframe(); 1.759 + NULL_CHECK(_jvf, false); 1.760 + 1.761 + if (!check_slot_type(_jvf)) { 1.762 + return false; 1.763 + } 1.764 + return true; 1.765 +} 1.766 + 1.767 +void VM_GetOrSetLocal::doit() { 1.768 + if (_set) { 1.769 + // Force deoptimization of frame if compiled because it's 1.770 + // possible the compiler emitted some locals as constant values, 1.771 + // meaning they are not mutable. 1.772 + if (can_be_deoptimized(_jvf)) { 1.773 + 1.774 + // Schedule deoptimization so that eventually the local 1.775 + // update will be written to an interpreter frame. 1.776 + VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id()); 1.777 + VMThread::execute(&deopt); 1.778 + 1.779 + // Now store a new value for the local which will be applied 1.780 + // once deoptimization occurs. Note however that while this 1.781 + // write is deferred until deoptimization actually happens 1.782 + // can vframe created after this point will have its locals 1.783 + // reflecting this update so as far as anyone can see the 1.784 + // write has already taken place. 1.785 + 1.786 + // If we are updating an oop then get the oop from the handle 1.787 + // since the handle will be long gone by the time the deopt 1.788 + // happens. The oop stored in the deferred local will be 1.789 + // gc'd on its own. 1.790 + if (_type == T_OBJECT) { 1.791 + _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l)); 1.792 + } 1.793 + // Re-read the vframe so we can see that it is deoptimized 1.794 + // [ Only need because of assert in update_local() ] 1.795 + _jvf = get_java_vframe(); 1.796 + ((compiledVFrame*)_jvf)->update_local(_type, _index, _value); 1.797 + return; 1.798 + } 1.799 + StackValueCollection *locals = _jvf->locals(); 1.800 + HandleMark hm; 1.801 + 1.802 + switch (_type) { 1.803 + case T_INT: locals->set_int_at (_index, _value.i); break; 1.804 + case T_LONG: locals->set_long_at (_index, _value.j); break; 1.805 + case T_FLOAT: locals->set_float_at (_index, _value.f); break; 1.806 + case T_DOUBLE: locals->set_double_at(_index, _value.d); break; 1.807 + case T_OBJECT: { 1.808 + Handle ob_h(JNIHandles::resolve_external_guard(_value.l)); 1.809 + locals->set_obj_at (_index, ob_h); 1.810 + break; 1.811 + } 1.812 + default: ShouldNotReachHere(); 1.813 + } 1.814 + _jvf->set_locals(locals); 1.815 + } else { 1.816 + StackValueCollection *locals = _jvf->locals(); 1.817 + 1.818 + if (locals->at(_index)->type() == T_CONFLICT) { 1.819 + memset(&_value, 0, sizeof(_value)); 1.820 + _value.l = NULL; 1.821 + return; 1.822 + } 1.823 + 1.824 + switch (_type) { 1.825 + case T_INT: _value.i = locals->int_at (_index); break; 1.826 + case T_LONG: _value.j = locals->long_at (_index); break; 1.827 + case T_FLOAT: _value.f = locals->float_at (_index); break; 1.828 + case T_DOUBLE: _value.d = locals->double_at(_index); break; 1.829 + case T_OBJECT: { 1.830 + // Wrap the oop to be returned in a local JNI handle since 1.831 + // oops_do() no longer applies after doit() is finished. 1.832 + oop obj = locals->obj_at(_index)(); 1.833 + _value.l = JNIHandles::make_local(_calling_thread, obj); 1.834 + break; 1.835 + } 1.836 + default: ShouldNotReachHere(); 1.837 + } 1.838 + } 1.839 +} 1.840 + 1.841 + 1.842 +bool VM_GetOrSetLocal::allow_nested_vm_operations() const { 1.843 + return true; // May need to deoptimize 1.844 +} 1.845 + 1.846 + 1.847 +///////////////////////////////////////////////////////////////////////////////////////// 1.848 + 1.849 +// 1.850 +// class JvmtiSuspendControl - see comments in jvmtiImpl.hpp 1.851 +// 1.852 + 1.853 +bool JvmtiSuspendControl::suspend(JavaThread *java_thread) { 1.854 + // external suspend should have caught suspending a thread twice 1.855 + 1.856 + // Immediate suspension required for JPDA back-end so JVMTI agent threads do 1.857 + // not deadlock due to later suspension on transitions while holding 1.858 + // raw monitors. Passing true causes the immediate suspension. 1.859 + // java_suspend() will catch threads in the process of exiting 1.860 + // and will ignore them. 1.861 + java_thread->java_suspend(); 1.862 + 1.863 + // It would be nice to have the following assertion in all the time, 1.864 + // but it is possible for a racing resume request to have resumed 1.865 + // this thread right after we suspended it. Temporarily enable this 1.866 + // assertion if you are chasing a different kind of bug. 1.867 + // 1.868 + // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL || 1.869 + // java_thread->is_being_ext_suspended(), "thread is not suspended"); 1.870 + 1.871 + if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) { 1.872 + // check again because we can get delayed in java_suspend(): 1.873 + // the thread is in process of exiting. 1.874 + return false; 1.875 + } 1.876 + 1.877 + return true; 1.878 +} 1.879 + 1.880 +bool JvmtiSuspendControl::resume(JavaThread *java_thread) { 1.881 + // external suspend should have caught resuming a thread twice 1.882 + assert(java_thread->is_being_ext_suspended(), "thread should be suspended"); 1.883 + 1.884 + // resume thread 1.885 + { 1.886 + // must always grab Threads_lock, see JVM_SuspendThread 1.887 + MutexLocker ml(Threads_lock); 1.888 + java_thread->java_resume(); 1.889 + } 1.890 + 1.891 + return true; 1.892 +} 1.893 + 1.894 + 1.895 +void JvmtiSuspendControl::print() { 1.896 +#ifndef PRODUCT 1.897 + MutexLocker mu(Threads_lock); 1.898 + ResourceMark rm; 1.899 + 1.900 + tty->print("Suspended Threads: ["); 1.901 + for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) { 1.902 +#if JVMTI_TRACE 1.903 + const char *name = JvmtiTrace::safe_get_thread_name(thread); 1.904 +#else 1.905 + const char *name = ""; 1.906 +#endif /*JVMTI_TRACE */ 1.907 + tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_'); 1.908 + if (!thread->has_last_Java_frame()) { 1.909 + tty->print("no stack"); 1.910 + } 1.911 + tty->print(") "); 1.912 + } 1.913 + tty->print_cr("]"); 1.914 +#endif 1.915 +}