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