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