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