| 1 | /* |
| 2 | * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 12 | * version 2 for more details (a copy is included in the LICENSE file that |
| 13 | * accompanied this code). |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License version |
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 20 | * or visit www.oracle.com if you need additional information or have any |
| 21 | * questions. |
| 22 | * |
| 23 | */ |
| 24 | |
| 25 | #include "precompiled.hpp" |
| 26 | #include "classfile/symbolTable.hpp" |
| 27 | #include "classfile/systemDictionary.hpp" |
| 28 | #include "interpreter/interpreter.hpp" |
| 29 | #include "interpreter/oopMapCache.hpp" |
| 30 | #include "jvmtifiles/jvmtiEnv.hpp" |
| 31 | #include "logging/log.hpp" |
| 32 | #include "logging/logStream.hpp" |
| 33 | #include "memory/allocation.inline.hpp" |
| 34 | #include "memory/resourceArea.hpp" |
| 35 | #include "oops/instanceKlass.hpp" |
| 36 | #include "oops/oop.inline.hpp" |
| 37 | #include "prims/jvmtiAgentThread.hpp" |
| 38 | #include "prims/jvmtiEventController.inline.hpp" |
| 39 | #include "prims/jvmtiImpl.hpp" |
| 40 | #include "prims/jvmtiRedefineClasses.hpp" |
| 41 | #include "runtime/atomic.hpp" |
| 42 | #include "runtime/deoptimization.hpp" |
| 43 | #include "runtime/frame.inline.hpp" |
| 44 | #include "runtime/handles.inline.hpp" |
| 45 | #include "runtime/interfaceSupport.inline.hpp" |
| 46 | #include "runtime/javaCalls.hpp" |
| 47 | #include "runtime/os.hpp" |
| 48 | #include "runtime/serviceThread.hpp" |
| 49 | #include "runtime/signature.hpp" |
| 50 | #include "runtime/thread.inline.hpp" |
| 51 | #include "runtime/threadSMR.hpp" |
| 52 | #include "runtime/vframe.hpp" |
| 53 | #include "runtime/vframe_hp.hpp" |
| 54 | #include "runtime/vmOperations.hpp" |
| 55 | #include "utilities/exceptions.hpp" |
| 56 | |
| 57 | // |
| 58 | // class JvmtiAgentThread |
| 59 | // |
| 60 | // JavaThread used to wrap a thread started by an agent |
| 61 | // using the JVMTI method RunAgentThread. |
| 62 | // |
| 63 | |
| 64 | JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg) |
| 65 | : JavaThread(start_function_wrapper) { |
| 66 | _env = env; |
| 67 | _start_fn = start_fn; |
| 68 | _start_arg = start_arg; |
| 69 | } |
| 70 | |
| 71 | void |
| 72 | JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) { |
| 73 | // It is expected that any Agent threads will be created as |
| 74 | // Java Threads. If this is the case, notification of the creation |
| 75 | // of the thread is given in JavaThread::thread_main(). |
| 76 | assert(thread->is_Java_thread(), "debugger thread should be a Java Thread" ); |
| 77 | assert(thread == JavaThread::current(), "sanity check" ); |
| 78 | |
| 79 | JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread; |
| 80 | dthread->call_start_function(); |
| 81 | } |
| 82 | |
| 83 | void |
| 84 | JvmtiAgentThread::call_start_function() { |
| 85 | ThreadToNativeFromVM transition(this); |
| 86 | _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg); |
| 87 | } |
| 88 | |
| 89 | |
| 90 | // |
| 91 | // class GrowableCache - private methods |
| 92 | // |
| 93 | |
| 94 | void GrowableCache::recache() { |
| 95 | int len = _elements->length(); |
| 96 | |
| 97 | FREE_C_HEAP_ARRAY(address, _cache); |
| 98 | _cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal); |
| 99 | |
| 100 | for (int i=0; i<len; i++) { |
| 101 | _cache[i] = _elements->at(i)->getCacheValue(); |
| 102 | // |
| 103 | // The cache entry has gone bad. Without a valid frame pointer |
| 104 | // value, the entry is useless so we simply delete it in product |
| 105 | // mode. The call to remove() will rebuild the cache again |
| 106 | // without the bad entry. |
| 107 | // |
| 108 | if (_cache[i] == NULL) { |
| 109 | assert(false, "cannot recache NULL elements" ); |
| 110 | remove(i); |
| 111 | return; |
| 112 | } |
| 113 | } |
| 114 | _cache[len] = NULL; |
| 115 | |
| 116 | _listener_fun(_this_obj,_cache); |
| 117 | } |
| 118 | |
| 119 | bool GrowableCache::equals(void* v, GrowableElement *e2) { |
| 120 | GrowableElement *e1 = (GrowableElement *) v; |
| 121 | assert(e1 != NULL, "e1 != NULL" ); |
| 122 | assert(e2 != NULL, "e2 != NULL" ); |
| 123 | |
| 124 | return e1->equals(e2); |
| 125 | } |
| 126 | |
| 127 | // |
| 128 | // class GrowableCache - public methods |
| 129 | // |
| 130 | |
| 131 | GrowableCache::GrowableCache() { |
| 132 | _this_obj = NULL; |
| 133 | _listener_fun = NULL; |
| 134 | _elements = NULL; |
| 135 | _cache = NULL; |
| 136 | } |
| 137 | |
| 138 | GrowableCache::~GrowableCache() { |
| 139 | clear(); |
| 140 | delete _elements; |
| 141 | FREE_C_HEAP_ARRAY(address, _cache); |
| 142 | } |
| 143 | |
| 144 | void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) { |
| 145 | _this_obj = this_obj; |
| 146 | _listener_fun = listener_fun; |
| 147 | _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<GrowableElement*>(5,true); |
| 148 | recache(); |
| 149 | } |
| 150 | |
| 151 | // number of elements in the collection |
| 152 | int GrowableCache::length() { |
| 153 | return _elements->length(); |
| 154 | } |
| 155 | |
| 156 | // get the value of the index element in the collection |
| 157 | GrowableElement* GrowableCache::at(int index) { |
| 158 | GrowableElement *e = (GrowableElement *) _elements->at(index); |
| 159 | assert(e != NULL, "e != NULL" ); |
| 160 | return e; |
| 161 | } |
| 162 | |
| 163 | int GrowableCache::find(GrowableElement* e) { |
| 164 | return _elements->find(e, GrowableCache::equals); |
| 165 | } |
| 166 | |
| 167 | // append a copy of the element to the end of the collection |
| 168 | void GrowableCache::append(GrowableElement* e) { |
| 169 | GrowableElement *new_e = e->clone(); |
| 170 | _elements->append(new_e); |
| 171 | recache(); |
| 172 | } |
| 173 | |
| 174 | // insert a copy of the element using lessthan() |
| 175 | void GrowableCache::insert(GrowableElement* e) { |
| 176 | GrowableElement *new_e = e->clone(); |
| 177 | _elements->append(new_e); |
| 178 | |
| 179 | int n = length()-2; |
| 180 | for (int i=n; i>=0; i--) { |
| 181 | GrowableElement *e1 = _elements->at(i); |
| 182 | GrowableElement *e2 = _elements->at(i+1); |
| 183 | if (e2->lessThan(e1)) { |
| 184 | _elements->at_put(i+1, e1); |
| 185 | _elements->at_put(i, e2); |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | recache(); |
| 190 | } |
| 191 | |
| 192 | // remove the element at index |
| 193 | void GrowableCache::remove (int index) { |
| 194 | GrowableElement *e = _elements->at(index); |
| 195 | assert(e != NULL, "e != NULL" ); |
| 196 | _elements->remove(e); |
| 197 | delete e; |
| 198 | recache(); |
| 199 | } |
| 200 | |
| 201 | // clear out all elements, release all heap space and |
| 202 | // let our listener know that things have changed. |
| 203 | void GrowableCache::clear() { |
| 204 | int len = _elements->length(); |
| 205 | for (int i=0; i<len; i++) { |
| 206 | delete _elements->at(i); |
| 207 | } |
| 208 | _elements->clear(); |
| 209 | recache(); |
| 210 | } |
| 211 | |
| 212 | void GrowableCache::oops_do(OopClosure* f) { |
| 213 | int len = _elements->length(); |
| 214 | for (int i=0; i<len; i++) { |
| 215 | GrowableElement *e = _elements->at(i); |
| 216 | e->oops_do(f); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | void GrowableCache::metadata_do(void f(Metadata*)) { |
| 221 | int len = _elements->length(); |
| 222 | for (int i=0; i<len; i++) { |
| 223 | GrowableElement *e = _elements->at(i); |
| 224 | e->metadata_do(f); |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | void GrowableCache::gc_epilogue() { |
| 229 | int len = _elements->length(); |
| 230 | for (int i=0; i<len; i++) { |
| 231 | _cache[i] = _elements->at(i)->getCacheValue(); |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | // |
| 236 | // class JvmtiBreakpoint |
| 237 | // |
| 238 | |
| 239 | JvmtiBreakpoint::JvmtiBreakpoint() { |
| 240 | _method = NULL; |
| 241 | _bci = 0; |
| 242 | _class_holder = NULL; |
| 243 | } |
| 244 | |
| 245 | JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) { |
| 246 | _method = m_method; |
| 247 | _class_holder = _method->method_holder()->klass_holder(); |
| 248 | #ifdef CHECK_UNHANDLED_OOPS |
| 249 | // _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are |
| 250 | // sometimes allocated on the heap. |
| 251 | // |
| 252 | // The code handling JvmtiBreakpoints allocated on the stack can't be |
| 253 | // interrupted by a GC until _class_holder is reachable by the GC via the |
| 254 | // oops_do method. |
| 255 | Thread::current()->allow_unhandled_oop(&_class_holder); |
| 256 | #endif // CHECK_UNHANDLED_OOPS |
| 257 | assert(_method != NULL, "_method != NULL" ); |
| 258 | _bci = (int) location; |
| 259 | assert(_bci >= 0, "_bci >= 0" ); |
| 260 | } |
| 261 | |
| 262 | void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { |
| 263 | _method = bp._method; |
| 264 | _bci = bp._bci; |
| 265 | _class_holder = bp._class_holder; |
| 266 | } |
| 267 | |
| 268 | bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { |
| 269 | Unimplemented(); |
| 270 | return false; |
| 271 | } |
| 272 | |
| 273 | bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) { |
| 274 | return _method == bp._method |
| 275 | && _bci == bp._bci; |
| 276 | } |
| 277 | |
| 278 | bool JvmtiBreakpoint::is_valid() { |
| 279 | // class loader can be NULL |
| 280 | return _method != NULL && |
| 281 | _bci >= 0; |
| 282 | } |
| 283 | |
| 284 | address JvmtiBreakpoint::getBcp() const { |
| 285 | return _method->bcp_from(_bci); |
| 286 | } |
| 287 | |
| 288 | void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { |
| 289 | ((Method*)_method->*meth_act)(_bci); |
| 290 | |
| 291 | // add/remove breakpoint to/from versions of the method that are EMCP. |
| 292 | Thread *thread = Thread::current(); |
| 293 | InstanceKlass* ik = _method->method_holder(); |
| 294 | Symbol* m_name = _method->name(); |
| 295 | Symbol* m_signature = _method->signature(); |
| 296 | |
| 297 | // search previous versions if they exist |
| 298 | for (InstanceKlass* pv_node = ik->previous_versions(); |
| 299 | pv_node != NULL; |
| 300 | pv_node = pv_node->previous_versions()) { |
| 301 | Array<Method*>* methods = pv_node->methods(); |
| 302 | |
| 303 | for (int i = methods->length() - 1; i >= 0; i--) { |
| 304 | Method* method = methods->at(i); |
| 305 | // Only set breakpoints in running EMCP methods. |
| 306 | if (method->is_running_emcp() && |
| 307 | method->name() == m_name && |
| 308 | method->signature() == m_signature) { |
| 309 | ResourceMark rm; |
| 310 | log_debug(redefine, class, breakpoint) |
| 311 | ("%sing breakpoint in %s(%s)" , meth_act == &Method::set_breakpoint ? "sett" : "clear" , |
| 312 | method->name()->as_C_string(), method->signature()->as_C_string()); |
| 313 | (method->*meth_act)(_bci); |
| 314 | break; |
| 315 | } |
| 316 | } |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | void JvmtiBreakpoint::set() { |
| 321 | each_method_version_do(&Method::set_breakpoint); |
| 322 | } |
| 323 | |
| 324 | void JvmtiBreakpoint::clear() { |
| 325 | each_method_version_do(&Method::clear_breakpoint); |
| 326 | } |
| 327 | |
| 328 | void JvmtiBreakpoint::print_on(outputStream* out) const { |
| 329 | #ifndef PRODUCT |
| 330 | ResourceMark rm; |
| 331 | const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); |
| 332 | const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string(); |
| 333 | out->print("Breakpoint(%s,%s,%d,%p)" , class_name, method_name, _bci, getBcp()); |
| 334 | #endif |
| 335 | } |
| 336 | |
| 337 | |
| 338 | // |
| 339 | // class VM_ChangeBreakpoints |
| 340 | // |
| 341 | // Modify the Breakpoints data structure at a safepoint |
| 342 | // |
| 343 | |
| 344 | void VM_ChangeBreakpoints::doit() { |
| 345 | switch (_operation) { |
| 346 | case SET_BREAKPOINT: |
| 347 | _breakpoints->set_at_safepoint(*_bp); |
| 348 | break; |
| 349 | case CLEAR_BREAKPOINT: |
| 350 | _breakpoints->clear_at_safepoint(*_bp); |
| 351 | break; |
| 352 | default: |
| 353 | assert(false, "Unknown operation" ); |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | void VM_ChangeBreakpoints::oops_do(OopClosure* f) { |
| 358 | // The JvmtiBreakpoints in _breakpoints will be visited via |
| 359 | // JvmtiExport::oops_do. |
| 360 | if (_bp != NULL) { |
| 361 | _bp->oops_do(f); |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) { |
| 366 | // Walk metadata in breakpoints to keep from being deallocated with RedefineClasses |
| 367 | if (_bp != NULL) { |
| 368 | _bp->metadata_do(f); |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | // |
| 373 | // class JvmtiBreakpoints |
| 374 | // |
| 375 | // a JVMTI internal collection of JvmtiBreakpoint |
| 376 | // |
| 377 | |
| 378 | JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) { |
| 379 | _bps.initialize(this,listener_fun); |
| 380 | } |
| 381 | |
| 382 | JvmtiBreakpoints:: ~JvmtiBreakpoints() {} |
| 383 | |
| 384 | void JvmtiBreakpoints::oops_do(OopClosure* f) { |
| 385 | _bps.oops_do(f); |
| 386 | } |
| 387 | |
| 388 | void JvmtiBreakpoints::metadata_do(void f(Metadata*)) { |
| 389 | _bps.metadata_do(f); |
| 390 | } |
| 391 | |
| 392 | void JvmtiBreakpoints::gc_epilogue() { |
| 393 | _bps.gc_epilogue(); |
| 394 | } |
| 395 | |
| 396 | void JvmtiBreakpoints::print() { |
| 397 | #ifndef PRODUCT |
| 398 | LogTarget(Trace, jvmti) log; |
| 399 | LogStream log_stream(log); |
| 400 | |
| 401 | int n = _bps.length(); |
| 402 | for (int i=0; i<n; i++) { |
| 403 | JvmtiBreakpoint& bp = _bps.at(i); |
| 404 | log_stream.print("%d: " , i); |
| 405 | bp.print_on(&log_stream); |
| 406 | log_stream.cr(); |
| 407 | } |
| 408 | #endif |
| 409 | } |
| 410 | |
| 411 | |
| 412 | void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) { |
| 413 | assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint" ); |
| 414 | |
| 415 | int i = _bps.find(bp); |
| 416 | if (i == -1) { |
| 417 | _bps.append(bp); |
| 418 | bp.set(); |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) { |
| 423 | assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint" ); |
| 424 | |
| 425 | int i = _bps.find(bp); |
| 426 | if (i != -1) { |
| 427 | _bps.remove(i); |
| 428 | bp.clear(); |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | int JvmtiBreakpoints::length() { return _bps.length(); } |
| 433 | |
| 434 | int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) { |
| 435 | if ( _bps.find(bp) != -1) { |
| 436 | return JVMTI_ERROR_DUPLICATE; |
| 437 | } |
| 438 | VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, &bp); |
| 439 | VMThread::execute(&set_breakpoint); |
| 440 | return JVMTI_ERROR_NONE; |
| 441 | } |
| 442 | |
| 443 | int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) { |
| 444 | if ( _bps.find(bp) == -1) { |
| 445 | return JVMTI_ERROR_NOT_FOUND; |
| 446 | } |
| 447 | |
| 448 | VM_ChangeBreakpoints clear_breakpoint(VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); |
| 449 | VMThread::execute(&clear_breakpoint); |
| 450 | return JVMTI_ERROR_NONE; |
| 451 | } |
| 452 | |
| 453 | void JvmtiBreakpoints::clearall_in_class_at_safepoint(Klass* klass) { |
| 454 | bool changed = true; |
| 455 | // We are going to run thru the list of bkpts |
| 456 | // and delete some. This deletion probably alters |
| 457 | // the list in some implementation defined way such |
| 458 | // that when we delete entry i, the next entry might |
| 459 | // no longer be at i+1. To be safe, each time we delete |
| 460 | // an entry, we'll just start again from the beginning. |
| 461 | // We'll stop when we make a pass thru the whole list without |
| 462 | // deleting anything. |
| 463 | while (changed) { |
| 464 | int len = _bps.length(); |
| 465 | changed = false; |
| 466 | for (int i = 0; i < len; i++) { |
| 467 | JvmtiBreakpoint& bp = _bps.at(i); |
| 468 | if (bp.method()->method_holder() == klass) { |
| 469 | bp.clear(); |
| 470 | _bps.remove(i); |
| 471 | // This changed 'i' so we have to start over. |
| 472 | changed = true; |
| 473 | break; |
| 474 | } |
| 475 | } |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | // |
| 480 | // class JvmtiCurrentBreakpoints |
| 481 | // |
| 482 | |
| 483 | JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL; |
| 484 | address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL; |
| 485 | |
| 486 | |
| 487 | JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() { |
| 488 | if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints); |
| 489 | _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun); |
| 490 | assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL" ); |
| 491 | return (*_jvmti_breakpoints); |
| 492 | } |
| 493 | |
| 494 | void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) { |
| 495 | JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj; |
| 496 | assert(this_jvmti != NULL, "this_jvmti != NULL" ); |
| 497 | |
| 498 | debug_only(int n = this_jvmti->length();); |
| 499 | assert(cache[n] == NULL, "cache must be NULL terminated" ); |
| 500 | |
| 501 | set_breakpoint_list(cache); |
| 502 | } |
| 503 | |
| 504 | |
| 505 | void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) { |
| 506 | if (_jvmti_breakpoints != NULL) { |
| 507 | _jvmti_breakpoints->oops_do(f); |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) { |
| 512 | if (_jvmti_breakpoints != NULL) { |
| 513 | _jvmti_breakpoints->metadata_do(f); |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | void JvmtiCurrentBreakpoints::gc_epilogue() { |
| 518 | if (_jvmti_breakpoints != NULL) { |
| 519 | _jvmti_breakpoints->gc_epilogue(); |
| 520 | } |
| 521 | } |
| 522 | |
| 523 | /////////////////////////////////////////////////////////////// |
| 524 | // |
| 525 | // class VM_GetOrSetLocal |
| 526 | // |
| 527 | |
| 528 | // Constructor for non-object getter |
| 529 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type) |
| 530 | : _thread(thread) |
| 531 | , _calling_thread(NULL) |
| 532 | , _depth(depth) |
| 533 | , _index(index) |
| 534 | , _type(type) |
| 535 | , _jvf(NULL) |
| 536 | , _set(false) |
| 537 | , _result(JVMTI_ERROR_NONE) |
| 538 | { |
| 539 | } |
| 540 | |
| 541 | // Constructor for object or non-object setter |
| 542 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value) |
| 543 | : _thread(thread) |
| 544 | , _calling_thread(NULL) |
| 545 | , _depth(depth) |
| 546 | , _index(index) |
| 547 | , _type(type) |
| 548 | , _value(value) |
| 549 | , _jvf(NULL) |
| 550 | , _set(true) |
| 551 | , _result(JVMTI_ERROR_NONE) |
| 552 | { |
| 553 | } |
| 554 | |
| 555 | // Constructor for object getter |
| 556 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index) |
| 557 | : _thread(thread) |
| 558 | , _calling_thread(calling_thread) |
| 559 | , _depth(depth) |
| 560 | , _index(index) |
| 561 | , _type(T_OBJECT) |
| 562 | , _jvf(NULL) |
| 563 | , _set(false) |
| 564 | , _result(JVMTI_ERROR_NONE) |
| 565 | { |
| 566 | } |
| 567 | |
| 568 | vframe *VM_GetOrSetLocal::get_vframe() { |
| 569 | if (!_thread->has_last_Java_frame()) { |
| 570 | return NULL; |
| 571 | } |
| 572 | RegisterMap reg_map(_thread); |
| 573 | vframe *vf = _thread->last_java_vframe(®_map); |
| 574 | int d = 0; |
| 575 | while ((vf != NULL) && (d < _depth)) { |
| 576 | vf = vf->java_sender(); |
| 577 | d++; |
| 578 | } |
| 579 | return vf; |
| 580 | } |
| 581 | |
| 582 | javaVFrame *VM_GetOrSetLocal::get_java_vframe() { |
| 583 | vframe* vf = get_vframe(); |
| 584 | if (vf == NULL) { |
| 585 | _result = JVMTI_ERROR_NO_MORE_FRAMES; |
| 586 | return NULL; |
| 587 | } |
| 588 | javaVFrame *jvf = (javaVFrame*)vf; |
| 589 | |
| 590 | if (!vf->is_java_frame()) { |
| 591 | _result = JVMTI_ERROR_OPAQUE_FRAME; |
| 592 | return NULL; |
| 593 | } |
| 594 | return jvf; |
| 595 | } |
| 596 | |
| 597 | // Check that the klass is assignable to a type with the given signature. |
| 598 | // Another solution could be to use the function Klass::is_subtype_of(type). |
| 599 | // But the type class can be forced to load/initialize eagerly in such a case. |
| 600 | // This may cause unexpected consequences like CFLH or class-init JVMTI events. |
| 601 | // It is better to avoid such a behavior. |
| 602 | bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { |
| 603 | assert(ty_sign != NULL, "type signature must not be NULL" ); |
| 604 | assert(thread != NULL, "thread must not be NULL" ); |
| 605 | assert(klass != NULL, "klass must not be NULL" ); |
| 606 | |
| 607 | int len = (int) strlen(ty_sign); |
| 608 | if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name |
| 609 | ty_sign++; |
| 610 | len -= 2; |
| 611 | } |
| 612 | TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len); |
| 613 | if (klass->name() == ty_sym) { |
| 614 | return true; |
| 615 | } |
| 616 | // Compare primary supers |
| 617 | int super_depth = klass->super_depth(); |
| 618 | int idx; |
| 619 | for (idx = 0; idx < super_depth; idx++) { |
| 620 | if (klass->primary_super_of_depth(idx)->name() == ty_sym) { |
| 621 | return true; |
| 622 | } |
| 623 | } |
| 624 | // Compare secondary supers |
| 625 | const Array<Klass*>* sec_supers = klass->secondary_supers(); |
| 626 | for (idx = 0; idx < sec_supers->length(); idx++) { |
| 627 | if (((Klass*) sec_supers->at(idx))->name() == ty_sym) { |
| 628 | return true; |
| 629 | } |
| 630 | } |
| 631 | return false; |
| 632 | } |
| 633 | |
| 634 | // Checks error conditions: |
| 635 | // JVMTI_ERROR_INVALID_SLOT |
| 636 | // JVMTI_ERROR_TYPE_MISMATCH |
| 637 | // Returns: 'true' - everything is Ok, 'false' - error code |
| 638 | |
| 639 | bool VM_GetOrSetLocal::check_slot_type_lvt(javaVFrame* jvf) { |
| 640 | Method* method_oop = jvf->method(); |
| 641 | jint num_entries = method_oop->localvariable_table_length(); |
| 642 | if (num_entries == 0) { |
| 643 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 644 | return false; // There are no slots |
| 645 | } |
| 646 | int signature_idx = -1; |
| 647 | int vf_bci = jvf->bci(); |
| 648 | LocalVariableTableElement* table = method_oop->localvariable_table_start(); |
| 649 | for (int i = 0; i < num_entries; i++) { |
| 650 | int start_bci = table[i].start_bci; |
| 651 | int end_bci = start_bci + table[i].length; |
| 652 | |
| 653 | // Here we assume that locations of LVT entries |
| 654 | // with the same slot number cannot be overlapped |
| 655 | if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) { |
| 656 | signature_idx = (int) table[i].descriptor_cp_index; |
| 657 | break; |
| 658 | } |
| 659 | } |
| 660 | if (signature_idx == -1) { |
| 661 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 662 | return false; // Incorrect slot index |
| 663 | } |
| 664 | Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx); |
| 665 | const char* signature = (const char *) sign_sym->as_utf8(); |
| 666 | BasicType slot_type = char2type(signature[0]); |
| 667 | |
| 668 | switch (slot_type) { |
| 669 | case T_BYTE: |
| 670 | case T_SHORT: |
| 671 | case T_CHAR: |
| 672 | case T_BOOLEAN: |
| 673 | slot_type = T_INT; |
| 674 | break; |
| 675 | case T_ARRAY: |
| 676 | slot_type = T_OBJECT; |
| 677 | break; |
| 678 | default: |
| 679 | break; |
| 680 | }; |
| 681 | if (_type != slot_type) { |
| 682 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
| 683 | return false; |
| 684 | } |
| 685 | |
| 686 | jobject jobj = _value.l; |
| 687 | if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed |
| 688 | // Check that the jobject class matches the return type signature. |
| 689 | JavaThread* cur_thread = JavaThread::current(); |
| 690 | HandleMark hm(cur_thread); |
| 691 | |
| 692 | Handle obj(cur_thread, JNIHandles::resolve_external_guard(jobj)); |
| 693 | NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); |
| 694 | Klass* ob_k = obj->klass(); |
| 695 | NULL_CHECK(ob_k, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); |
| 696 | |
| 697 | if (!is_assignable(signature, ob_k, cur_thread)) { |
| 698 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
| 699 | return false; |
| 700 | } |
| 701 | } |
| 702 | return true; |
| 703 | } |
| 704 | |
| 705 | bool VM_GetOrSetLocal::check_slot_type_no_lvt(javaVFrame* jvf) { |
| 706 | Method* method_oop = jvf->method(); |
| 707 | jint = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; |
| 708 | |
| 709 | if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { |
| 710 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 711 | return false; |
| 712 | } |
| 713 | StackValueCollection *locals = _jvf->locals(); |
| 714 | BasicType slot_type = locals->at(_index)->type(); |
| 715 | |
| 716 | if (slot_type == T_CONFLICT) { |
| 717 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 718 | return false; |
| 719 | } |
| 720 | if (extra_slot) { |
| 721 | BasicType = locals->at(_index + 1)->type(); |
| 722 | if (extra_slot_type != T_INT) { |
| 723 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 724 | return false; |
| 725 | } |
| 726 | } |
| 727 | if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) { |
| 728 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
| 729 | return false; |
| 730 | } |
| 731 | return true; |
| 732 | } |
| 733 | |
| 734 | static bool can_be_deoptimized(vframe* vf) { |
| 735 | return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); |
| 736 | } |
| 737 | |
| 738 | bool VM_GetOrSetLocal::doit_prologue() { |
| 739 | _jvf = get_java_vframe(); |
| 740 | NULL_CHECK(_jvf, false); |
| 741 | |
| 742 | Method* method_oop = _jvf->method(); |
| 743 | if (method_oop->is_native()) { |
| 744 | if (getting_receiver() && !method_oop->is_static()) { |
| 745 | return true; |
| 746 | } else { |
| 747 | _result = JVMTI_ERROR_OPAQUE_FRAME; |
| 748 | return false; |
| 749 | } |
| 750 | } |
| 751 | |
| 752 | if (!check_slot_type_no_lvt(_jvf)) { |
| 753 | return false; |
| 754 | } |
| 755 | if (method_oop->has_localvariable_table()) { |
| 756 | return check_slot_type_lvt(_jvf); |
| 757 | } |
| 758 | return true; |
| 759 | } |
| 760 | |
| 761 | void VM_GetOrSetLocal::doit() { |
| 762 | InterpreterOopMap oop_mask; |
| 763 | _jvf->method()->mask_for(_jvf->bci(), &oop_mask); |
| 764 | if (oop_mask.is_dead(_index)) { |
| 765 | // The local can be invalid and uninitialized in the scope of current bci |
| 766 | _result = JVMTI_ERROR_INVALID_SLOT; |
| 767 | return; |
| 768 | } |
| 769 | if (_set) { |
| 770 | // Force deoptimization of frame if compiled because it's |
| 771 | // possible the compiler emitted some locals as constant values, |
| 772 | // meaning they are not mutable. |
| 773 | if (can_be_deoptimized(_jvf)) { |
| 774 | |
| 775 | // Schedule deoptimization so that eventually the local |
| 776 | // update will be written to an interpreter frame. |
| 777 | Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id()); |
| 778 | |
| 779 | // Now store a new value for the local which will be applied |
| 780 | // once deoptimization occurs. Note however that while this |
| 781 | // write is deferred until deoptimization actually happens |
| 782 | // can vframe created after this point will have its locals |
| 783 | // reflecting this update so as far as anyone can see the |
| 784 | // write has already taken place. |
| 785 | |
| 786 | // If we are updating an oop then get the oop from the handle |
| 787 | // since the handle will be long gone by the time the deopt |
| 788 | // happens. The oop stored in the deferred local will be |
| 789 | // gc'd on its own. |
| 790 | if (_type == T_OBJECT) { |
| 791 | _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l)); |
| 792 | } |
| 793 | // Re-read the vframe so we can see that it is deoptimized |
| 794 | // [ Only need because of assert in update_local() ] |
| 795 | _jvf = get_java_vframe(); |
| 796 | ((compiledVFrame*)_jvf)->update_local(_type, _index, _value); |
| 797 | return; |
| 798 | } |
| 799 | StackValueCollection *locals = _jvf->locals(); |
| 800 | HandleMark hm; |
| 801 | |
| 802 | switch (_type) { |
| 803 | case T_INT: locals->set_int_at (_index, _value.i); break; |
| 804 | case T_LONG: locals->set_long_at (_index, _value.j); break; |
| 805 | case T_FLOAT: locals->set_float_at (_index, _value.f); break; |
| 806 | case T_DOUBLE: locals->set_double_at(_index, _value.d); break; |
| 807 | case T_OBJECT: { |
| 808 | Handle ob_h(Thread::current(), JNIHandles::resolve_external_guard(_value.l)); |
| 809 | locals->set_obj_at (_index, ob_h); |
| 810 | break; |
| 811 | } |
| 812 | default: ShouldNotReachHere(); |
| 813 | } |
| 814 | _jvf->set_locals(locals); |
| 815 | } else { |
| 816 | if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) { |
| 817 | assert(getting_receiver(), "Can only get here when getting receiver" ); |
| 818 | oop receiver = _jvf->fr().get_native_receiver(); |
| 819 | _value.l = JNIHandles::make_local(_calling_thread, receiver); |
| 820 | } else { |
| 821 | StackValueCollection *locals = _jvf->locals(); |
| 822 | |
| 823 | switch (_type) { |
| 824 | case T_INT: _value.i = locals->int_at (_index); break; |
| 825 | case T_LONG: _value.j = locals->long_at (_index); break; |
| 826 | case T_FLOAT: _value.f = locals->float_at (_index); break; |
| 827 | case T_DOUBLE: _value.d = locals->double_at(_index); break; |
| 828 | case T_OBJECT: { |
| 829 | // Wrap the oop to be returned in a local JNI handle since |
| 830 | // oops_do() no longer applies after doit() is finished. |
| 831 | oop obj = locals->obj_at(_index)(); |
| 832 | _value.l = JNIHandles::make_local(_calling_thread, obj); |
| 833 | break; |
| 834 | } |
| 835 | default: ShouldNotReachHere(); |
| 836 | } |
| 837 | } |
| 838 | } |
| 839 | } |
| 840 | |
| 841 | |
| 842 | bool VM_GetOrSetLocal::allow_nested_vm_operations() const { |
| 843 | return true; // May need to deoptimize |
| 844 | } |
| 845 | |
| 846 | |
| 847 | VM_GetReceiver::VM_GetReceiver( |
| 848 | JavaThread* thread, JavaThread* caller_thread, jint depth) |
| 849 | : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {} |
| 850 | |
| 851 | ///////////////////////////////////////////////////////////////////////////////////////// |
| 852 | |
| 853 | // |
| 854 | // class JvmtiSuspendControl - see comments in jvmtiImpl.hpp |
| 855 | // |
| 856 | |
| 857 | bool JvmtiSuspendControl::suspend(JavaThread *java_thread) { |
| 858 | // external suspend should have caught suspending a thread twice |
| 859 | |
| 860 | // Immediate suspension required for JPDA back-end so JVMTI agent threads do |
| 861 | // not deadlock due to later suspension on transitions while holding |
| 862 | // raw monitors. Passing true causes the immediate suspension. |
| 863 | // java_suspend() will catch threads in the process of exiting |
| 864 | // and will ignore them. |
| 865 | java_thread->java_suspend(); |
| 866 | |
| 867 | // It would be nice to have the following assertion in all the time, |
| 868 | // but it is possible for a racing resume request to have resumed |
| 869 | // this thread right after we suspended it. Temporarily enable this |
| 870 | // assertion if you are chasing a different kind of bug. |
| 871 | // |
| 872 | // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL || |
| 873 | // java_thread->is_being_ext_suspended(), "thread is not suspended"); |
| 874 | |
| 875 | if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) { |
| 876 | // check again because we can get delayed in java_suspend(): |
| 877 | // the thread is in process of exiting. |
| 878 | return false; |
| 879 | } |
| 880 | |
| 881 | return true; |
| 882 | } |
| 883 | |
| 884 | bool JvmtiSuspendControl::resume(JavaThread *java_thread) { |
| 885 | // external suspend should have caught resuming a thread twice |
| 886 | assert(java_thread->is_being_ext_suspended(), "thread should be suspended" ); |
| 887 | |
| 888 | // resume thread |
| 889 | { |
| 890 | // must always grab Threads_lock, see JVM_SuspendThread |
| 891 | MutexLocker ml(Threads_lock); |
| 892 | java_thread->java_resume(); |
| 893 | } |
| 894 | |
| 895 | return true; |
| 896 | } |
| 897 | |
| 898 | |
| 899 | void JvmtiSuspendControl::print() { |
| 900 | #ifndef PRODUCT |
| 901 | LogStreamHandle(Trace, jvmti) log_stream; |
| 902 | log_stream.print("Suspended Threads: [" ); |
| 903 | for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) { |
| 904 | #ifdef JVMTI_TRACE |
| 905 | const char *name = JvmtiTrace::safe_get_thread_name(thread); |
| 906 | #else |
| 907 | const char *name = "" ; |
| 908 | #endif /*JVMTI_TRACE */ |
| 909 | log_stream.print("%s(%c " , name, thread->is_being_ext_suspended() ? 'S' : '_'); |
| 910 | if (!thread->has_last_Java_frame()) { |
| 911 | log_stream.print("no stack" ); |
| 912 | } |
| 913 | log_stream.print(") " ); |
| 914 | } |
| 915 | log_stream.print_cr("]" ); |
| 916 | #endif |
| 917 | } |
| 918 | |
| 919 | JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( |
| 920 | nmethod* nm) { |
| 921 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); |
| 922 | event._event_data.compiled_method_load = nm; |
| 923 | // Keep the nmethod alive until the ServiceThread can process |
| 924 | // this deferred event. |
| 925 | nmethodLocker::lock_nmethod(nm); |
| 926 | return event; |
| 927 | } |
| 928 | |
| 929 | JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( |
| 930 | nmethod* nm, jmethodID id, const void* code) { |
| 931 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); |
| 932 | event._event_data.compiled_method_unload.nm = nm; |
| 933 | event._event_data.compiled_method_unload.method_id = id; |
| 934 | event._event_data.compiled_method_unload.code_begin = code; |
| 935 | // Keep the nmethod alive until the ServiceThread can process |
| 936 | // this deferred event. This will keep the memory for the |
| 937 | // generated code from being reused too early. We pass |
| 938 | // zombie_ok == true here so that our nmethod that was just |
| 939 | // made into a zombie can be locked. |
| 940 | nmethodLocker::lock_nmethod(nm, true /* zombie_ok */); |
| 941 | return event; |
| 942 | } |
| 943 | |
| 944 | JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event( |
| 945 | const char* name, const void* code_begin, const void* code_end) { |
| 946 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED); |
| 947 | // Need to make a copy of the name since we don't know how long |
| 948 | // the event poster will keep it around after we enqueue the |
| 949 | // deferred event and return. strdup() failure is handled in |
| 950 | // the post() routine below. |
| 951 | event._event_data.dynamic_code_generated.name = os::strdup(name); |
| 952 | event._event_data.dynamic_code_generated.code_begin = code_begin; |
| 953 | event._event_data.dynamic_code_generated.code_end = code_end; |
| 954 | return event; |
| 955 | } |
| 956 | |
| 957 | void JvmtiDeferredEvent::post() { |
| 958 | assert(ServiceThread::is_service_thread(Thread::current()), |
| 959 | "Service thread must post enqueued events" ); |
| 960 | switch(_type) { |
| 961 | case TYPE_COMPILED_METHOD_LOAD: { |
| 962 | nmethod* nm = _event_data.compiled_method_load; |
| 963 | JvmtiExport::post_compiled_method_load(nm); |
| 964 | // done with the deferred event so unlock the nmethod |
| 965 | nmethodLocker::unlock_nmethod(nm); |
| 966 | break; |
| 967 | } |
| 968 | case TYPE_COMPILED_METHOD_UNLOAD: { |
| 969 | nmethod* nm = _event_data.compiled_method_unload.nm; |
| 970 | JvmtiExport::post_compiled_method_unload( |
| 971 | _event_data.compiled_method_unload.method_id, |
| 972 | _event_data.compiled_method_unload.code_begin); |
| 973 | // done with the deferred event so unlock the nmethod |
| 974 | nmethodLocker::unlock_nmethod(nm); |
| 975 | break; |
| 976 | } |
| 977 | case TYPE_DYNAMIC_CODE_GENERATED: { |
| 978 | JvmtiExport::post_dynamic_code_generated_internal( |
| 979 | // if strdup failed give the event a default name |
| 980 | (_event_data.dynamic_code_generated.name == NULL) |
| 981 | ? "unknown_code" : _event_data.dynamic_code_generated.name, |
| 982 | _event_data.dynamic_code_generated.code_begin, |
| 983 | _event_data.dynamic_code_generated.code_end); |
| 984 | if (_event_data.dynamic_code_generated.name != NULL) { |
| 985 | // release our copy |
| 986 | os::free((void *)_event_data.dynamic_code_generated.name); |
| 987 | } |
| 988 | break; |
| 989 | } |
| 990 | default: |
| 991 | ShouldNotReachHere(); |
| 992 | } |
| 993 | } |
| 994 | |
| 995 | JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL; |
| 996 | JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL; |
| 997 | |
| 998 | bool JvmtiDeferredEventQueue::has_events() { |
| 999 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
| 1000 | return _queue_head != NULL; |
| 1001 | } |
| 1002 | |
| 1003 | void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) { |
| 1004 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
| 1005 | |
| 1006 | // Events get added to the end of the queue (and are pulled off the front). |
| 1007 | QueueNode* node = new QueueNode(event); |
| 1008 | if (_queue_tail == NULL) { |
| 1009 | _queue_tail = _queue_head = node; |
| 1010 | } else { |
| 1011 | assert(_queue_tail->next() == NULL, "Must be the last element in the list" ); |
| 1012 | _queue_tail->set_next(node); |
| 1013 | _queue_tail = node; |
| 1014 | } |
| 1015 | |
| 1016 | Service_lock->notify_all(); |
| 1017 | assert((_queue_head == NULL) == (_queue_tail == NULL), |
| 1018 | "Inconsistent queue markers" ); |
| 1019 | } |
| 1020 | |
| 1021 | JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() { |
| 1022 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
| 1023 | |
| 1024 | assert(_queue_head != NULL, "Nothing to dequeue" ); |
| 1025 | |
| 1026 | if (_queue_head == NULL) { |
| 1027 | // Just in case this happens in product; it shouldn't but let's not crash |
| 1028 | return JvmtiDeferredEvent(); |
| 1029 | } |
| 1030 | |
| 1031 | QueueNode* node = _queue_head; |
| 1032 | _queue_head = _queue_head->next(); |
| 1033 | if (_queue_head == NULL) { |
| 1034 | _queue_tail = NULL; |
| 1035 | } |
| 1036 | |
| 1037 | assert((_queue_head == NULL) == (_queue_tail == NULL), |
| 1038 | "Inconsistent queue markers" ); |
| 1039 | |
| 1040 | JvmtiDeferredEvent event = node->event(); |
| 1041 | delete node; |
| 1042 | return event; |
| 1043 | } |
| 1044 | |