1 /* 2 * Copyright (c) 2003, 2018, 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/javaClasses.inline.hpp" 27 #include "classfile/symbolTable.hpp" 28 #include "classfile/systemDictionary.hpp" 29 #include "classfile/vmSymbols.hpp" 30 #include "code/codeCache.hpp" 31 #include "jvmtifiles/jvmtiEnv.hpp" 32 #include "memory/allocation.inline.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "oops/access.inline.hpp" 35 #include "oops/arrayOop.inline.hpp" 36 #include "oops/constantPool.inline.hpp" 37 #include "oops/instanceMirrorKlass.hpp" 38 #include "oops/objArrayKlass.hpp" 39 #include "oops/objArrayOop.inline.hpp" 40 #include "oops/oop.inline.hpp" 41 #include "oops/typeArrayOop.inline.hpp" 42 #include "prims/jvmtiEventController.hpp" 43 #include "prims/jvmtiEventController.inline.hpp" 44 #include "prims/jvmtiExport.hpp" 45 #include "prims/jvmtiImpl.hpp" 46 #include "prims/jvmtiTagMap.hpp" 47 #include "runtime/biasedLocking.hpp" 48 #include "runtime/javaCalls.hpp" 49 #include "runtime/jniHandles.inline.hpp" 50 #include "runtime/mutex.hpp" 51 #include "runtime/mutexLocker.hpp" 52 #include "runtime/reflectionUtils.hpp" 53 #include "runtime/thread.inline.hpp" 54 #include "runtime/threadSMR.hpp" 55 #include "runtime/vframe.hpp" 56 #include "runtime/vmThread.hpp" 57 #include "runtime/vm_operations.hpp" 58 #include "utilities/macros.hpp" 59 60 // JvmtiTagHashmapEntry 61 // 62 // Each entry encapsulates a reference to the tagged object 63 // and the tag value. In addition an entry includes a next pointer which 64 // is used to chain entries together. 65 66 class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> { 67 private: 68 friend class JvmtiTagMap; 69 70 oop _object; // tagged object 71 jlong _tag; // the tag 72 JvmtiTagHashmapEntry* _next; // next on the list 73 74 inline void init(oop object, jlong tag) { 75 _object = object; 76 _tag = tag; 77 _next = NULL; 78 } 79 80 // constructor 81 JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); } 82 83 public: 84 85 // accessor methods 86 inline oop* object_addr() { return &_object; } 87 inline oop object() { return RootAccess<ON_PHANTOM_OOP_REF>::oop_load(object_addr()); } 88 // Peek at the object without keeping it alive. The returned object must be 89 // kept alive using a normal access if it leaks out of a thread transition from VM. 90 inline oop object_peek() { 91 return RootAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(object_addr()); 92 } 93 inline jlong tag() const { return _tag; } 94 95 inline void set_tag(jlong tag) { 96 assert(tag != 0, "can't be zero"); 97 _tag = tag; 98 } 99 100 inline bool equals(oop object) { 101 return object == object_peek(); 102 } 103 104 inline JvmtiTagHashmapEntry* next() const { return _next; } 105 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; } 106 }; 107 108 109 // JvmtiTagHashmap 110 // 111 // A hashmap is essentially a table of pointers to entries. Entries 112 // are hashed to a location, or position in the table, and then 113 // chained from that location. The "key" for hashing is address of 114 // the object, or oop. The "value" is the tag value. 115 // 116 // A hashmap maintains a count of the number entries in the hashmap 117 // and resizes if the number of entries exceeds a given threshold. 118 // The threshold is specified as a percentage of the size - for 119 // example a threshold of 0.75 will trigger the hashmap to resize 120 // if the number of entries is >75% of table size. 121 // 122 // A hashmap provides functions for adding, removing, and finding 123 // entries. It also provides a function to iterate over all entries 124 // in the hashmap. 125 126 class JvmtiTagHashmap : public CHeapObj<mtInternal> { 127 private: 128 friend class JvmtiTagMap; 129 130 enum { 131 small_trace_threshold = 10000, // threshold for tracing 132 medium_trace_threshold = 100000, 133 large_trace_threshold = 1000000, 134 initial_trace_threshold = small_trace_threshold 135 }; 136 137 static int _sizes[]; // array of possible hashmap sizes 138 int _size; // actual size of the table 139 int _size_index; // index into size table 140 141 int _entry_count; // number of entries in the hashmap 142 143 float _load_factor; // load factor as a % of the size 144 int _resize_threshold; // computed threshold to trigger resizing. 145 bool _resizing_enabled; // indicates if hashmap can resize 146 147 int _trace_threshold; // threshold for trace messages 148 149 JvmtiTagHashmapEntry** _table; // the table of entries. 150 151 // private accessors 152 int resize_threshold() const { return _resize_threshold; } 153 int trace_threshold() const { return _trace_threshold; } 154 155 // initialize the hashmap 156 void init(int size_index=0, float load_factor=4.0f) { 157 int initial_size = _sizes[size_index]; 158 _size_index = size_index; 159 _size = initial_size; 160 _entry_count = 0; 161 _trace_threshold = initial_trace_threshold; 162 _load_factor = load_factor; 163 _resize_threshold = (int)(_load_factor * _size); 164 _resizing_enabled = true; 165 size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*); 166 _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal); 167 if (_table == NULL) { 168 vm_exit_out_of_memory(s, OOM_MALLOC_ERROR, 169 "unable to allocate initial hashtable for jvmti object tags"); 170 } 171 for (int i=0; i<initial_size; i++) { 172 _table[i] = NULL; 173 } 174 } 175 176 // hash a given key (oop) with the specified size 177 static unsigned int hash(oop key, int size) { 178 // shift right to get better distribution (as these bits will be zero 179 // with aligned addresses) 180 unsigned int addr = (unsigned int)(cast_from_oop<intptr_t>(key)); 181 #ifdef _LP64 182 return (addr >> 3) % size; 183 #else 184 return (addr >> 2) % size; 185 #endif 186 } 187 188 // hash a given key (oop) 189 unsigned int hash(oop key) { 190 return hash(key, _size); 191 } 192 193 // resize the hashmap - allocates a large table and re-hashes 194 // all entries into the new table. 195 void resize() { 196 int new_size_index = _size_index+1; 197 int new_size = _sizes[new_size_index]; 198 if (new_size < 0) { 199 // hashmap already at maximum capacity 200 return; 201 } 202 203 // allocate new table 204 size_t s = new_size * sizeof(JvmtiTagHashmapEntry*); 205 JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal); 206 if (new_table == NULL) { 207 warning("unable to allocate larger hashtable for jvmti object tags"); 208 set_resizing_enabled(false); 209 return; 210 } 211 212 // initialize new table 213 int i; 214 for (i=0; i<new_size; i++) { 215 new_table[i] = NULL; 216 } 217 218 // rehash all entries into the new table 219 for (i=0; i<_size; i++) { 220 JvmtiTagHashmapEntry* entry = _table[i]; 221 while (entry != NULL) { 222 JvmtiTagHashmapEntry* next = entry->next(); 223 oop key = entry->object_peek(); 224 assert(key != NULL, "jni weak reference cleared!!"); 225 unsigned int h = hash(key, new_size); 226 JvmtiTagHashmapEntry* anchor = new_table[h]; 227 if (anchor == NULL) { 228 new_table[h] = entry; 229 entry->set_next(NULL); 230 } else { 231 entry->set_next(anchor); 232 new_table[h] = entry; 233 } 234 entry = next; 235 } 236 } 237 238 // free old table and update settings. 239 os::free((void*)_table); 240 _table = new_table; 241 _size_index = new_size_index; 242 _size = new_size; 243 244 // compute new resize threshold 245 _resize_threshold = (int)(_load_factor * _size); 246 } 247 248 249 // internal remove function - remove an entry at a given position in the 250 // table. 251 inline void remove(JvmtiTagHashmapEntry* prev, int pos, JvmtiTagHashmapEntry* entry) { 252 assert(pos >= 0 && pos < _size, "out of range"); 253 if (prev == NULL) { 254 _table[pos] = entry->next(); 255 } else { 256 prev->set_next(entry->next()); 257 } 258 assert(_entry_count > 0, "checking"); 259 _entry_count--; 260 } 261 262 // resizing switch 263 bool is_resizing_enabled() const { return _resizing_enabled; } 264 void set_resizing_enabled(bool enable) { _resizing_enabled = enable; } 265 266 // debugging 267 void print_memory_usage(); 268 void compute_next_trace_threshold(); 269 270 public: 271 272 // create a JvmtiTagHashmap of a preferred size and optionally a load factor. 273 // The preferred size is rounded down to an actual size. 274 JvmtiTagHashmap(int size, float load_factor=0.0f) { 275 int i=0; 276 while (_sizes[i] < size) { 277 if (_sizes[i] < 0) { 278 assert(i > 0, "sanity check"); 279 i--; 280 break; 281 } 282 i++; 283 } 284 285 // if a load factor is specified then use it, otherwise use default 286 if (load_factor > 0.01f) { 287 init(i, load_factor); 288 } else { 289 init(i); 290 } 291 } 292 293 // create a JvmtiTagHashmap with default settings 294 JvmtiTagHashmap() { 295 init(); 296 } 297 298 // release table when JvmtiTagHashmap destroyed 299 ~JvmtiTagHashmap() { 300 if (_table != NULL) { 301 os::free((void*)_table); 302 _table = NULL; 303 } 304 } 305 306 // accessors 307 int size() const { return _size; } 308 JvmtiTagHashmapEntry** table() const { return _table; } 309 int entry_count() const { return _entry_count; } 310 311 // find an entry in the hashmap, returns NULL if not found. 312 inline JvmtiTagHashmapEntry* find(oop key) { 313 unsigned int h = hash(key); 314 JvmtiTagHashmapEntry* entry = _table[h]; 315 while (entry != NULL) { 316 if (entry->equals(key)) { 317 return entry; 318 } 319 entry = entry->next(); 320 } 321 return NULL; 322 } 323 324 325 // add a new entry to hashmap 326 inline void add(oop key, JvmtiTagHashmapEntry* entry) { 327 assert(key != NULL, "checking"); 328 assert(find(key) == NULL, "duplicate detected"); 329 unsigned int h = hash(key); 330 JvmtiTagHashmapEntry* anchor = _table[h]; 331 if (anchor == NULL) { 332 _table[h] = entry; 333 entry->set_next(NULL); 334 } else { 335 entry->set_next(anchor); 336 _table[h] = entry; 337 } 338 339 _entry_count++; 340 if (log_is_enabled(Debug, jvmti, objecttagging) && entry_count() >= trace_threshold()) { 341 print_memory_usage(); 342 compute_next_trace_threshold(); 343 } 344 345 // if the number of entries exceed the threshold then resize 346 if (entry_count() > resize_threshold() && is_resizing_enabled()) { 347 resize(); 348 } 349 } 350 351 // remove an entry with the given key. 352 inline JvmtiTagHashmapEntry* remove(oop key) { 353 unsigned int h = hash(key); 354 JvmtiTagHashmapEntry* entry = _table[h]; 355 JvmtiTagHashmapEntry* prev = NULL; 356 while (entry != NULL) { 357 if (entry->equals(key)) { 358 break; 359 } 360 prev = entry; 361 entry = entry->next(); 362 } 363 if (entry != NULL) { 364 remove(prev, h, entry); 365 } 366 return entry; 367 } 368 369 // iterate over all entries in the hashmap 370 void entry_iterate(JvmtiTagHashmapEntryClosure* closure); 371 }; 372 373 // possible hashmap sizes - odd primes that roughly double in size. 374 // To avoid excessive resizing the odd primes from 4801-76831 and 375 // 76831-307261 have been removed. The list must be terminated by -1. 376 int JvmtiTagHashmap::_sizes[] = { 4801, 76831, 307261, 614563, 1228891, 377 2457733, 4915219, 9830479, 19660831, 39321619, 78643219, -1 }; 378 379 380 // A supporting class for iterating over all entries in Hashmap 381 class JvmtiTagHashmapEntryClosure { 382 public: 383 virtual void do_entry(JvmtiTagHashmapEntry* entry) = 0; 384 }; 385 386 387 // iterate over all entries in the hashmap 388 void JvmtiTagHashmap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) { 389 for (int i=0; i<_size; i++) { 390 JvmtiTagHashmapEntry* entry = _table[i]; 391 JvmtiTagHashmapEntry* prev = NULL; 392 while (entry != NULL) { 393 // obtain the next entry before invoking do_entry - this is 394 // necessary because do_entry may remove the entry from the 395 // hashmap. 396 JvmtiTagHashmapEntry* next = entry->next(); 397 closure->do_entry(entry); 398 entry = next; 399 } 400 } 401 } 402 403 // debugging 404 void JvmtiTagHashmap::print_memory_usage() { 405 intptr_t p = (intptr_t)this; 406 tty->print("[JvmtiTagHashmap @ " INTPTR_FORMAT, p); 407 408 // table + entries in KB 409 int hashmap_usage = (size()*sizeof(JvmtiTagHashmapEntry*) + 410 entry_count()*sizeof(JvmtiTagHashmapEntry))/K; 411 412 int weak_globals_usage = (int)(JNIHandles::weak_global_handle_memory_usage()/K); 413 tty->print_cr(", %d entries (%d KB) <JNI weak globals: %d KB>]", 414 entry_count(), hashmap_usage, weak_globals_usage); 415 } 416 417 // compute threshold for the next trace message 418 void JvmtiTagHashmap::compute_next_trace_threshold() { 419 _trace_threshold = entry_count(); 420 if (trace_threshold() < medium_trace_threshold) { 421 _trace_threshold += small_trace_threshold; 422 } else { 423 if (trace_threshold() < large_trace_threshold) { 424 _trace_threshold += medium_trace_threshold; 425 } else { 426 _trace_threshold += large_trace_threshold; 427 } 428 } 429 } 430 431 // create a JvmtiTagMap 432 JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) : 433 _env(env), 434 _lock(Mutex::nonleaf+2, "JvmtiTagMap._lock", false), 435 _free_entries(NULL), 436 _free_entries_count(0) 437 { 438 assert(JvmtiThreadState_lock->is_locked(), "sanity check"); 439 assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment"); 440 441 _hashmap = new JvmtiTagHashmap(); 442 443 // finally add us to the environment 444 ((JvmtiEnvBase *)env)->set_tag_map(this); 445 } 446 447 448 // destroy a JvmtiTagMap 449 JvmtiTagMap::~JvmtiTagMap() { 450 451 // no lock acquired as we assume the enclosing environment is 452 // also being destroryed. 453 ((JvmtiEnvBase *)_env)->set_tag_map(NULL); 454 455 JvmtiTagHashmapEntry** table = _hashmap->table(); 456 for (int j = 0; j < _hashmap->size(); j++) { 457 JvmtiTagHashmapEntry* entry = table[j]; 458 while (entry != NULL) { 459 JvmtiTagHashmapEntry* next = entry->next(); 460 delete entry; 461 entry = next; 462 } 463 } 464 465 // finally destroy the hashmap 466 delete _hashmap; 467 _hashmap = NULL; 468 469 // remove any entries on the free list 470 JvmtiTagHashmapEntry* entry = _free_entries; 471 while (entry != NULL) { 472 JvmtiTagHashmapEntry* next = entry->next(); 473 delete entry; 474 entry = next; 475 } 476 _free_entries = NULL; 477 } 478 479 // create a hashmap entry 480 // - if there's an entry on the (per-environment) free list then this 481 // is returned. Otherwise an new entry is allocated. 482 JvmtiTagHashmapEntry* JvmtiTagMap::create_entry(oop ref, jlong tag) { 483 assert(Thread::current()->is_VM_thread() || is_locked(), "checking"); 484 JvmtiTagHashmapEntry* entry; 485 if (_free_entries == NULL) { 486 entry = new JvmtiTagHashmapEntry(ref, tag); 487 } else { 488 assert(_free_entries_count > 0, "mismatched _free_entries_count"); 489 _free_entries_count--; 490 entry = _free_entries; 491 _free_entries = entry->next(); 492 entry->init(ref, tag); 493 } 494 return entry; 495 } 496 497 // destroy an entry by returning it to the free list 498 void JvmtiTagMap::destroy_entry(JvmtiTagHashmapEntry* entry) { 499 assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking"); 500 // limit the size of the free list 501 if (_free_entries_count >= max_free_entries) { 502 delete entry; 503 } else { 504 entry->set_next(_free_entries); 505 _free_entries = entry; 506 _free_entries_count++; 507 } 508 } 509 510 // returns the tag map for the given environments. If the tag map 511 // doesn't exist then it is created. 512 JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) { 513 JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map(); 514 if (tag_map == NULL) { 515 MutexLocker mu(JvmtiThreadState_lock); 516 tag_map = ((JvmtiEnvBase*)env)->tag_map(); 517 if (tag_map == NULL) { 518 tag_map = new JvmtiTagMap(env); 519 } 520 } else { 521 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 522 } 523 return tag_map; 524 } 525 526 // iterate over all entries in the tag map. 527 void JvmtiTagMap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) { 528 hashmap()->entry_iterate(closure); 529 } 530 531 // returns true if the hashmaps are empty 532 bool JvmtiTagMap::is_empty() { 533 assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking"); 534 return hashmap()->entry_count() == 0; 535 } 536 537 538 // Return the tag value for an object, or 0 if the object is 539 // not tagged 540 // 541 static inline jlong tag_for(JvmtiTagMap* tag_map, oop o) { 542 JvmtiTagHashmapEntry* entry = tag_map->hashmap()->find(o); 543 if (entry == NULL) { 544 return 0; 545 } else { 546 return entry->tag(); 547 } 548 } 549 550 551 // A CallbackWrapper is a support class for querying and tagging an object 552 // around a callback to a profiler. The constructor does pre-callback 553 // work to get the tag value, klass tag value, ... and the destructor 554 // does the post-callback work of tagging or untagging the object. 555 // 556 // { 557 // CallbackWrapper wrapper(tag_map, o); 558 // 559 // (*callback)(wrapper.klass_tag(), wrapper.obj_size(), wrapper.obj_tag_p(), ...) 560 // 561 // } // wrapper goes out of scope here which results in the destructor 562 // checking to see if the object has been tagged, untagged, or the 563 // tag value has changed. 564 // 565 class CallbackWrapper : public StackObj { 566 private: 567 JvmtiTagMap* _tag_map; 568 JvmtiTagHashmap* _hashmap; 569 JvmtiTagHashmapEntry* _entry; 570 oop _o; 571 jlong _obj_size; 572 jlong _obj_tag; 573 jlong _klass_tag; 574 575 protected: 576 JvmtiTagMap* tag_map() const { return _tag_map; } 577 578 // invoked post-callback to tag, untag, or update the tag of an object 579 void inline post_callback_tag_update(oop o, JvmtiTagHashmap* hashmap, 580 JvmtiTagHashmapEntry* entry, jlong obj_tag); 581 public: 582 CallbackWrapper(JvmtiTagMap* tag_map, oop o) { 583 assert(Thread::current()->is_VM_thread() || tag_map->is_locked(), 584 "MT unsafe or must be VM thread"); 585 586 // object to tag 587 _o = o; 588 589 // object size 590 _obj_size = (jlong)_o->size() * wordSize; 591 592 // record the context 593 _tag_map = tag_map; 594 _hashmap = tag_map->hashmap(); 595 _entry = _hashmap->find(_o); 596 597 // get object tag 598 _obj_tag = (_entry == NULL) ? 0 : _entry->tag(); 599 600 // get the class and the class's tag value 601 assert(SystemDictionary::Class_klass()->is_mirror_instance_klass(), "Is not?"); 602 603 _klass_tag = tag_for(tag_map, _o->klass()->java_mirror()); 604 } 605 606 ~CallbackWrapper() { 607 post_callback_tag_update(_o, _hashmap, _entry, _obj_tag); 608 } 609 610 inline jlong* obj_tag_p() { return &_obj_tag; } 611 inline jlong obj_size() const { return _obj_size; } 612 inline jlong obj_tag() const { return _obj_tag; } 613 inline jlong klass_tag() const { return _klass_tag; } 614 }; 615 616 617 618 // callback post-callback to tag, untag, or update the tag of an object 619 void inline CallbackWrapper::post_callback_tag_update(oop o, 620 JvmtiTagHashmap* hashmap, 621 JvmtiTagHashmapEntry* entry, 622 jlong obj_tag) { 623 if (entry == NULL) { 624 if (obj_tag != 0) { 625 // callback has tagged the object 626 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 627 entry = tag_map()->create_entry(o, obj_tag); 628 hashmap->add(o, entry); 629 } 630 } else { 631 // object was previously tagged - the callback may have untagged 632 // the object or changed the tag value 633 if (obj_tag == 0) { 634 635 JvmtiTagHashmapEntry* entry_removed = hashmap->remove(o); 636 assert(entry_removed == entry, "checking"); 637 tag_map()->destroy_entry(entry); 638 639 } else { 640 if (obj_tag != entry->tag()) { 641 entry->set_tag(obj_tag); 642 } 643 } 644 } 645 } 646 647 // An extended CallbackWrapper used when reporting an object reference 648 // to the agent. 649 // 650 // { 651 // TwoOopCallbackWrapper wrapper(tag_map, referrer, o); 652 // 653 // (*callback)(wrapper.klass_tag(), 654 // wrapper.obj_size(), 655 // wrapper.obj_tag_p() 656 // wrapper.referrer_tag_p(), ...) 657 // 658 // } // wrapper goes out of scope here which results in the destructor 659 // checking to see if the referrer object has been tagged, untagged, 660 // or the tag value has changed. 661 // 662 class TwoOopCallbackWrapper : public CallbackWrapper { 663 private: 664 bool _is_reference_to_self; 665 JvmtiTagHashmap* _referrer_hashmap; 666 JvmtiTagHashmapEntry* _referrer_entry; 667 oop _referrer; 668 jlong _referrer_obj_tag; 669 jlong _referrer_klass_tag; 670 jlong* _referrer_tag_p; 671 672 bool is_reference_to_self() const { return _is_reference_to_self; } 673 674 public: 675 TwoOopCallbackWrapper(JvmtiTagMap* tag_map, oop referrer, oop o) : 676 CallbackWrapper(tag_map, o) 677 { 678 // self reference needs to be handled in a special way 679 _is_reference_to_self = (referrer == o); 680 681 if (_is_reference_to_self) { 682 _referrer_klass_tag = klass_tag(); 683 _referrer_tag_p = obj_tag_p(); 684 } else { 685 _referrer = referrer; 686 // record the context 687 _referrer_hashmap = tag_map->hashmap(); 688 _referrer_entry = _referrer_hashmap->find(_referrer); 689 690 // get object tag 691 _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag(); 692 _referrer_tag_p = &_referrer_obj_tag; 693 694 // get referrer class tag. 695 _referrer_klass_tag = tag_for(tag_map, _referrer->klass()->java_mirror()); 696 } 697 } 698 699 ~TwoOopCallbackWrapper() { 700 if (!is_reference_to_self()){ 701 post_callback_tag_update(_referrer, 702 _referrer_hashmap, 703 _referrer_entry, 704 _referrer_obj_tag); 705 } 706 } 707 708 // address of referrer tag 709 // (for a self reference this will return the same thing as obj_tag_p()) 710 inline jlong* referrer_tag_p() { return _referrer_tag_p; } 711 712 // referrer's class tag 713 inline jlong referrer_klass_tag() { return _referrer_klass_tag; } 714 }; 715 716 // tag an object 717 // 718 // This function is performance critical. If many threads attempt to tag objects 719 // around the same time then it's possible that the Mutex associated with the 720 // tag map will be a hot lock. 721 void JvmtiTagMap::set_tag(jobject object, jlong tag) { 722 MutexLocker ml(lock()); 723 724 // resolve the object 725 oop o = JNIHandles::resolve_non_null(object); 726 727 // see if the object is already tagged 728 JvmtiTagHashmap* hashmap = _hashmap; 729 JvmtiTagHashmapEntry* entry = hashmap->find(o); 730 731 // if the object is not already tagged then we tag it 732 if (entry == NULL) { 733 if (tag != 0) { 734 entry = create_entry(o, tag); 735 hashmap->add(o, entry); 736 } else { 737 // no-op 738 } 739 } else { 740 // if the object is already tagged then we either update 741 // the tag (if a new tag value has been provided) 742 // or remove the object if the new tag value is 0. 743 if (tag == 0) { 744 hashmap->remove(o); 745 destroy_entry(entry); 746 } else { 747 entry->set_tag(tag); 748 } 749 } 750 } 751 752 // get the tag for an object 753 jlong JvmtiTagMap::get_tag(jobject object) { 754 MutexLocker ml(lock()); 755 756 // resolve the object 757 oop o = JNIHandles::resolve_non_null(object); 758 759 return tag_for(this, o); 760 } 761 762 763 // Helper class used to describe the static or instance fields of a class. 764 // For each field it holds the field index (as defined by the JVMTI specification), 765 // the field type, and the offset. 766 767 class ClassFieldDescriptor: public CHeapObj<mtInternal> { 768 private: 769 int _field_index; 770 int _field_offset; 771 char _field_type; 772 public: 773 ClassFieldDescriptor(int index, char type, int offset) : 774 _field_index(index), _field_type(type), _field_offset(offset) { 775 } 776 int field_index() const { return _field_index; } 777 char field_type() const { return _field_type; } 778 int field_offset() const { return _field_offset; } 779 }; 780 781 class ClassFieldMap: public CHeapObj<mtInternal> { 782 private: 783 enum { 784 initial_field_count = 5 785 }; 786 787 // list of field descriptors 788 GrowableArray<ClassFieldDescriptor*>* _fields; 789 790 // constructor 791 ClassFieldMap(); 792 793 // add a field 794 void add(int index, char type, int offset); 795 796 // returns the field count for the given class 797 static int compute_field_count(InstanceKlass* ik); 798 799 public: 800 ~ClassFieldMap(); 801 802 // access 803 int field_count() { return _fields->length(); } 804 ClassFieldDescriptor* field_at(int i) { return _fields->at(i); } 805 806 // functions to create maps of static or instance fields 807 static ClassFieldMap* create_map_of_static_fields(Klass* k); 808 static ClassFieldMap* create_map_of_instance_fields(oop obj); 809 }; 810 811 ClassFieldMap::ClassFieldMap() { 812 _fields = new (ResourceObj::C_HEAP, mtInternal) 813 GrowableArray<ClassFieldDescriptor*>(initial_field_count, true); 814 } 815 816 ClassFieldMap::~ClassFieldMap() { 817 for (int i=0; i<_fields->length(); i++) { 818 delete _fields->at(i); 819 } 820 delete _fields; 821 } 822 823 void ClassFieldMap::add(int index, char type, int offset) { 824 ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset); 825 _fields->append(field); 826 } 827 828 // Returns a heap allocated ClassFieldMap to describe the static fields 829 // of the given class. 830 // 831 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) { 832 HandleMark hm; 833 InstanceKlass* ik = InstanceKlass::cast(k); 834 835 // create the field map 836 ClassFieldMap* field_map = new ClassFieldMap(); 837 838 FilteredFieldStream f(ik, false, false); 839 int max_field_index = f.field_count()-1; 840 841 int index = 0; 842 for (FilteredFieldStream fld(ik, true, true); !fld.eos(); fld.next(), index++) { 843 // ignore instance fields 844 if (!fld.access_flags().is_static()) { 845 continue; 846 } 847 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset()); 848 } 849 return field_map; 850 } 851 852 // Returns a heap allocated ClassFieldMap to describe the instance fields 853 // of the given class. All instance fields are included (this means public 854 // and private fields declared in superclasses and superinterfaces too). 855 // 856 ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) { 857 HandleMark hm; 858 InstanceKlass* ik = InstanceKlass::cast(obj->klass()); 859 860 // create the field map 861 ClassFieldMap* field_map = new ClassFieldMap(); 862 863 FilteredFieldStream f(ik, false, false); 864 865 int max_field_index = f.field_count()-1; 866 867 int index = 0; 868 for (FilteredFieldStream fld(ik, false, false); !fld.eos(); fld.next(), index++) { 869 // ignore static fields 870 if (fld.access_flags().is_static()) { 871 continue; 872 } 873 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset()); 874 } 875 876 return field_map; 877 } 878 879 // Helper class used to cache a ClassFileMap for the instance fields of 880 // a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during 881 // heap iteration and avoid creating a field map for each object in the heap 882 // (only need to create the map when the first instance of a class is encountered). 883 // 884 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> { 885 private: 886 enum { 887 initial_class_count = 200 888 }; 889 ClassFieldMap* _field_map; 890 891 ClassFieldMap* field_map() const { return _field_map; } 892 893 JvmtiCachedClassFieldMap(ClassFieldMap* field_map); 894 ~JvmtiCachedClassFieldMap(); 895 896 static GrowableArray<InstanceKlass*>* _class_list; 897 static void add_to_class_list(InstanceKlass* ik); 898 899 public: 900 // returns the field map for a given object (returning map cached 901 // by InstanceKlass if possible 902 static ClassFieldMap* get_map_of_instance_fields(oop obj); 903 904 // removes the field map from all instanceKlasses - should be 905 // called before VM operation completes 906 static void clear_cache(); 907 908 // returns the number of ClassFieldMap cached by instanceKlasses 909 static int cached_field_map_count(); 910 }; 911 912 GrowableArray<InstanceKlass*>* JvmtiCachedClassFieldMap::_class_list; 913 914 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) { 915 _field_map = field_map; 916 } 917 918 JvmtiCachedClassFieldMap::~JvmtiCachedClassFieldMap() { 919 if (_field_map != NULL) { 920 delete _field_map; 921 } 922 } 923 924 // Marker class to ensure that the class file map cache is only used in a defined 925 // scope. 926 class ClassFieldMapCacheMark : public StackObj { 927 private: 928 static bool _is_active; 929 public: 930 ClassFieldMapCacheMark() { 931 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 932 assert(JvmtiCachedClassFieldMap::cached_field_map_count() == 0, "cache not empty"); 933 assert(!_is_active, "ClassFieldMapCacheMark cannot be nested"); 934 _is_active = true; 935 } 936 ~ClassFieldMapCacheMark() { 937 JvmtiCachedClassFieldMap::clear_cache(); 938 _is_active = false; 939 } 940 static bool is_active() { return _is_active; } 941 }; 942 943 bool ClassFieldMapCacheMark::_is_active; 944 945 946 // record that the given InstanceKlass is caching a field map 947 void JvmtiCachedClassFieldMap::add_to_class_list(InstanceKlass* ik) { 948 if (_class_list == NULL) { 949 _class_list = new (ResourceObj::C_HEAP, mtInternal) 950 GrowableArray<InstanceKlass*>(initial_class_count, true); 951 } 952 _class_list->push(ik); 953 } 954 955 // returns the instance field map for the given object 956 // (returns field map cached by the InstanceKlass if possible) 957 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) { 958 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 959 assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active"); 960 961 Klass* k = obj->klass(); 962 InstanceKlass* ik = InstanceKlass::cast(k); 963 964 // return cached map if possible 965 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); 966 if (cached_map != NULL) { 967 assert(cached_map->field_map() != NULL, "missing field list"); 968 return cached_map->field_map(); 969 } else { 970 ClassFieldMap* field_map = ClassFieldMap::create_map_of_instance_fields(obj); 971 cached_map = new JvmtiCachedClassFieldMap(field_map); 972 ik->set_jvmti_cached_class_field_map(cached_map); 973 add_to_class_list(ik); 974 return field_map; 975 } 976 } 977 978 // remove the fields maps cached from all instanceKlasses 979 void JvmtiCachedClassFieldMap::clear_cache() { 980 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 981 if (_class_list != NULL) { 982 for (int i = 0; i < _class_list->length(); i++) { 983 InstanceKlass* ik = _class_list->at(i); 984 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); 985 assert(cached_map != NULL, "should not be NULL"); 986 ik->set_jvmti_cached_class_field_map(NULL); 987 delete cached_map; // deletes the encapsulated field map 988 } 989 delete _class_list; 990 _class_list = NULL; 991 } 992 } 993 994 // returns the number of ClassFieldMap cached by instanceKlasses 995 int JvmtiCachedClassFieldMap::cached_field_map_count() { 996 return (_class_list == NULL) ? 0 : _class_list->length(); 997 } 998 999 // helper function to indicate if an object is filtered by its tag or class tag 1000 static inline bool is_filtered_by_heap_filter(jlong obj_tag, 1001 jlong klass_tag, 1002 int heap_filter) { 1003 // apply the heap filter 1004 if (obj_tag != 0) { 1005 // filter out tagged objects 1006 if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true; 1007 } else { 1008 // filter out untagged objects 1009 if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true; 1010 } 1011 if (klass_tag != 0) { 1012 // filter out objects with tagged classes 1013 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true; 1014 } else { 1015 // filter out objects with untagged classes. 1016 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true; 1017 } 1018 return false; 1019 } 1020 1021 // helper function to indicate if an object is filtered by a klass filter 1022 static inline bool is_filtered_by_klass_filter(oop obj, Klass* klass_filter) { 1023 if (klass_filter != NULL) { 1024 if (obj->klass() != klass_filter) { 1025 return true; 1026 } 1027 } 1028 return false; 1029 } 1030 1031 // helper function to tell if a field is a primitive field or not 1032 static inline bool is_primitive_field_type(char type) { 1033 return (type != 'L' && type != '['); 1034 } 1035 1036 // helper function to copy the value from location addr to jvalue. 1037 static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) { 1038 switch (value_type) { 1039 case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; } 1040 case JVMTI_PRIMITIVE_TYPE_BYTE : { v->b = *(jbyte*)addr; break; } 1041 case JVMTI_PRIMITIVE_TYPE_CHAR : { v->c = *(jchar*)addr; break; } 1042 case JVMTI_PRIMITIVE_TYPE_SHORT : { v->s = *(jshort*)addr; break; } 1043 case JVMTI_PRIMITIVE_TYPE_INT : { v->i = *(jint*)addr; break; } 1044 case JVMTI_PRIMITIVE_TYPE_LONG : { v->j = *(jlong*)addr; break; } 1045 case JVMTI_PRIMITIVE_TYPE_FLOAT : { v->f = *(jfloat*)addr; break; } 1046 case JVMTI_PRIMITIVE_TYPE_DOUBLE : { v->d = *(jdouble*)addr; break; } 1047 default: ShouldNotReachHere(); 1048 } 1049 } 1050 1051 // helper function to invoke string primitive value callback 1052 // returns visit control flags 1053 static jint invoke_string_value_callback(jvmtiStringPrimitiveValueCallback cb, 1054 CallbackWrapper* wrapper, 1055 oop str, 1056 void* user_data) 1057 { 1058 assert(str->klass() == SystemDictionary::String_klass(), "not a string"); 1059 1060 typeArrayOop s_value = java_lang_String::value(str); 1061 1062 // JDK-6584008: the value field may be null if a String instance is 1063 // partially constructed. 1064 if (s_value == NULL) { 1065 return 0; 1066 } 1067 // get the string value and length 1068 // (string value may be offset from the base) 1069 int s_len = java_lang_String::length(str); 1070 bool is_latin1 = java_lang_String::is_latin1(str); 1071 jchar* value; 1072 if (s_len > 0) { 1073 if (!is_latin1) { 1074 value = s_value->char_at_addr(0); 1075 } else { 1076 // Inflate latin1 encoded string to UTF16 1077 jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len, mtInternal); 1078 for (int i = 0; i < s_len; i++) { 1079 buf[i] = ((jchar) s_value->byte_at(i)) & 0xff; 1080 } 1081 value = &buf[0]; 1082 } 1083 } else { 1084 // Don't use char_at_addr(0) if length is 0 1085 value = (jchar*) s_value->base(T_CHAR); 1086 } 1087 1088 // invoke the callback 1089 jint res = (*cb)(wrapper->klass_tag(), 1090 wrapper->obj_size(), 1091 wrapper->obj_tag_p(), 1092 value, 1093 (jint)s_len, 1094 user_data); 1095 1096 if (is_latin1 && s_len > 0) { 1097 FREE_C_HEAP_ARRAY(jchar, value); 1098 } 1099 return res; 1100 } 1101 1102 // helper function to invoke string primitive value callback 1103 // returns visit control flags 1104 static jint invoke_array_primitive_value_callback(jvmtiArrayPrimitiveValueCallback cb, 1105 CallbackWrapper* wrapper, 1106 oop obj, 1107 void* user_data) 1108 { 1109 assert(obj->is_typeArray(), "not a primitive array"); 1110 1111 // get base address of first element 1112 typeArrayOop array = typeArrayOop(obj); 1113 BasicType type = TypeArrayKlass::cast(array->klass())->element_type(); 1114 void* elements = array->base(type); 1115 1116 // jvmtiPrimitiveType is defined so this mapping is always correct 1117 jvmtiPrimitiveType elem_type = (jvmtiPrimitiveType)type2char(type); 1118 1119 return (*cb)(wrapper->klass_tag(), 1120 wrapper->obj_size(), 1121 wrapper->obj_tag_p(), 1122 (jint)array->length(), 1123 elem_type, 1124 elements, 1125 user_data); 1126 } 1127 1128 // helper function to invoke the primitive field callback for all static fields 1129 // of a given class 1130 static jint invoke_primitive_field_callback_for_static_fields 1131 (CallbackWrapper* wrapper, 1132 oop obj, 1133 jvmtiPrimitiveFieldCallback cb, 1134 void* user_data) 1135 { 1136 // for static fields only the index will be set 1137 static jvmtiHeapReferenceInfo reference_info = { 0 }; 1138 1139 assert(obj->klass() == SystemDictionary::Class_klass(), "not a class"); 1140 if (java_lang_Class::is_primitive(obj)) { 1141 return 0; 1142 } 1143 Klass* klass = java_lang_Class::as_Klass(obj); 1144 1145 // ignore classes for object and type arrays 1146 if (!klass->is_instance_klass()) { 1147 return 0; 1148 } 1149 1150 // ignore classes which aren't linked yet 1151 InstanceKlass* ik = InstanceKlass::cast(klass); 1152 if (!ik->is_linked()) { 1153 return 0; 1154 } 1155 1156 // get the field map 1157 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass); 1158 1159 // invoke the callback for each static primitive field 1160 for (int i=0; i<field_map->field_count(); i++) { 1161 ClassFieldDescriptor* field = field_map->field_at(i); 1162 1163 // ignore non-primitive fields 1164 char type = field->field_type(); 1165 if (!is_primitive_field_type(type)) { 1166 continue; 1167 } 1168 // one-to-one mapping 1169 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 1170 1171 // get offset and field value 1172 int offset = field->field_offset(); 1173 address addr = (address)klass->java_mirror() + offset; 1174 jvalue value; 1175 copy_to_jvalue(&value, addr, value_type); 1176 1177 // field index 1178 reference_info.field.index = field->field_index(); 1179 1180 // invoke the callback 1181 jint res = (*cb)(JVMTI_HEAP_REFERENCE_STATIC_FIELD, 1182 &reference_info, 1183 wrapper->klass_tag(), 1184 wrapper->obj_tag_p(), 1185 value, 1186 value_type, 1187 user_data); 1188 if (res & JVMTI_VISIT_ABORT) { 1189 delete field_map; 1190 return res; 1191 } 1192 } 1193 1194 delete field_map; 1195 return 0; 1196 } 1197 1198 // helper function to invoke the primitive field callback for all instance fields 1199 // of a given object 1200 static jint invoke_primitive_field_callback_for_instance_fields( 1201 CallbackWrapper* wrapper, 1202 oop obj, 1203 jvmtiPrimitiveFieldCallback cb, 1204 void* user_data) 1205 { 1206 // for instance fields only the index will be set 1207 static jvmtiHeapReferenceInfo reference_info = { 0 }; 1208 1209 // get the map of the instance fields 1210 ClassFieldMap* fields = JvmtiCachedClassFieldMap::get_map_of_instance_fields(obj); 1211 1212 // invoke the callback for each instance primitive field 1213 for (int i=0; i<fields->field_count(); i++) { 1214 ClassFieldDescriptor* field = fields->field_at(i); 1215 1216 // ignore non-primitive fields 1217 char type = field->field_type(); 1218 if (!is_primitive_field_type(type)) { 1219 continue; 1220 } 1221 // one-to-one mapping 1222 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 1223 1224 // get offset and field value 1225 int offset = field->field_offset(); 1226 address addr = (address)obj + offset; 1227 jvalue value; 1228 copy_to_jvalue(&value, addr, value_type); 1229 1230 // field index 1231 reference_info.field.index = field->field_index(); 1232 1233 // invoke the callback 1234 jint res = (*cb)(JVMTI_HEAP_REFERENCE_FIELD, 1235 &reference_info, 1236 wrapper->klass_tag(), 1237 wrapper->obj_tag_p(), 1238 value, 1239 value_type, 1240 user_data); 1241 if (res & JVMTI_VISIT_ABORT) { 1242 return res; 1243 } 1244 } 1245 return 0; 1246 } 1247 1248 1249 // VM operation to iterate over all objects in the heap (both reachable 1250 // and unreachable) 1251 class VM_HeapIterateOperation: public VM_Operation { 1252 private: 1253 ObjectClosure* _blk; 1254 public: 1255 VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; } 1256 1257 VMOp_Type type() const { return VMOp_HeapIterateOperation; } 1258 void doit() { 1259 // allows class files maps to be cached during iteration 1260 ClassFieldMapCacheMark cm; 1261 1262 // make sure that heap is parsable (fills TLABs with filler objects) 1263 Universe::heap()->ensure_parsability(false); // no need to retire TLABs 1264 1265 // Verify heap before iteration - if the heap gets corrupted then 1266 // JVMTI's IterateOverHeap will crash. 1267 if (VerifyBeforeIteration) { 1268 Universe::verify(); 1269 } 1270 1271 // do the iteration 1272 // If this operation encounters a bad object when using CMS, 1273 // consider using safe_object_iterate() which avoids perm gen 1274 // objects that may contain bad references. 1275 Universe::heap()->object_iterate(_blk); 1276 } 1277 1278 }; 1279 1280 1281 // An ObjectClosure used to support the deprecated IterateOverHeap and 1282 // IterateOverInstancesOfClass functions 1283 class IterateOverHeapObjectClosure: public ObjectClosure { 1284 private: 1285 JvmtiTagMap* _tag_map; 1286 Klass* _klass; 1287 jvmtiHeapObjectFilter _object_filter; 1288 jvmtiHeapObjectCallback _heap_object_callback; 1289 const void* _user_data; 1290 1291 // accessors 1292 JvmtiTagMap* tag_map() const { return _tag_map; } 1293 jvmtiHeapObjectFilter object_filter() const { return _object_filter; } 1294 jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; } 1295 Klass* klass() const { return _klass; } 1296 const void* user_data() const { return _user_data; } 1297 1298 // indicates if iteration has been aborted 1299 bool _iteration_aborted; 1300 bool is_iteration_aborted() const { return _iteration_aborted; } 1301 void set_iteration_aborted(bool aborted) { _iteration_aborted = aborted; } 1302 1303 public: 1304 IterateOverHeapObjectClosure(JvmtiTagMap* tag_map, 1305 Klass* klass, 1306 jvmtiHeapObjectFilter object_filter, 1307 jvmtiHeapObjectCallback heap_object_callback, 1308 const void* user_data) : 1309 _tag_map(tag_map), 1310 _klass(klass), 1311 _object_filter(object_filter), 1312 _heap_object_callback(heap_object_callback), 1313 _user_data(user_data), 1314 _iteration_aborted(false) 1315 { 1316 } 1317 1318 void do_object(oop o); 1319 }; 1320 1321 // invoked for each object in the heap 1322 void IterateOverHeapObjectClosure::do_object(oop o) { 1323 // check if iteration has been halted 1324 if (is_iteration_aborted()) return; 1325 1326 // instanceof check when filtering by klass 1327 if (klass() != NULL && !o->is_a(klass())) { 1328 return; 1329 } 1330 // prepare for the calllback 1331 CallbackWrapper wrapper(tag_map(), o); 1332 1333 // if the object is tagged and we're only interested in untagged objects 1334 // then don't invoke the callback. Similiarly, if the object is untagged 1335 // and we're only interested in tagged objects we skip the callback. 1336 if (wrapper.obj_tag() != 0) { 1337 if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return; 1338 } else { 1339 if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return; 1340 } 1341 1342 // invoke the agent's callback 1343 jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(), 1344 wrapper.obj_size(), 1345 wrapper.obj_tag_p(), 1346 (void*)user_data()); 1347 if (control == JVMTI_ITERATION_ABORT) { 1348 set_iteration_aborted(true); 1349 } 1350 } 1351 1352 // An ObjectClosure used to support the IterateThroughHeap function 1353 class IterateThroughHeapObjectClosure: public ObjectClosure { 1354 private: 1355 JvmtiTagMap* _tag_map; 1356 Klass* _klass; 1357 int _heap_filter; 1358 const jvmtiHeapCallbacks* _callbacks; 1359 const void* _user_data; 1360 1361 // accessor functions 1362 JvmtiTagMap* tag_map() const { return _tag_map; } 1363 int heap_filter() const { return _heap_filter; } 1364 const jvmtiHeapCallbacks* callbacks() const { return _callbacks; } 1365 Klass* klass() const { return _klass; } 1366 const void* user_data() const { return _user_data; } 1367 1368 // indicates if the iteration has been aborted 1369 bool _iteration_aborted; 1370 bool is_iteration_aborted() const { return _iteration_aborted; } 1371 1372 // used to check the visit control flags. If the abort flag is set 1373 // then we set the iteration aborted flag so that the iteration completes 1374 // without processing any further objects 1375 bool check_flags_for_abort(jint flags) { 1376 bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0; 1377 if (is_abort) { 1378 _iteration_aborted = true; 1379 } 1380 return is_abort; 1381 } 1382 1383 public: 1384 IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map, 1385 Klass* klass, 1386 int heap_filter, 1387 const jvmtiHeapCallbacks* heap_callbacks, 1388 const void* user_data) : 1389 _tag_map(tag_map), 1390 _klass(klass), 1391 _heap_filter(heap_filter), 1392 _callbacks(heap_callbacks), 1393 _user_data(user_data), 1394 _iteration_aborted(false) 1395 { 1396 } 1397 1398 void do_object(oop o); 1399 }; 1400 1401 // invoked for each object in the heap 1402 void IterateThroughHeapObjectClosure::do_object(oop obj) { 1403 // check if iteration has been halted 1404 if (is_iteration_aborted()) return; 1405 1406 // apply class filter 1407 if (is_filtered_by_klass_filter(obj, klass())) return; 1408 1409 // prepare for callback 1410 CallbackWrapper wrapper(tag_map(), obj); 1411 1412 // check if filtered by the heap filter 1413 if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) { 1414 return; 1415 } 1416 1417 // for arrays we need the length, otherwise -1 1418 bool is_array = obj->is_array(); 1419 int len = is_array ? arrayOop(obj)->length() : -1; 1420 1421 // invoke the object callback (if callback is provided) 1422 if (callbacks()->heap_iteration_callback != NULL) { 1423 jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback; 1424 jint res = (*cb)(wrapper.klass_tag(), 1425 wrapper.obj_size(), 1426 wrapper.obj_tag_p(), 1427 (jint)len, 1428 (void*)user_data()); 1429 if (check_flags_for_abort(res)) return; 1430 } 1431 1432 // for objects and classes we report primitive fields if callback provided 1433 if (callbacks()->primitive_field_callback != NULL && obj->is_instance()) { 1434 jint res; 1435 jvmtiPrimitiveFieldCallback cb = callbacks()->primitive_field_callback; 1436 if (obj->klass() == SystemDictionary::Class_klass()) { 1437 res = invoke_primitive_field_callback_for_static_fields(&wrapper, 1438 obj, 1439 cb, 1440 (void*)user_data()); 1441 } else { 1442 res = invoke_primitive_field_callback_for_instance_fields(&wrapper, 1443 obj, 1444 cb, 1445 (void*)user_data()); 1446 } 1447 if (check_flags_for_abort(res)) return; 1448 } 1449 1450 // string callback 1451 if (!is_array && 1452 callbacks()->string_primitive_value_callback != NULL && 1453 obj->klass() == SystemDictionary::String_klass()) { 1454 jint res = invoke_string_value_callback( 1455 callbacks()->string_primitive_value_callback, 1456 &wrapper, 1457 obj, 1458 (void*)user_data() ); 1459 if (check_flags_for_abort(res)) return; 1460 } 1461 1462 // array callback 1463 if (is_array && 1464 callbacks()->array_primitive_value_callback != NULL && 1465 obj->is_typeArray()) { 1466 jint res = invoke_array_primitive_value_callback( 1467 callbacks()->array_primitive_value_callback, 1468 &wrapper, 1469 obj, 1470 (void*)user_data() ); 1471 if (check_flags_for_abort(res)) return; 1472 } 1473 }; 1474 1475 1476 // Deprecated function to iterate over all objects in the heap 1477 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter, 1478 Klass* klass, 1479 jvmtiHeapObjectCallback heap_object_callback, 1480 const void* user_data) 1481 { 1482 MutexLocker ml(Heap_lock); 1483 IterateOverHeapObjectClosure blk(this, 1484 klass, 1485 object_filter, 1486 heap_object_callback, 1487 user_data); 1488 VM_HeapIterateOperation op(&blk); 1489 VMThread::execute(&op); 1490 } 1491 1492 1493 // Iterates over all objects in the heap 1494 void JvmtiTagMap::iterate_through_heap(jint heap_filter, 1495 Klass* klass, 1496 const jvmtiHeapCallbacks* callbacks, 1497 const void* user_data) 1498 { 1499 MutexLocker ml(Heap_lock); 1500 IterateThroughHeapObjectClosure blk(this, 1501 klass, 1502 heap_filter, 1503 callbacks, 1504 user_data); 1505 VM_HeapIterateOperation op(&blk); 1506 VMThread::execute(&op); 1507 } 1508 1509 // support class for get_objects_with_tags 1510 1511 class TagObjectCollector : public JvmtiTagHashmapEntryClosure { 1512 private: 1513 JvmtiEnv* _env; 1514 jlong* _tags; 1515 jint _tag_count; 1516 1517 GrowableArray<jobject>* _object_results; // collected objects (JNI weak refs) 1518 GrowableArray<uint64_t>* _tag_results; // collected tags 1519 1520 public: 1521 TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) { 1522 _env = env; 1523 _tags = (jlong*)tags; 1524 _tag_count = tag_count; 1525 _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true); 1526 _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true); 1527 } 1528 1529 ~TagObjectCollector() { 1530 delete _object_results; 1531 delete _tag_results; 1532 } 1533 1534 // for each tagged object check if the tag value matches 1535 // - if it matches then we create a JNI local reference to the object 1536 // and record the reference and tag value. 1537 // 1538 void do_entry(JvmtiTagHashmapEntry* entry) { 1539 for (int i=0; i<_tag_count; i++) { 1540 if (_tags[i] == entry->tag()) { 1541 // The reference in this tag map could be the only (implicitly weak) 1542 // reference to that object. If we hand it out, we need to keep it live wrt 1543 // SATB marking similar to other j.l.ref.Reference referents. This is 1544 // achieved by using a phantom load in the object() accessor. 1545 oop o = entry->object(); 1546 assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); 1547 jobject ref = JNIHandles::make_local(JavaThread::current(), o); 1548 _object_results->append(ref); 1549 _tag_results->append((uint64_t)entry->tag()); 1550 } 1551 } 1552 } 1553 1554 // return the results from the collection 1555 // 1556 jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { 1557 jvmtiError error; 1558 int count = _object_results->length(); 1559 assert(count >= 0, "sanity check"); 1560 1561 // if object_result_ptr is not NULL then allocate the result and copy 1562 // in the object references. 1563 if (object_result_ptr != NULL) { 1564 error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr); 1565 if (error != JVMTI_ERROR_NONE) { 1566 return error; 1567 } 1568 for (int i=0; i<count; i++) { 1569 (*object_result_ptr)[i] = _object_results->at(i); 1570 } 1571 } 1572 1573 // if tag_result_ptr is not NULL then allocate the result and copy 1574 // in the tag values. 1575 if (tag_result_ptr != NULL) { 1576 error = _env->Allocate(count * sizeof(jlong), (unsigned char**)tag_result_ptr); 1577 if (error != JVMTI_ERROR_NONE) { 1578 if (object_result_ptr != NULL) { 1579 _env->Deallocate((unsigned char*)object_result_ptr); 1580 } 1581 return error; 1582 } 1583 for (int i=0; i<count; i++) { 1584 (*tag_result_ptr)[i] = (jlong)_tag_results->at(i); 1585 } 1586 } 1587 1588 *count_ptr = count; 1589 return JVMTI_ERROR_NONE; 1590 } 1591 }; 1592 1593 // return the list of objects with the specified tags 1594 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags, 1595 jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { 1596 1597 TagObjectCollector collector(env(), tags, count); 1598 { 1599 // iterate over all tagged objects 1600 MutexLocker ml(lock()); 1601 entry_iterate(&collector); 1602 } 1603 return collector.result(count_ptr, object_result_ptr, tag_result_ptr); 1604 } 1605 1606 1607 // ObjectMarker is used to support the marking objects when walking the 1608 // heap. 1609 // 1610 // This implementation uses the existing mark bits in an object for 1611 // marking. Objects that are marked must later have their headers restored. 1612 // As most objects are unlocked and don't have their identity hash computed 1613 // we don't have to save their headers. Instead we save the headers that 1614 // are "interesting". Later when the headers are restored this implementation 1615 // restores all headers to their initial value and then restores the few 1616 // objects that had interesting headers. 1617 // 1618 // Future work: This implementation currently uses growable arrays to save 1619 // the oop and header of interesting objects. As an optimization we could 1620 // use the same technique as the GC and make use of the unused area 1621 // between top() and end(). 1622 // 1623 1624 // An ObjectClosure used to restore the mark bits of an object 1625 class RestoreMarksClosure : public ObjectClosure { 1626 public: 1627 void do_object(oop o) { 1628 if (o != NULL) { 1629 markOop mark = o->mark(); 1630 if (mark->is_marked()) { 1631 o->init_mark(); 1632 } 1633 } 1634 } 1635 }; 1636 1637 // ObjectMarker provides the mark and visited functions 1638 class ObjectMarker : AllStatic { 1639 private: 1640 // saved headers 1641 static GrowableArray<oop>* _saved_oop_stack; 1642 static GrowableArray<markOop>* _saved_mark_stack; 1643 static bool _needs_reset; // do we need to reset mark bits? 1644 1645 public: 1646 static void init(); // initialize 1647 static void done(); // clean-up 1648 1649 static inline void mark(oop o); // mark an object 1650 static inline bool visited(oop o); // check if object has been visited 1651 1652 static inline bool needs_reset() { return _needs_reset; } 1653 static inline void set_needs_reset(bool v) { _needs_reset = v; } 1654 }; 1655 1656 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; 1657 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL; 1658 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default 1659 1660 // initialize ObjectMarker - prepares for object marking 1661 void ObjectMarker::init() { 1662 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 1663 1664 // prepare heap for iteration 1665 Universe::heap()->ensure_parsability(false); // no need to retire TLABs 1666 1667 // create stacks for interesting headers 1668 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true); 1669 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); 1670 1671 if (UseBiasedLocking) { 1672 BiasedLocking::preserve_marks(); 1673 } 1674 } 1675 1676 // Object marking is done so restore object headers 1677 void ObjectMarker::done() { 1678 // iterate over all objects and restore the mark bits to 1679 // their initial value 1680 RestoreMarksClosure blk; 1681 if (needs_reset()) { 1682 Universe::heap()->object_iterate(&blk); 1683 } else { 1684 // We don't need to reset mark bits on this call, but reset the 1685 // flag to the default for the next call. 1686 set_needs_reset(true); 1687 } 1688 1689 // now restore the interesting headers 1690 for (int i = 0; i < _saved_oop_stack->length(); i++) { 1691 oop o = _saved_oop_stack->at(i); 1692 markOop mark = _saved_mark_stack->at(i); 1693 o->set_mark(mark); 1694 } 1695 1696 if (UseBiasedLocking) { 1697 BiasedLocking::restore_marks(); 1698 } 1699 1700 // free the stacks 1701 delete _saved_oop_stack; 1702 delete _saved_mark_stack; 1703 } 1704 1705 // mark an object 1706 inline void ObjectMarker::mark(oop o) { 1707 assert(Universe::heap()->is_in(o), "sanity check"); 1708 assert(!o->mark()->is_marked(), "should only mark an object once"); 1709 1710 // object's mark word 1711 markOop mark = o->mark(); 1712 1713 if (mark->must_be_preserved(o)) { 1714 _saved_mark_stack->push(mark); 1715 _saved_oop_stack->push(o); 1716 } 1717 1718 // mark the object 1719 o->set_mark(markOopDesc::prototype()->set_marked()); 1720 } 1721 1722 // return true if object is marked 1723 inline bool ObjectMarker::visited(oop o) { 1724 return o->mark()->is_marked(); 1725 } 1726 1727 // Stack allocated class to help ensure that ObjectMarker is used 1728 // correctly. Constructor initializes ObjectMarker, destructor calls 1729 // ObjectMarker's done() function to restore object headers. 1730 class ObjectMarkerController : public StackObj { 1731 public: 1732 ObjectMarkerController() { 1733 ObjectMarker::init(); 1734 } 1735 ~ObjectMarkerController() { 1736 ObjectMarker::done(); 1737 } 1738 }; 1739 1740 1741 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind 1742 // (not performance critical as only used for roots) 1743 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) { 1744 switch (kind) { 1745 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL; 1746 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS; 1747 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR; 1748 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL; 1749 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL; 1750 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD; 1751 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER; 1752 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER; 1753 } 1754 } 1755 1756 // Base class for all heap walk contexts. The base class maintains a flag 1757 // to indicate if the context is valid or not. 1758 class HeapWalkContext { 1759 private: 1760 bool _valid; 1761 public: 1762 HeapWalkContext(bool valid) { _valid = valid; } 1763 void invalidate() { _valid = false; } 1764 bool is_valid() const { return _valid; } 1765 }; 1766 1767 // A basic heap walk context for the deprecated heap walking functions. 1768 // The context for a basic heap walk are the callbacks and fields used by 1769 // the referrer caching scheme. 1770 class BasicHeapWalkContext: public HeapWalkContext { 1771 private: 1772 jvmtiHeapRootCallback _heap_root_callback; 1773 jvmtiStackReferenceCallback _stack_ref_callback; 1774 jvmtiObjectReferenceCallback _object_ref_callback; 1775 1776 // used for caching 1777 oop _last_referrer; 1778 jlong _last_referrer_tag; 1779 1780 public: 1781 BasicHeapWalkContext() : HeapWalkContext(false) { } 1782 1783 BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback, 1784 jvmtiStackReferenceCallback stack_ref_callback, 1785 jvmtiObjectReferenceCallback object_ref_callback) : 1786 HeapWalkContext(true), 1787 _heap_root_callback(heap_root_callback), 1788 _stack_ref_callback(stack_ref_callback), 1789 _object_ref_callback(object_ref_callback), 1790 _last_referrer(NULL), 1791 _last_referrer_tag(0) { 1792 } 1793 1794 // accessors 1795 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; } 1796 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; } 1797 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; } 1798 1799 oop last_referrer() const { return _last_referrer; } 1800 void set_last_referrer(oop referrer) { _last_referrer = referrer; } 1801 jlong last_referrer_tag() const { return _last_referrer_tag; } 1802 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; } 1803 }; 1804 1805 // The advanced heap walk context for the FollowReferences functions. 1806 // The context is the callbacks, and the fields used for filtering. 1807 class AdvancedHeapWalkContext: public HeapWalkContext { 1808 private: 1809 jint _heap_filter; 1810 Klass* _klass_filter; 1811 const jvmtiHeapCallbacks* _heap_callbacks; 1812 1813 public: 1814 AdvancedHeapWalkContext() : HeapWalkContext(false) { } 1815 1816 AdvancedHeapWalkContext(jint heap_filter, 1817 Klass* klass_filter, 1818 const jvmtiHeapCallbacks* heap_callbacks) : 1819 HeapWalkContext(true), 1820 _heap_filter(heap_filter), 1821 _klass_filter(klass_filter), 1822 _heap_callbacks(heap_callbacks) { 1823 } 1824 1825 // accessors 1826 jint heap_filter() const { return _heap_filter; } 1827 Klass* klass_filter() const { return _klass_filter; } 1828 1829 const jvmtiHeapReferenceCallback heap_reference_callback() const { 1830 return _heap_callbacks->heap_reference_callback; 1831 }; 1832 const jvmtiPrimitiveFieldCallback primitive_field_callback() const { 1833 return _heap_callbacks->primitive_field_callback; 1834 } 1835 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const { 1836 return _heap_callbacks->array_primitive_value_callback; 1837 } 1838 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const { 1839 return _heap_callbacks->string_primitive_value_callback; 1840 } 1841 }; 1842 1843 // The CallbackInvoker is a class with static functions that the heap walk can call 1844 // into to invoke callbacks. It works in one of two modes. The "basic" mode is 1845 // used for the deprecated IterateOverReachableObjects functions. The "advanced" 1846 // mode is for the newer FollowReferences function which supports a lot of 1847 // additional callbacks. 1848 class CallbackInvoker : AllStatic { 1849 private: 1850 // heap walk styles 1851 enum { basic, advanced }; 1852 static int _heap_walk_type; 1853 static bool is_basic_heap_walk() { return _heap_walk_type == basic; } 1854 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; } 1855 1856 // context for basic style heap walk 1857 static BasicHeapWalkContext _basic_context; 1858 static BasicHeapWalkContext* basic_context() { 1859 assert(_basic_context.is_valid(), "invalid"); 1860 return &_basic_context; 1861 } 1862 1863 // context for advanced style heap walk 1864 static AdvancedHeapWalkContext _advanced_context; 1865 static AdvancedHeapWalkContext* advanced_context() { 1866 assert(_advanced_context.is_valid(), "invalid"); 1867 return &_advanced_context; 1868 } 1869 1870 // context needed for all heap walks 1871 static JvmtiTagMap* _tag_map; 1872 static const void* _user_data; 1873 static GrowableArray<oop>* _visit_stack; 1874 1875 // accessors 1876 static JvmtiTagMap* tag_map() { return _tag_map; } 1877 static const void* user_data() { return _user_data; } 1878 static GrowableArray<oop>* visit_stack() { return _visit_stack; } 1879 1880 // if the object hasn't been visited then push it onto the visit stack 1881 // so that it will be visited later 1882 static inline bool check_for_visit(oop obj) { 1883 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj); 1884 return true; 1885 } 1886 1887 // invoke basic style callbacks 1888 static inline bool invoke_basic_heap_root_callback 1889 (jvmtiHeapRootKind root_kind, oop obj); 1890 static inline bool invoke_basic_stack_ref_callback 1891 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method, 1892 int slot, oop obj); 1893 static inline bool invoke_basic_object_reference_callback 1894 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index); 1895 1896 // invoke advanced style callbacks 1897 static inline bool invoke_advanced_heap_root_callback 1898 (jvmtiHeapReferenceKind ref_kind, oop obj); 1899 static inline bool invoke_advanced_stack_ref_callback 1900 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth, 1901 jmethodID method, jlocation bci, jint slot, oop obj); 1902 static inline bool invoke_advanced_object_reference_callback 1903 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index); 1904 1905 // used to report the value of primitive fields 1906 static inline bool report_primitive_field 1907 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type); 1908 1909 public: 1910 // initialize for basic mode 1911 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map, 1912 GrowableArray<oop>* visit_stack, 1913 const void* user_data, 1914 BasicHeapWalkContext context); 1915 1916 // initialize for advanced mode 1917 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map, 1918 GrowableArray<oop>* visit_stack, 1919 const void* user_data, 1920 AdvancedHeapWalkContext context); 1921 1922 // functions to report roots 1923 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o); 1924 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth, 1925 jmethodID m, oop o); 1926 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth, 1927 jmethodID method, jlocation bci, jint slot, oop o); 1928 1929 // functions to report references 1930 static inline bool report_array_element_reference(oop referrer, oop referree, jint index); 1931 static inline bool report_class_reference(oop referrer, oop referree); 1932 static inline bool report_class_loader_reference(oop referrer, oop referree); 1933 static inline bool report_signers_reference(oop referrer, oop referree); 1934 static inline bool report_protection_domain_reference(oop referrer, oop referree); 1935 static inline bool report_superclass_reference(oop referrer, oop referree); 1936 static inline bool report_interface_reference(oop referrer, oop referree); 1937 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot); 1938 static inline bool report_field_reference(oop referrer, oop referree, jint slot); 1939 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index); 1940 static inline bool report_primitive_array_values(oop array); 1941 static inline bool report_string_value(oop str); 1942 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type); 1943 static inline bool report_primitive_static_field(oop o, jint index, address value, char type); 1944 }; 1945 1946 // statics 1947 int CallbackInvoker::_heap_walk_type; 1948 BasicHeapWalkContext CallbackInvoker::_basic_context; 1949 AdvancedHeapWalkContext CallbackInvoker::_advanced_context; 1950 JvmtiTagMap* CallbackInvoker::_tag_map; 1951 const void* CallbackInvoker::_user_data; 1952 GrowableArray<oop>* CallbackInvoker::_visit_stack; 1953 1954 // initialize for basic heap walk (IterateOverReachableObjects et al) 1955 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map, 1956 GrowableArray<oop>* visit_stack, 1957 const void* user_data, 1958 BasicHeapWalkContext context) { 1959 _tag_map = tag_map; 1960 _visit_stack = visit_stack; 1961 _user_data = user_data; 1962 _basic_context = context; 1963 _advanced_context.invalidate(); // will trigger assertion if used 1964 _heap_walk_type = basic; 1965 } 1966 1967 // initialize for advanced heap walk (FollowReferences) 1968 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map, 1969 GrowableArray<oop>* visit_stack, 1970 const void* user_data, 1971 AdvancedHeapWalkContext context) { 1972 _tag_map = tag_map; 1973 _visit_stack = visit_stack; 1974 _user_data = user_data; 1975 _advanced_context = context; 1976 _basic_context.invalidate(); // will trigger assertion if used 1977 _heap_walk_type = advanced; 1978 } 1979 1980 1981 // invoke basic style heap root callback 1982 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) { 1983 // if we heap roots should be reported 1984 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback(); 1985 if (cb == NULL) { 1986 return check_for_visit(obj); 1987 } 1988 1989 CallbackWrapper wrapper(tag_map(), obj); 1990 jvmtiIterationControl control = (*cb)(root_kind, 1991 wrapper.klass_tag(), 1992 wrapper.obj_size(), 1993 wrapper.obj_tag_p(), 1994 (void*)user_data()); 1995 // push root to visit stack when following references 1996 if (control == JVMTI_ITERATION_CONTINUE && 1997 basic_context()->object_ref_callback() != NULL) { 1998 visit_stack()->push(obj); 1999 } 2000 return control != JVMTI_ITERATION_ABORT; 2001 } 2002 2003 // invoke basic style stack ref callback 2004 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind, 2005 jlong thread_tag, 2006 jint depth, 2007 jmethodID method, 2008 int slot, 2009 oop obj) { 2010 // if we stack refs should be reported 2011 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback(); 2012 if (cb == NULL) { 2013 return check_for_visit(obj); 2014 } 2015 2016 CallbackWrapper wrapper(tag_map(), obj); 2017 jvmtiIterationControl control = (*cb)(root_kind, 2018 wrapper.klass_tag(), 2019 wrapper.obj_size(), 2020 wrapper.obj_tag_p(), 2021 thread_tag, 2022 depth, 2023 method, 2024 slot, 2025 (void*)user_data()); 2026 // push root to visit stack when following references 2027 if (control == JVMTI_ITERATION_CONTINUE && 2028 basic_context()->object_ref_callback() != NULL) { 2029 visit_stack()->push(obj); 2030 } 2031 return control != JVMTI_ITERATION_ABORT; 2032 } 2033 2034 // invoke basic style object reference callback 2035 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind, 2036 oop referrer, 2037 oop referree, 2038 jint index) { 2039 2040 BasicHeapWalkContext* context = basic_context(); 2041 2042 // callback requires the referrer's tag. If it's the same referrer 2043 // as the last call then we use the cached value. 2044 jlong referrer_tag; 2045 if (referrer == context->last_referrer()) { 2046 referrer_tag = context->last_referrer_tag(); 2047 } else { 2048 referrer_tag = tag_for(tag_map(), referrer); 2049 } 2050 2051 // do the callback 2052 CallbackWrapper wrapper(tag_map(), referree); 2053 jvmtiObjectReferenceCallback cb = context->object_ref_callback(); 2054 jvmtiIterationControl control = (*cb)(ref_kind, 2055 wrapper.klass_tag(), 2056 wrapper.obj_size(), 2057 wrapper.obj_tag_p(), 2058 referrer_tag, 2059 index, 2060 (void*)user_data()); 2061 2062 // record referrer and referrer tag. For self-references record the 2063 // tag value from the callback as this might differ from referrer_tag. 2064 context->set_last_referrer(referrer); 2065 if (referrer == referree) { 2066 context->set_last_referrer_tag(*wrapper.obj_tag_p()); 2067 } else { 2068 context->set_last_referrer_tag(referrer_tag); 2069 } 2070 2071 if (control == JVMTI_ITERATION_CONTINUE) { 2072 return check_for_visit(referree); 2073 } else { 2074 return control != JVMTI_ITERATION_ABORT; 2075 } 2076 } 2077 2078 // invoke advanced style heap root callback 2079 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind, 2080 oop obj) { 2081 AdvancedHeapWalkContext* context = advanced_context(); 2082 2083 // check that callback is provided 2084 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2085 if (cb == NULL) { 2086 return check_for_visit(obj); 2087 } 2088 2089 // apply class filter 2090 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2091 return check_for_visit(obj); 2092 } 2093 2094 // setup the callback wrapper 2095 CallbackWrapper wrapper(tag_map(), obj); 2096 2097 // apply tag filter 2098 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2099 wrapper.klass_tag(), 2100 context->heap_filter())) { 2101 return check_for_visit(obj); 2102 } 2103 2104 // for arrays we need the length, otherwise -1 2105 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2106 2107 // invoke the callback 2108 jint res = (*cb)(ref_kind, 2109 NULL, // referrer info 2110 wrapper.klass_tag(), 2111 0, // referrer_class_tag is 0 for heap root 2112 wrapper.obj_size(), 2113 wrapper.obj_tag_p(), 2114 NULL, // referrer_tag_p 2115 len, 2116 (void*)user_data()); 2117 if (res & JVMTI_VISIT_ABORT) { 2118 return false;// referrer class tag 2119 } 2120 if (res & JVMTI_VISIT_OBJECTS) { 2121 check_for_visit(obj); 2122 } 2123 return true; 2124 } 2125 2126 // report a reference from a thread stack to an object 2127 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind, 2128 jlong thread_tag, 2129 jlong tid, 2130 int depth, 2131 jmethodID method, 2132 jlocation bci, 2133 jint slot, 2134 oop obj) { 2135 AdvancedHeapWalkContext* context = advanced_context(); 2136 2137 // check that callback is provider 2138 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2139 if (cb == NULL) { 2140 return check_for_visit(obj); 2141 } 2142 2143 // apply class filter 2144 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2145 return check_for_visit(obj); 2146 } 2147 2148 // setup the callback wrapper 2149 CallbackWrapper wrapper(tag_map(), obj); 2150 2151 // apply tag filter 2152 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2153 wrapper.klass_tag(), 2154 context->heap_filter())) { 2155 return check_for_visit(obj); 2156 } 2157 2158 // setup the referrer info 2159 jvmtiHeapReferenceInfo reference_info; 2160 reference_info.stack_local.thread_tag = thread_tag; 2161 reference_info.stack_local.thread_id = tid; 2162 reference_info.stack_local.depth = depth; 2163 reference_info.stack_local.method = method; 2164 reference_info.stack_local.location = bci; 2165 reference_info.stack_local.slot = slot; 2166 2167 // for arrays we need the length, otherwise -1 2168 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2169 2170 // call into the agent 2171 int res = (*cb)(ref_kind, 2172 &reference_info, 2173 wrapper.klass_tag(), 2174 0, // referrer_class_tag is 0 for heap root (stack) 2175 wrapper.obj_size(), 2176 wrapper.obj_tag_p(), 2177 NULL, // referrer_tag is 0 for root 2178 len, 2179 (void*)user_data()); 2180 2181 if (res & JVMTI_VISIT_ABORT) { 2182 return false; 2183 } 2184 if (res & JVMTI_VISIT_OBJECTS) { 2185 check_for_visit(obj); 2186 } 2187 return true; 2188 } 2189 2190 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback 2191 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed. 2192 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \ 2193 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \ 2194 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \ 2195 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \ 2196 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \ 2197 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL)) 2198 2199 // invoke the object reference callback to report a reference 2200 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind, 2201 oop referrer, 2202 oop obj, 2203 jint index) 2204 { 2205 // field index is only valid field in reference_info 2206 static jvmtiHeapReferenceInfo reference_info = { 0 }; 2207 2208 AdvancedHeapWalkContext* context = advanced_context(); 2209 2210 // check that callback is provider 2211 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2212 if (cb == NULL) { 2213 return check_for_visit(obj); 2214 } 2215 2216 // apply class filter 2217 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2218 return check_for_visit(obj); 2219 } 2220 2221 // setup the callback wrapper 2222 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj); 2223 2224 // apply tag filter 2225 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2226 wrapper.klass_tag(), 2227 context->heap_filter())) { 2228 return check_for_visit(obj); 2229 } 2230 2231 // field index is only valid field in reference_info 2232 reference_info.field.index = index; 2233 2234 // for arrays we need the length, otherwise -1 2235 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2236 2237 // invoke the callback 2238 int res = (*cb)(ref_kind, 2239 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL, 2240 wrapper.klass_tag(), 2241 wrapper.referrer_klass_tag(), 2242 wrapper.obj_size(), 2243 wrapper.obj_tag_p(), 2244 wrapper.referrer_tag_p(), 2245 len, 2246 (void*)user_data()); 2247 2248 if (res & JVMTI_VISIT_ABORT) { 2249 return false; 2250 } 2251 if (res & JVMTI_VISIT_OBJECTS) { 2252 check_for_visit(obj); 2253 } 2254 return true; 2255 } 2256 2257 // report a "simple root" 2258 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) { 2259 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL && 2260 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root"); 2261 2262 if (is_basic_heap_walk()) { 2263 // map to old style root kind 2264 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind); 2265 return invoke_basic_heap_root_callback(root_kind, obj); 2266 } else { 2267 assert(is_advanced_heap_walk(), "wrong heap walk type"); 2268 return invoke_advanced_heap_root_callback(kind, obj); 2269 } 2270 } 2271 2272 2273 // invoke the primitive array values 2274 inline bool CallbackInvoker::report_primitive_array_values(oop obj) { 2275 assert(obj->is_typeArray(), "not a primitive array"); 2276 2277 AdvancedHeapWalkContext* context = advanced_context(); 2278 assert(context->array_primitive_value_callback() != NULL, "no callback"); 2279 2280 // apply class filter 2281 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2282 return true; 2283 } 2284 2285 CallbackWrapper wrapper(tag_map(), obj); 2286 2287 // apply tag filter 2288 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2289 wrapper.klass_tag(), 2290 context->heap_filter())) { 2291 return true; 2292 } 2293 2294 // invoke the callback 2295 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(), 2296 &wrapper, 2297 obj, 2298 (void*)user_data()); 2299 return (!(res & JVMTI_VISIT_ABORT)); 2300 } 2301 2302 // invoke the string value callback 2303 inline bool CallbackInvoker::report_string_value(oop str) { 2304 assert(str->klass() == SystemDictionary::String_klass(), "not a string"); 2305 2306 AdvancedHeapWalkContext* context = advanced_context(); 2307 assert(context->string_primitive_value_callback() != NULL, "no callback"); 2308 2309 // apply class filter 2310 if (is_filtered_by_klass_filter(str, context->klass_filter())) { 2311 return true; 2312 } 2313 2314 CallbackWrapper wrapper(tag_map(), str); 2315 2316 // apply tag filter 2317 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2318 wrapper.klass_tag(), 2319 context->heap_filter())) { 2320 return true; 2321 } 2322 2323 // invoke the callback 2324 int res = invoke_string_value_callback(context->string_primitive_value_callback(), 2325 &wrapper, 2326 str, 2327 (void*)user_data()); 2328 return (!(res & JVMTI_VISIT_ABORT)); 2329 } 2330 2331 // invoke the primitive field callback 2332 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind, 2333 oop obj, 2334 jint index, 2335 address addr, 2336 char type) 2337 { 2338 // for primitive fields only the index will be set 2339 static jvmtiHeapReferenceInfo reference_info = { 0 }; 2340 2341 AdvancedHeapWalkContext* context = advanced_context(); 2342 assert(context->primitive_field_callback() != NULL, "no callback"); 2343 2344 // apply class filter 2345 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2346 return true; 2347 } 2348 2349 CallbackWrapper wrapper(tag_map(), obj); 2350 2351 // apply tag filter 2352 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2353 wrapper.klass_tag(), 2354 context->heap_filter())) { 2355 return true; 2356 } 2357 2358 // the field index in the referrer 2359 reference_info.field.index = index; 2360 2361 // map the type 2362 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 2363 2364 // setup the jvalue 2365 jvalue value; 2366 copy_to_jvalue(&value, addr, value_type); 2367 2368 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback(); 2369 int res = (*cb)(ref_kind, 2370 &reference_info, 2371 wrapper.klass_tag(), 2372 wrapper.obj_tag_p(), 2373 value, 2374 value_type, 2375 (void*)user_data()); 2376 return (!(res & JVMTI_VISIT_ABORT)); 2377 } 2378 2379 2380 // instance field 2381 inline bool CallbackInvoker::report_primitive_instance_field(oop obj, 2382 jint index, 2383 address value, 2384 char type) { 2385 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD, 2386 obj, 2387 index, 2388 value, 2389 type); 2390 } 2391 2392 // static field 2393 inline bool CallbackInvoker::report_primitive_static_field(oop obj, 2394 jint index, 2395 address value, 2396 char type) { 2397 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD, 2398 obj, 2399 index, 2400 value, 2401 type); 2402 } 2403 2404 // report a JNI local (root object) to the profiler 2405 inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) { 2406 if (is_basic_heap_walk()) { 2407 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL, 2408 thread_tag, 2409 depth, 2410 m, 2411 -1, 2412 obj); 2413 } else { 2414 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL, 2415 thread_tag, tid, 2416 depth, 2417 m, 2418 (jlocation)-1, 2419 -1, 2420 obj); 2421 } 2422 } 2423 2424 2425 // report a local (stack reference, root object) 2426 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag, 2427 jlong tid, 2428 jint depth, 2429 jmethodID method, 2430 jlocation bci, 2431 jint slot, 2432 oop obj) { 2433 if (is_basic_heap_walk()) { 2434 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL, 2435 thread_tag, 2436 depth, 2437 method, 2438 slot, 2439 obj); 2440 } else { 2441 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL, 2442 thread_tag, 2443 tid, 2444 depth, 2445 method, 2446 bci, 2447 slot, 2448 obj); 2449 } 2450 } 2451 2452 // report an object referencing a class. 2453 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) { 2454 if (is_basic_heap_walk()) { 2455 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1); 2456 } else { 2457 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1); 2458 } 2459 } 2460 2461 // report a class referencing its class loader. 2462 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) { 2463 if (is_basic_heap_walk()) { 2464 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1); 2465 } else { 2466 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1); 2467 } 2468 } 2469 2470 // report a class referencing its signers. 2471 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) { 2472 if (is_basic_heap_walk()) { 2473 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1); 2474 } else { 2475 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1); 2476 } 2477 } 2478 2479 // report a class referencing its protection domain.. 2480 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) { 2481 if (is_basic_heap_walk()) { 2482 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1); 2483 } else { 2484 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1); 2485 } 2486 } 2487 2488 // report a class referencing its superclass. 2489 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) { 2490 if (is_basic_heap_walk()) { 2491 // Send this to be consistent with past implementation 2492 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1); 2493 } else { 2494 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1); 2495 } 2496 } 2497 2498 // report a class referencing one of its interfaces. 2499 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) { 2500 if (is_basic_heap_walk()) { 2501 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1); 2502 } else { 2503 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1); 2504 } 2505 } 2506 2507 // report a class referencing one of its static fields. 2508 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) { 2509 if (is_basic_heap_walk()) { 2510 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot); 2511 } else { 2512 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot); 2513 } 2514 } 2515 2516 // report an array referencing an element object 2517 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) { 2518 if (is_basic_heap_walk()) { 2519 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index); 2520 } else { 2521 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index); 2522 } 2523 } 2524 2525 // report an object referencing an instance field object 2526 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) { 2527 if (is_basic_heap_walk()) { 2528 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot); 2529 } else { 2530 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot); 2531 } 2532 } 2533 2534 // report an array referencing an element object 2535 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) { 2536 if (is_basic_heap_walk()) { 2537 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index); 2538 } else { 2539 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index); 2540 } 2541 } 2542 2543 // A supporting closure used to process simple roots 2544 class SimpleRootsClosure : public OopClosure { 2545 private: 2546 jvmtiHeapReferenceKind _kind; 2547 bool _continue; 2548 2549 jvmtiHeapReferenceKind root_kind() { return _kind; } 2550 2551 public: 2552 void set_kind(jvmtiHeapReferenceKind kind) { 2553 _kind = kind; 2554 _continue = true; 2555 } 2556 2557 inline bool stopped() { 2558 return !_continue; 2559 } 2560 2561 void do_oop(oop* obj_p) { 2562 // iteration has terminated 2563 if (stopped()) { 2564 return; 2565 } 2566 2567 oop o = *obj_p; 2568 // ignore null 2569 if (o == NULL) { 2570 return; 2571 } 2572 2573 assert(Universe::heap()->is_in_reserved(o), "should be impossible"); 2574 2575 jvmtiHeapReferenceKind kind = root_kind(); 2576 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { 2577 // SystemDictionary::always_strong_oops_do reports the application 2578 // class loader as a root. We want this root to be reported as 2579 // a root kind of "OTHER" rather than "SYSTEM_CLASS". 2580 if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) { 2581 kind = JVMTI_HEAP_REFERENCE_OTHER; 2582 } 2583 } 2584 2585 // invoke the callback 2586 _continue = CallbackInvoker::report_simple_root(kind, o); 2587 2588 } 2589 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } 2590 }; 2591 2592 // A supporting closure used to process JNI locals 2593 class JNILocalRootsClosure : public OopClosure { 2594 private: 2595 jlong _thread_tag; 2596 jlong _tid; 2597 jint _depth; 2598 jmethodID _method; 2599 bool _continue; 2600 public: 2601 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) { 2602 _thread_tag = thread_tag; 2603 _tid = tid; 2604 _depth = depth; 2605 _method = method; 2606 _continue = true; 2607 } 2608 2609 inline bool stopped() { 2610 return !_continue; 2611 } 2612 2613 void do_oop(oop* obj_p) { 2614 // iteration has terminated 2615 if (stopped()) { 2616 return; 2617 } 2618 2619 oop o = *obj_p; 2620 // ignore null 2621 if (o == NULL) { 2622 return; 2623 } 2624 2625 // invoke the callback 2626 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o); 2627 } 2628 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } 2629 }; 2630 2631 2632 // A VM operation to iterate over objects that are reachable from 2633 // a set of roots or an initial object. 2634 // 2635 // For VM_HeapWalkOperation the set of roots used is :- 2636 // 2637 // - All JNI global references 2638 // - All inflated monitors 2639 // - All classes loaded by the boot class loader (or all classes 2640 // in the event that class unloading is disabled) 2641 // - All java threads 2642 // - For each java thread then all locals and JNI local references 2643 // on the thread's execution stack 2644 // - All visible/explainable objects from Universes::oops_do 2645 // 2646 class VM_HeapWalkOperation: public VM_Operation { 2647 private: 2648 enum { 2649 initial_visit_stack_size = 4000 2650 }; 2651 2652 bool _is_advanced_heap_walk; // indicates FollowReferences 2653 JvmtiTagMap* _tag_map; 2654 Handle _initial_object; 2655 GrowableArray<oop>* _visit_stack; // the visit stack 2656 2657 bool _collecting_heap_roots; // are we collecting roots 2658 bool _following_object_refs; // are we following object references 2659 2660 bool _reporting_primitive_fields; // optional reporting 2661 bool _reporting_primitive_array_values; 2662 bool _reporting_string_values; 2663 2664 GrowableArray<oop>* create_visit_stack() { 2665 return new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(initial_visit_stack_size, true); 2666 } 2667 2668 // accessors 2669 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; } 2670 JvmtiTagMap* tag_map() const { return _tag_map; } 2671 Handle initial_object() const { return _initial_object; } 2672 2673 bool is_following_references() const { return _following_object_refs; } 2674 2675 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; } 2676 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; } 2677 bool is_reporting_string_values() const { return _reporting_string_values; } 2678 2679 GrowableArray<oop>* visit_stack() const { return _visit_stack; } 2680 2681 // iterate over the various object types 2682 inline bool iterate_over_array(oop o); 2683 inline bool iterate_over_type_array(oop o); 2684 inline bool iterate_over_class(oop o); 2685 inline bool iterate_over_object(oop o); 2686 2687 // root collection 2688 inline bool collect_simple_roots(); 2689 inline bool collect_stack_roots(); 2690 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk); 2691 2692 // visit an object 2693 inline bool visit(oop o); 2694 2695 public: 2696 VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2697 Handle initial_object, 2698 BasicHeapWalkContext callbacks, 2699 const void* user_data); 2700 2701 VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2702 Handle initial_object, 2703 AdvancedHeapWalkContext callbacks, 2704 const void* user_data); 2705 2706 ~VM_HeapWalkOperation(); 2707 2708 VMOp_Type type() const { return VMOp_HeapWalkOperation; } 2709 void doit(); 2710 }; 2711 2712 2713 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2714 Handle initial_object, 2715 BasicHeapWalkContext callbacks, 2716 const void* user_data) { 2717 _is_advanced_heap_walk = false; 2718 _tag_map = tag_map; 2719 _initial_object = initial_object; 2720 _following_object_refs = (callbacks.object_ref_callback() != NULL); 2721 _reporting_primitive_fields = false; 2722 _reporting_primitive_array_values = false; 2723 _reporting_string_values = false; 2724 _visit_stack = create_visit_stack(); 2725 2726 2727 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks); 2728 } 2729 2730 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2731 Handle initial_object, 2732 AdvancedHeapWalkContext callbacks, 2733 const void* user_data) { 2734 _is_advanced_heap_walk = true; 2735 _tag_map = tag_map; 2736 _initial_object = initial_object; 2737 _following_object_refs = true; 2738 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);; 2739 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);; 2740 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);; 2741 _visit_stack = create_visit_stack(); 2742 2743 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks); 2744 } 2745 2746 VM_HeapWalkOperation::~VM_HeapWalkOperation() { 2747 if (_following_object_refs) { 2748 assert(_visit_stack != NULL, "checking"); 2749 delete _visit_stack; 2750 _visit_stack = NULL; 2751 } 2752 } 2753 2754 // an array references its class and has a reference to 2755 // each element in the array 2756 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) { 2757 objArrayOop array = objArrayOop(o); 2758 2759 // array reference to its class 2760 oop mirror = ObjArrayKlass::cast(array->klass())->java_mirror(); 2761 if (!CallbackInvoker::report_class_reference(o, mirror)) { 2762 return false; 2763 } 2764 2765 // iterate over the array and report each reference to a 2766 // non-null element 2767 for (int index=0; index<array->length(); index++) { 2768 oop elem = array->obj_at(index); 2769 if (elem == NULL) { 2770 continue; 2771 } 2772 2773 // report the array reference o[index] = elem 2774 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) { 2775 return false; 2776 } 2777 } 2778 return true; 2779 } 2780 2781 // a type array references its class 2782 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) { 2783 Klass* k = o->klass(); 2784 oop mirror = k->java_mirror(); 2785 if (!CallbackInvoker::report_class_reference(o, mirror)) { 2786 return false; 2787 } 2788 2789 // report the array contents if required 2790 if (is_reporting_primitive_array_values()) { 2791 if (!CallbackInvoker::report_primitive_array_values(o)) { 2792 return false; 2793 } 2794 } 2795 return true; 2796 } 2797 2798 #ifdef ASSERT 2799 // verify that a static oop field is in range 2800 static inline bool verify_static_oop(InstanceKlass* ik, 2801 oop mirror, int offset) { 2802 address obj_p = (address)mirror + offset; 2803 address start = (address)InstanceMirrorKlass::start_of_static_fields(mirror); 2804 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize); 2805 assert(end >= start, "sanity check"); 2806 2807 if (obj_p >= start && obj_p < end) { 2808 return true; 2809 } else { 2810 return false; 2811 } 2812 } 2813 #endif // #ifdef ASSERT 2814 2815 // a class references its super class, interfaces, class loader, ... 2816 // and finally its static fields 2817 inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) { 2818 int i; 2819 Klass* klass = java_lang_Class::as_Klass(java_class); 2820 2821 if (klass->is_instance_klass()) { 2822 InstanceKlass* ik = InstanceKlass::cast(klass); 2823 2824 // Ignore the class if it hasn't been initialized yet 2825 if (!ik->is_linked()) { 2826 return true; 2827 } 2828 2829 // get the java mirror 2830 oop mirror = klass->java_mirror(); 2831 2832 // super (only if something more interesting than java.lang.Object) 2833 Klass* java_super = ik->java_super(); 2834 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) { 2835 oop super = java_super->java_mirror(); 2836 if (!CallbackInvoker::report_superclass_reference(mirror, super)) { 2837 return false; 2838 } 2839 } 2840 2841 // class loader 2842 oop cl = ik->class_loader(); 2843 if (cl != NULL) { 2844 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) { 2845 return false; 2846 } 2847 } 2848 2849 // protection domain 2850 oop pd = ik->protection_domain(); 2851 if (pd != NULL) { 2852 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) { 2853 return false; 2854 } 2855 } 2856 2857 // signers 2858 oop signers = ik->signers(); 2859 if (signers != NULL) { 2860 if (!CallbackInvoker::report_signers_reference(mirror, signers)) { 2861 return false; 2862 } 2863 } 2864 2865 // references from the constant pool 2866 { 2867 ConstantPool* pool = ik->constants(); 2868 for (int i = 1; i < pool->length(); i++) { 2869 constantTag tag = pool->tag_at(i).value(); 2870 if (tag.is_string() || tag.is_klass()) { 2871 oop entry; 2872 if (tag.is_string()) { 2873 entry = pool->resolved_string_at(i); 2874 // If the entry is non-null it is resolved. 2875 if (entry == NULL) continue; 2876 } else { 2877 entry = pool->resolved_klass_at(i)->java_mirror(); 2878 } 2879 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) { 2880 return false; 2881 } 2882 } 2883 } 2884 } 2885 2886 // interfaces 2887 // (These will already have been reported as references from the constant pool 2888 // but are specified by IterateOverReachableObjects and must be reported). 2889 Array<Klass*>* interfaces = ik->local_interfaces(); 2890 for (i = 0; i < interfaces->length(); i++) { 2891 oop interf = ((Klass*)interfaces->at(i))->java_mirror(); 2892 if (interf == NULL) { 2893 continue; 2894 } 2895 if (!CallbackInvoker::report_interface_reference(mirror, interf)) { 2896 return false; 2897 } 2898 } 2899 2900 // iterate over the static fields 2901 2902 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass); 2903 for (i=0; i<field_map->field_count(); i++) { 2904 ClassFieldDescriptor* field = field_map->field_at(i); 2905 char type = field->field_type(); 2906 if (!is_primitive_field_type(type)) { 2907 oop fld_o = mirror->obj_field(field->field_offset()); 2908 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check"); 2909 if (fld_o != NULL) { 2910 int slot = field->field_index(); 2911 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) { 2912 delete field_map; 2913 return false; 2914 } 2915 } 2916 } else { 2917 if (is_reporting_primitive_fields()) { 2918 address addr = (address)mirror + field->field_offset(); 2919 int slot = field->field_index(); 2920 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) { 2921 delete field_map; 2922 return false; 2923 } 2924 } 2925 } 2926 } 2927 delete field_map; 2928 2929 return true; 2930 } 2931 2932 return true; 2933 } 2934 2935 // an object references a class and its instance fields 2936 // (static fields are ignored here as we report these as 2937 // references from the class). 2938 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) { 2939 // reference to the class 2940 if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) { 2941 return false; 2942 } 2943 2944 // iterate over instance fields 2945 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o); 2946 for (int i=0; i<field_map->field_count(); i++) { 2947 ClassFieldDescriptor* field = field_map->field_at(i); 2948 char type = field->field_type(); 2949 if (!is_primitive_field_type(type)) { 2950 oop fld_o = o->obj_field(field->field_offset()); 2951 // ignore any objects that aren't visible to profiler 2952 if (fld_o != NULL) { 2953 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not " 2954 "have references to Klass* anymore"); 2955 int slot = field->field_index(); 2956 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { 2957 return false; 2958 } 2959 } 2960 } else { 2961 if (is_reporting_primitive_fields()) { 2962 // primitive instance field 2963 address addr = (address)o + field->field_offset(); 2964 int slot = field->field_index(); 2965 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) { 2966 return false; 2967 } 2968 } 2969 } 2970 } 2971 2972 // if the object is a java.lang.String 2973 if (is_reporting_string_values() && 2974 o->klass() == SystemDictionary::String_klass()) { 2975 if (!CallbackInvoker::report_string_value(o)) { 2976 return false; 2977 } 2978 } 2979 return true; 2980 } 2981 2982 2983 // Collects all simple (non-stack) roots except for threads; 2984 // threads are handled in collect_stack_roots() as an optimization. 2985 // if there's a heap root callback provided then the callback is 2986 // invoked for each simple root. 2987 // if an object reference callback is provided then all simple 2988 // roots are pushed onto the marking stack so that they can be 2989 // processed later 2990 // 2991 inline bool VM_HeapWalkOperation::collect_simple_roots() { 2992 SimpleRootsClosure blk; 2993 2994 // JNI globals 2995 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL); 2996 JNIHandles::oops_do(&blk); 2997 if (blk.stopped()) { 2998 return false; 2999 } 3000 3001 // Preloaded classes and loader from the system dictionary 3002 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS); 3003 SystemDictionary::always_strong_oops_do(&blk); 3004 ClassLoaderDataGraph::always_strong_oops_do(&blk, false); 3005 if (blk.stopped()) { 3006 return false; 3007 } 3008 3009 // Inflated monitors 3010 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR); 3011 ObjectSynchronizer::oops_do(&blk); 3012 if (blk.stopped()) { 3013 return false; 3014 } 3015 3016 // threads are now handled in collect_stack_roots() 3017 3018 // Other kinds of roots maintained by HotSpot 3019 // Many of these won't be visible but others (such as instances of important 3020 // exceptions) will be visible. 3021 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); 3022 Universe::oops_do(&blk); 3023 3024 // If there are any non-perm roots in the code cache, visit them. 3025 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); 3026 CodeBlobToOopClosure look_in_blobs(&blk, !CodeBlobToOopClosure::FixRelocations); 3027 CodeCache::scavenge_root_nmethods_do(&look_in_blobs); 3028 3029 return true; 3030 } 3031 3032 // Walk the stack of a given thread and find all references (locals 3033 // and JNI calls) and report these as stack references 3034 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread, 3035 JNILocalRootsClosure* blk) 3036 { 3037 oop threadObj = java_thread->threadObj(); 3038 assert(threadObj != NULL, "sanity check"); 3039 3040 // only need to get the thread's tag once per thread 3041 jlong thread_tag = tag_for(_tag_map, threadObj); 3042 3043 // also need the thread id 3044 jlong tid = java_lang_Thread::thread_id(threadObj); 3045 3046 3047 if (java_thread->has_last_Java_frame()) { 3048 3049 // vframes are resource allocated 3050 Thread* current_thread = Thread::current(); 3051 ResourceMark rm(current_thread); 3052 HandleMark hm(current_thread); 3053 3054 RegisterMap reg_map(java_thread); 3055 frame f = java_thread->last_frame(); 3056 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread); 3057 3058 bool is_top_frame = true; 3059 int depth = 0; 3060 frame* last_entry_frame = NULL; 3061 3062 while (vf != NULL) { 3063 if (vf->is_java_frame()) { 3064 3065 // java frame (interpreted, compiled, ...) 3066 javaVFrame *jvf = javaVFrame::cast(vf); 3067 3068 // the jmethodID 3069 jmethodID method = jvf->method()->jmethod_id(); 3070 3071 if (!(jvf->method()->is_native())) { 3072 jlocation bci = (jlocation)jvf->bci(); 3073 StackValueCollection* locals = jvf->locals(); 3074 for (int slot=0; slot<locals->size(); slot++) { 3075 if (locals->at(slot)->type() == T_OBJECT) { 3076 oop o = locals->obj_at(slot)(); 3077 if (o == NULL) { 3078 continue; 3079 } 3080 3081 // stack reference 3082 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method, 3083 bci, slot, o)) { 3084 return false; 3085 } 3086 } 3087 } 3088 3089 StackValueCollection* exprs = jvf->expressions(); 3090 for (int index=0; index < exprs->size(); index++) { 3091 if (exprs->at(index)->type() == T_OBJECT) { 3092 oop o = exprs->obj_at(index)(); 3093 if (o == NULL) { 3094 continue; 3095 } 3096 3097 // stack reference 3098 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method, 3099 bci, locals->size() + index, o)) { 3100 return false; 3101 } 3102 } 3103 } 3104 3105 // Follow oops from compiled nmethod 3106 if (jvf->cb() != NULL && jvf->cb()->is_nmethod()) { 3107 blk->set_context(thread_tag, tid, depth, method); 3108 jvf->cb()->as_nmethod()->oops_do(blk); 3109 } 3110 } else { 3111 blk->set_context(thread_tag, tid, depth, method); 3112 if (is_top_frame) { 3113 // JNI locals for the top frame. 3114 java_thread->active_handles()->oops_do(blk); 3115 } else { 3116 if (last_entry_frame != NULL) { 3117 // JNI locals for the entry frame 3118 assert(last_entry_frame->is_entry_frame(), "checking"); 3119 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk); 3120 } 3121 } 3122 } 3123 last_entry_frame = NULL; 3124 depth++; 3125 } else { 3126 // externalVFrame - for an entry frame then we report the JNI locals 3127 // when we find the corresponding javaVFrame 3128 frame* fr = vf->frame_pointer(); 3129 assert(fr != NULL, "sanity check"); 3130 if (fr->is_entry_frame()) { 3131 last_entry_frame = fr; 3132 } 3133 } 3134 3135 vf = vf->sender(); 3136 is_top_frame = false; 3137 } 3138 } else { 3139 // no last java frame but there may be JNI locals 3140 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL); 3141 java_thread->active_handles()->oops_do(blk); 3142 } 3143 return true; 3144 } 3145 3146 3147 // Collects the simple roots for all threads and collects all 3148 // stack roots - for each thread it walks the execution 3149 // stack to find all references and local JNI refs. 3150 inline bool VM_HeapWalkOperation::collect_stack_roots() { 3151 JNILocalRootsClosure blk; 3152 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) { 3153 oop threadObj = thread->threadObj(); 3154 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 3155 // Collect the simple root for this thread before we 3156 // collect its stack roots 3157 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, 3158 threadObj)) { 3159 return false; 3160 } 3161 if (!collect_stack_roots(thread, &blk)) { 3162 return false; 3163 } 3164 } 3165 } 3166 return true; 3167 } 3168 3169 // visit an object 3170 // first mark the object as visited 3171 // second get all the outbound references from this object (in other words, all 3172 // the objects referenced by this object). 3173 // 3174 bool VM_HeapWalkOperation::visit(oop o) { 3175 // mark object as visited 3176 assert(!ObjectMarker::visited(o), "can't visit same object more than once"); 3177 ObjectMarker::mark(o); 3178 3179 // instance 3180 if (o->is_instance()) { 3181 if (o->klass() == SystemDictionary::Class_klass()) { 3182 if (!java_lang_Class::is_primitive(o)) { 3183 // a java.lang.Class 3184 return iterate_over_class(o); 3185 } 3186 } else { 3187 return iterate_over_object(o); 3188 } 3189 } 3190 3191 // object array 3192 if (o->is_objArray()) { 3193 return iterate_over_array(o); 3194 } 3195 3196 // type array 3197 if (o->is_typeArray()) { 3198 return iterate_over_type_array(o); 3199 } 3200 3201 return true; 3202 } 3203 3204 void VM_HeapWalkOperation::doit() { 3205 ResourceMark rm; 3206 ObjectMarkerController marker; 3207 ClassFieldMapCacheMark cm; 3208 3209 assert(visit_stack()->is_empty(), "visit stack must be empty"); 3210 3211 // the heap walk starts with an initial object or the heap roots 3212 if (initial_object().is_null()) { 3213 // If either collect_stack_roots() or collect_simple_roots() 3214 // returns false at this point, then there are no mark bits 3215 // to reset. 3216 ObjectMarker::set_needs_reset(false); 3217 3218 // Calling collect_stack_roots() before collect_simple_roots() 3219 // can result in a big performance boost for an agent that is 3220 // focused on analyzing references in the thread stacks. 3221 if (!collect_stack_roots()) return; 3222 3223 if (!collect_simple_roots()) return; 3224 3225 // no early return so enable heap traversal to reset the mark bits 3226 ObjectMarker::set_needs_reset(true); 3227 } else { 3228 visit_stack()->push(initial_object()()); 3229 } 3230 3231 // object references required 3232 if (is_following_references()) { 3233 3234 // visit each object until all reachable objects have been 3235 // visited or the callback asked to terminate the iteration. 3236 while (!visit_stack()->is_empty()) { 3237 oop o = visit_stack()->pop(); 3238 if (!ObjectMarker::visited(o)) { 3239 if (!visit(o)) { 3240 break; 3241 } 3242 } 3243 } 3244 } 3245 } 3246 3247 // iterate over all objects that are reachable from a set of roots 3248 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback, 3249 jvmtiStackReferenceCallback stack_ref_callback, 3250 jvmtiObjectReferenceCallback object_ref_callback, 3251 const void* user_data) { 3252 MutexLocker ml(Heap_lock); 3253 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback); 3254 VM_HeapWalkOperation op(this, Handle(), context, user_data); 3255 VMThread::execute(&op); 3256 } 3257 3258 // iterate over all objects that are reachable from a given object 3259 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object, 3260 jvmtiObjectReferenceCallback object_ref_callback, 3261 const void* user_data) { 3262 oop obj = JNIHandles::resolve(object); 3263 Handle initial_object(Thread::current(), obj); 3264 3265 MutexLocker ml(Heap_lock); 3266 BasicHeapWalkContext context(NULL, NULL, object_ref_callback); 3267 VM_HeapWalkOperation op(this, initial_object, context, user_data); 3268 VMThread::execute(&op); 3269 } 3270 3271 // follow references from an initial object or the GC roots 3272 void JvmtiTagMap::follow_references(jint heap_filter, 3273 Klass* klass, 3274 jobject object, 3275 const jvmtiHeapCallbacks* callbacks, 3276 const void* user_data) 3277 { 3278 oop obj = JNIHandles::resolve(object); 3279 Handle initial_object(Thread::current(), obj); 3280 3281 MutexLocker ml(Heap_lock); 3282 AdvancedHeapWalkContext context(heap_filter, klass, callbacks); 3283 VM_HeapWalkOperation op(this, initial_object, context, user_data); 3284 VMThread::execute(&op); 3285 } 3286 3287 3288 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 3289 // No locks during VM bring-up (0 threads) and no safepoints after main 3290 // thread creation and before VMThread creation (1 thread); initial GC 3291 // verification can happen in that window which gets to here. 3292 assert(Threads::number_of_threads() <= 1 || 3293 SafepointSynchronize::is_at_safepoint(), 3294 "must be executed at a safepoint"); 3295 if (JvmtiEnv::environments_might_exist()) { 3296 JvmtiEnvIterator it; 3297 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { 3298 JvmtiTagMap* tag_map = env->tag_map(); 3299 if (tag_map != NULL && !tag_map->is_empty()) { 3300 tag_map->do_weak_oops(is_alive, f); 3301 } 3302 } 3303 } 3304 } 3305 3306 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) { 3307 3308 // does this environment have the OBJECT_FREE event enabled 3309 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE); 3310 3311 // counters used for trace message 3312 int freed = 0; 3313 int moved = 0; 3314 3315 JvmtiTagHashmap* hashmap = this->hashmap(); 3316 3317 // reenable sizing (if disabled) 3318 hashmap->set_resizing_enabled(true); 3319 3320 // if the hashmap is empty then we can skip it 3321 if (hashmap->_entry_count == 0) { 3322 return; 3323 } 3324 3325 // now iterate through each entry in the table 3326 3327 JvmtiTagHashmapEntry** table = hashmap->table(); 3328 int size = hashmap->size(); 3329 3330 JvmtiTagHashmapEntry* delayed_add = NULL; 3331 3332 for (int pos = 0; pos < size; ++pos) { 3333 JvmtiTagHashmapEntry* entry = table[pos]; 3334 JvmtiTagHashmapEntry* prev = NULL; 3335 3336 while (entry != NULL) { 3337 JvmtiTagHashmapEntry* next = entry->next(); 3338 3339 // has object been GC'ed 3340 if (!is_alive->do_object_b(entry->object_peek())) { 3341 // grab the tag 3342 jlong tag = entry->tag(); 3343 guarantee(tag != 0, "checking"); 3344 3345 // remove GC'ed entry from hashmap and return the 3346 // entry to the free list 3347 hashmap->remove(prev, pos, entry); 3348 destroy_entry(entry); 3349 3350 // post the event to the profiler 3351 if (post_object_free) { 3352 JvmtiExport::post_object_free(env(), tag); 3353 } 3354 3355 ++freed; 3356 } else { 3357 f->do_oop(entry->object_addr()); 3358 oop new_oop = entry->object_peek(); 3359 3360 // if the object has moved then re-hash it and move its 3361 // entry to its new location. 3362 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size); 3363 if (new_pos != (unsigned int)pos) { 3364 if (prev == NULL) { 3365 table[pos] = next; 3366 } else { 3367 prev->set_next(next); 3368 } 3369 if (new_pos < (unsigned int)pos) { 3370 entry->set_next(table[new_pos]); 3371 table[new_pos] = entry; 3372 } else { 3373 // Delay adding this entry to it's new position as we'd end up 3374 // hitting it again during this iteration. 3375 entry->set_next(delayed_add); 3376 delayed_add = entry; 3377 } 3378 moved++; 3379 } else { 3380 // object didn't move 3381 prev = entry; 3382 } 3383 } 3384 3385 entry = next; 3386 } 3387 } 3388 3389 // Re-add all the entries which were kept aside 3390 while (delayed_add != NULL) { 3391 JvmtiTagHashmapEntry* next = delayed_add->next(); 3392 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object_peek(), size); 3393 delayed_add->set_next(table[pos]); 3394 table[pos] = delayed_add; 3395 delayed_add = next; 3396 } 3397 3398 log_debug(jvmti, objecttagging)("(%d->%d, %d freed, %d total moves)", 3399 hashmap->_entry_count + freed, hashmap->_entry_count, freed, moved); 3400 }