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