1 /* 2 * Copyright (c) 2003, 2011, 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 { 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 { 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); 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); 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 = _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 { 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 { 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) GrowableArray<ClassFieldDescriptor*>(initial_field_count, true); 825 } 826 827 ClassFieldMap::~ClassFieldMap() { 828 for (int i=0; i<_fields->length(); i++) { 829 delete _fields->at(i); 830 } 831 delete _fields; 832 } 833 834 void ClassFieldMap::add(int index, char type, int offset) { 835 ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset); 836 _fields->append(field); 837 } 838 839 // Returns a heap allocated ClassFieldMap to describe the static fields 840 // of the given class. 841 // 842 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(klassOop k) { 843 HandleMark hm; 844 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k); 845 846 // create the field map 847 ClassFieldMap* field_map = new ClassFieldMap(); 848 849 FilteredFieldStream f(ikh, false, false); 850 int max_field_index = f.field_count()-1; 851 852 int index = 0; 853 for (FilteredFieldStream fld(ikh, true, true); !fld.eos(); fld.next(), index++) { 854 // ignore instance fields 855 if (!fld.access_flags().is_static()) { 856 continue; 857 } 858 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset()); 859 } 860 return field_map; 861 } 862 863 // Returns a heap allocated ClassFieldMap to describe the instance fields 864 // of the given class. All instance fields are included (this means public 865 // and private fields declared in superclasses and superinterfaces too). 866 // 867 ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) { 868 HandleMark hm; 869 instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), obj->klass()); 870 871 // create the field map 872 ClassFieldMap* field_map = new ClassFieldMap(); 873 874 FilteredFieldStream f(ikh, false, false); 875 876 int max_field_index = f.field_count()-1; 877 878 int index = 0; 879 for (FilteredFieldStream fld(ikh, false, false); !fld.eos(); fld.next(), index++) { 880 // ignore static fields 881 if (fld.access_flags().is_static()) { 882 continue; 883 } 884 field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset()); 885 } 886 887 return field_map; 888 } 889 890 // Helper class used to cache a ClassFileMap for the instance fields of 891 // a cache. A JvmtiCachedClassFieldMap can be cached by an instanceKlass during 892 // heap iteration and avoid creating a field map for each object in the heap 893 // (only need to create the map when the first instance of a class is encountered). 894 // 895 class JvmtiCachedClassFieldMap : public CHeapObj { 896 private: 897 enum { 898 initial_class_count = 200 899 }; 900 ClassFieldMap* _field_map; 901 902 ClassFieldMap* field_map() const { return _field_map; } 903 904 JvmtiCachedClassFieldMap(ClassFieldMap* field_map); 905 ~JvmtiCachedClassFieldMap(); 906 907 static GrowableArray<instanceKlass*>* _class_list; 908 static void add_to_class_list(instanceKlass* ik); 909 910 public: 911 // returns the field map for a given object (returning map cached 912 // by instanceKlass if possible 913 static ClassFieldMap* get_map_of_instance_fields(oop obj); 914 915 // removes the field map from all instanceKlasses - should be 916 // called before VM operation completes 917 static void clear_cache(); 918 919 // returns the number of ClassFieldMap cached by instanceKlasses 920 static int cached_field_map_count(); 921 }; 922 923 GrowableArray<instanceKlass*>* JvmtiCachedClassFieldMap::_class_list; 924 925 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) { 926 _field_map = field_map; 927 } 928 929 JvmtiCachedClassFieldMap::~JvmtiCachedClassFieldMap() { 930 if (_field_map != NULL) { 931 delete _field_map; 932 } 933 } 934 935 // Marker class to ensure that the class file map cache is only used in a defined 936 // scope. 937 class ClassFieldMapCacheMark : public StackObj { 938 private: 939 static bool _is_active; 940 public: 941 ClassFieldMapCacheMark() { 942 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 943 assert(JvmtiCachedClassFieldMap::cached_field_map_count() == 0, "cache not empty"); 944 assert(!_is_active, "ClassFieldMapCacheMark cannot be nested"); 945 _is_active = true; 946 } 947 ~ClassFieldMapCacheMark() { 948 JvmtiCachedClassFieldMap::clear_cache(); 949 _is_active = false; 950 } 951 static bool is_active() { return _is_active; } 952 }; 953 954 bool ClassFieldMapCacheMark::_is_active; 955 956 957 // record that the given instanceKlass is caching a field map 958 void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) { 959 if (_class_list == NULL) { 960 _class_list = new (ResourceObj::C_HEAP) GrowableArray<instanceKlass*>(initial_class_count, true); 961 } 962 _class_list->push(ik); 963 } 964 965 // returns the instance field map for the given object 966 // (returns field map cached by the instanceKlass if possible) 967 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) { 968 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 969 assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active"); 970 971 klassOop k = obj->klass(); 972 instanceKlass* ik = instanceKlass::cast(k); 973 974 // return cached map if possible 975 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); 976 if (cached_map != NULL) { 977 assert(cached_map->field_map() != NULL, "missing field list"); 978 return cached_map->field_map(); 979 } else { 980 ClassFieldMap* field_map = ClassFieldMap::create_map_of_instance_fields(obj); 981 cached_map = new JvmtiCachedClassFieldMap(field_map); 982 ik->set_jvmti_cached_class_field_map(cached_map); 983 add_to_class_list(ik); 984 return field_map; 985 } 986 } 987 988 // remove the fields maps cached from all instanceKlasses 989 void JvmtiCachedClassFieldMap::clear_cache() { 990 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 991 if (_class_list != NULL) { 992 for (int i = 0; i < _class_list->length(); i++) { 993 instanceKlass* ik = _class_list->at(i); 994 JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map(); 995 assert(cached_map != NULL, "should not be NULL"); 996 ik->set_jvmti_cached_class_field_map(NULL); 997 delete cached_map; // deletes the encapsulated field map 998 } 999 delete _class_list; 1000 _class_list = NULL; 1001 } 1002 } 1003 1004 // returns the number of ClassFieldMap cached by instanceKlasses 1005 int JvmtiCachedClassFieldMap::cached_field_map_count() { 1006 return (_class_list == NULL) ? 0 : _class_list->length(); 1007 } 1008 1009 // helper function to indicate if an object is filtered by its tag or class tag 1010 static inline bool is_filtered_by_heap_filter(jlong obj_tag, 1011 jlong klass_tag, 1012 int heap_filter) { 1013 // apply the heap filter 1014 if (obj_tag != 0) { 1015 // filter out tagged objects 1016 if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true; 1017 } else { 1018 // filter out untagged objects 1019 if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true; 1020 } 1021 if (klass_tag != 0) { 1022 // filter out objects with tagged classes 1023 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true; 1024 } else { 1025 // filter out objects with untagged classes. 1026 if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true; 1027 } 1028 return false; 1029 } 1030 1031 // helper function to indicate if an object is filtered by a klass filter 1032 static inline bool is_filtered_by_klass_filter(oop obj, KlassHandle klass_filter) { 1033 if (!klass_filter.is_null()) { 1034 if (obj->klass() != klass_filter()) { 1035 return true; 1036 } 1037 } 1038 return false; 1039 } 1040 1041 // helper function to tell if a field is a primitive field or not 1042 static inline bool is_primitive_field_type(char type) { 1043 return (type != 'L' && type != '['); 1044 } 1045 1046 // helper function to copy the value from location addr to jvalue. 1047 static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) { 1048 switch (value_type) { 1049 case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; } 1050 case JVMTI_PRIMITIVE_TYPE_BYTE : { v->b = *(jbyte*)addr; break; } 1051 case JVMTI_PRIMITIVE_TYPE_CHAR : { v->c = *(jchar*)addr; break; } 1052 case JVMTI_PRIMITIVE_TYPE_SHORT : { v->s = *(jshort*)addr; break; } 1053 case JVMTI_PRIMITIVE_TYPE_INT : { v->i = *(jint*)addr; break; } 1054 case JVMTI_PRIMITIVE_TYPE_LONG : { v->j = *(jlong*)addr; break; } 1055 case JVMTI_PRIMITIVE_TYPE_FLOAT : { v->f = *(jfloat*)addr; break; } 1056 case JVMTI_PRIMITIVE_TYPE_DOUBLE : { v->d = *(jdouble*)addr; break; } 1057 default: ShouldNotReachHere(); 1058 } 1059 } 1060 1061 // helper function to invoke string primitive value callback 1062 // returns visit control flags 1063 static jint invoke_string_value_callback(jvmtiStringPrimitiveValueCallback cb, 1064 CallbackWrapper* wrapper, 1065 oop str, 1066 void* user_data) 1067 { 1068 assert(str->klass() == SystemDictionary::String_klass(), "not a string"); 1069 1070 // get the string value and length 1071 // (string value may be offset from the base) 1072 int s_len = java_lang_String::length(str); 1073 typeArrayOop s_value = java_lang_String::value(str); 1074 int s_offset = java_lang_String::offset(str); 1075 jchar* value; 1076 if (s_len > 0) { 1077 value = s_value->char_at_addr(s_offset); 1078 } else { 1079 value = (jchar*) s_value->base(T_CHAR); 1080 } 1081 1082 // invoke the callback 1083 return (*cb)(wrapper->klass_tag(), 1084 wrapper->obj_size(), 1085 wrapper->obj_tag_p(), 1086 value, 1087 (jint)s_len, 1088 user_data); 1089 } 1090 1091 // helper function to invoke string primitive value callback 1092 // returns visit control flags 1093 static jint invoke_array_primitive_value_callback(jvmtiArrayPrimitiveValueCallback cb, 1094 CallbackWrapper* wrapper, 1095 oop obj, 1096 void* user_data) 1097 { 1098 assert(obj->is_typeArray(), "not a primitive array"); 1099 1100 // get base address of first element 1101 typeArrayOop array = typeArrayOop(obj); 1102 BasicType type = typeArrayKlass::cast(array->klass())->element_type(); 1103 void* elements = array->base(type); 1104 1105 // jvmtiPrimitiveType is defined so this mapping is always correct 1106 jvmtiPrimitiveType elem_type = (jvmtiPrimitiveType)type2char(type); 1107 1108 return (*cb)(wrapper->klass_tag(), 1109 wrapper->obj_size(), 1110 wrapper->obj_tag_p(), 1111 (jint)array->length(), 1112 elem_type, 1113 elements, 1114 user_data); 1115 } 1116 1117 // helper function to invoke the primitive field callback for all static fields 1118 // of a given class 1119 static jint invoke_primitive_field_callback_for_static_fields 1120 (CallbackWrapper* wrapper, 1121 oop obj, 1122 jvmtiPrimitiveFieldCallback cb, 1123 void* user_data) 1124 { 1125 // for static fields only the index will be set 1126 static jvmtiHeapReferenceInfo reference_info = { 0 }; 1127 1128 assert(obj->klass() == SystemDictionary::Class_klass(), "not a class"); 1129 if (java_lang_Class::is_primitive(obj)) { 1130 return 0; 1131 } 1132 klassOop k = java_lang_Class::as_klassOop(obj); 1133 Klass* klass = k->klass_part(); 1134 1135 // ignore classes for object and type arrays 1136 if (!klass->oop_is_instance()) { 1137 return 0; 1138 } 1139 1140 // ignore classes which aren't linked yet 1141 instanceKlass* ik = instanceKlass::cast(k); 1142 if (!ik->is_linked()) { 1143 return 0; 1144 } 1145 1146 // get the field map 1147 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k); 1148 1149 // invoke the callback for each static primitive field 1150 for (int i=0; i<field_map->field_count(); i++) { 1151 ClassFieldDescriptor* field = field_map->field_at(i); 1152 1153 // ignore non-primitive fields 1154 char type = field->field_type(); 1155 if (!is_primitive_field_type(type)) { 1156 continue; 1157 } 1158 // one-to-one mapping 1159 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 1160 1161 // get offset and field value 1162 int offset = field->field_offset(); 1163 address addr = (address)k + offset; 1164 jvalue value; 1165 copy_to_jvalue(&value, addr, value_type); 1166 1167 // field index 1168 reference_info.field.index = field->field_index(); 1169 1170 // invoke the callback 1171 jint res = (*cb)(JVMTI_HEAP_REFERENCE_STATIC_FIELD, 1172 &reference_info, 1173 wrapper->klass_tag(), 1174 wrapper->obj_tag_p(), 1175 value, 1176 value_type, 1177 user_data); 1178 if (res & JVMTI_VISIT_ABORT) { 1179 delete field_map; 1180 return res; 1181 } 1182 } 1183 1184 delete field_map; 1185 return 0; 1186 } 1187 1188 // helper function to invoke the primitive field callback for all instance fields 1189 // of a given object 1190 static jint invoke_primitive_field_callback_for_instance_fields( 1191 CallbackWrapper* wrapper, 1192 oop obj, 1193 jvmtiPrimitiveFieldCallback cb, 1194 void* user_data) 1195 { 1196 // for instance fields only the index will be set 1197 static jvmtiHeapReferenceInfo reference_info = { 0 }; 1198 1199 // get the map of the instance fields 1200 ClassFieldMap* fields = JvmtiCachedClassFieldMap::get_map_of_instance_fields(obj); 1201 1202 // invoke the callback for each instance primitive field 1203 for (int i=0; i<fields->field_count(); i++) { 1204 ClassFieldDescriptor* field = fields->field_at(i); 1205 1206 // ignore non-primitive fields 1207 char type = field->field_type(); 1208 if (!is_primitive_field_type(type)) { 1209 continue; 1210 } 1211 // one-to-one mapping 1212 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 1213 1214 // get offset and field value 1215 int offset = field->field_offset(); 1216 address addr = (address)obj + offset; 1217 jvalue value; 1218 copy_to_jvalue(&value, addr, value_type); 1219 1220 // field index 1221 reference_info.field.index = field->field_index(); 1222 1223 // invoke the callback 1224 jint res = (*cb)(JVMTI_HEAP_REFERENCE_FIELD, 1225 &reference_info, 1226 wrapper->klass_tag(), 1227 wrapper->obj_tag_p(), 1228 value, 1229 value_type, 1230 user_data); 1231 if (res & JVMTI_VISIT_ABORT) { 1232 return res; 1233 } 1234 } 1235 return 0; 1236 } 1237 1238 1239 // VM operation to iterate over all objects in the heap (both reachable 1240 // and unreachable) 1241 class VM_HeapIterateOperation: public VM_Operation { 1242 private: 1243 ObjectClosure* _blk; 1244 public: 1245 VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; } 1246 1247 VMOp_Type type() const { return VMOp_HeapIterateOperation; } 1248 void doit() { 1249 // allows class files maps to be cached during iteration 1250 ClassFieldMapCacheMark cm; 1251 1252 // make sure that heap is parsable (fills TLABs with filler objects) 1253 Universe::heap()->ensure_parsability(false); // no need to retire TLABs 1254 1255 // Verify heap before iteration - if the heap gets corrupted then 1256 // JVMTI's IterateOverHeap will crash. 1257 if (VerifyBeforeIteration) { 1258 Universe::verify(); 1259 } 1260 1261 // do the iteration 1262 // If this operation encounters a bad object when using CMS, 1263 // consider using safe_object_iterate() which avoids perm gen 1264 // objects that may contain bad references. 1265 Universe::heap()->object_iterate(_blk); 1266 1267 // when sharing is enabled we must iterate over the shared spaces 1268 if (UseSharedSpaces) { 1269 GenCollectedHeap* gch = GenCollectedHeap::heap(); 1270 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen(); 1271 gen->ro_space()->object_iterate(_blk); 1272 gen->rw_space()->object_iterate(_blk); 1273 } 1274 } 1275 1276 }; 1277 1278 1279 // An ObjectClosure used to support the deprecated IterateOverHeap and 1280 // IterateOverInstancesOfClass functions 1281 class IterateOverHeapObjectClosure: public ObjectClosure { 1282 private: 1283 JvmtiTagMap* _tag_map; 1284 KlassHandle _klass; 1285 jvmtiHeapObjectFilter _object_filter; 1286 jvmtiHeapObjectCallback _heap_object_callback; 1287 const void* _user_data; 1288 1289 // accessors 1290 JvmtiTagMap* tag_map() const { return _tag_map; } 1291 jvmtiHeapObjectFilter object_filter() const { return _object_filter; } 1292 jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; } 1293 KlassHandle klass() const { return _klass; } 1294 const void* user_data() const { return _user_data; } 1295 1296 // indicates if iteration has been aborted 1297 bool _iteration_aborted; 1298 bool is_iteration_aborted() const { return _iteration_aborted; } 1299 void set_iteration_aborted(bool aborted) { _iteration_aborted = aborted; } 1300 1301 public: 1302 IterateOverHeapObjectClosure(JvmtiTagMap* tag_map, 1303 KlassHandle klass, 1304 jvmtiHeapObjectFilter object_filter, 1305 jvmtiHeapObjectCallback heap_object_callback, 1306 const void* user_data) : 1307 _tag_map(tag_map), 1308 _klass(klass), 1309 _object_filter(object_filter), 1310 _heap_object_callback(heap_object_callback), 1311 _user_data(user_data), 1312 _iteration_aborted(false) 1313 { 1314 } 1315 1316 void do_object(oop o); 1317 }; 1318 1319 // invoked for each object in the heap 1320 void IterateOverHeapObjectClosure::do_object(oop o) { 1321 // check if iteration has been halted 1322 if (is_iteration_aborted()) return; 1323 1324 // ignore any objects that aren't visible to profiler 1325 if (!ServiceUtil::visible_oop(o)) return; 1326 1327 // instanceof check when filtering by klass 1328 if (!klass().is_null() && !o->is_a(klass()())) { 1329 return; 1330 } 1331 // prepare for the calllback 1332 CallbackWrapper wrapper(tag_map(), o); 1333 1334 // if the object is tagged and we're only interested in untagged objects 1335 // then don't invoke the callback. Similiarly, if the object is untagged 1336 // and we're only interested in tagged objects we skip the callback. 1337 if (wrapper.obj_tag() != 0) { 1338 if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return; 1339 } else { 1340 if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return; 1341 } 1342 1343 // invoke the agent's callback 1344 jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(), 1345 wrapper.obj_size(), 1346 wrapper.obj_tag_p(), 1347 (void*)user_data()); 1348 if (control == JVMTI_ITERATION_ABORT) { 1349 set_iteration_aborted(true); 1350 } 1351 } 1352 1353 // An ObjectClosure used to support the IterateThroughHeap function 1354 class IterateThroughHeapObjectClosure: public ObjectClosure { 1355 private: 1356 JvmtiTagMap* _tag_map; 1357 KlassHandle _klass; 1358 int _heap_filter; 1359 const jvmtiHeapCallbacks* _callbacks; 1360 const void* _user_data; 1361 1362 // accessor functions 1363 JvmtiTagMap* tag_map() const { return _tag_map; } 1364 int heap_filter() const { return _heap_filter; } 1365 const jvmtiHeapCallbacks* callbacks() const { return _callbacks; } 1366 KlassHandle klass() const { return _klass; } 1367 const void* user_data() const { return _user_data; } 1368 1369 // indicates if the iteration has been aborted 1370 bool _iteration_aborted; 1371 bool is_iteration_aborted() const { return _iteration_aborted; } 1372 1373 // used to check the visit control flags. If the abort flag is set 1374 // then we set the iteration aborted flag so that the iteration completes 1375 // without processing any further objects 1376 bool check_flags_for_abort(jint flags) { 1377 bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0; 1378 if (is_abort) { 1379 _iteration_aborted = true; 1380 } 1381 return is_abort; 1382 } 1383 1384 public: 1385 IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map, 1386 KlassHandle klass, 1387 int heap_filter, 1388 const jvmtiHeapCallbacks* heap_callbacks, 1389 const void* user_data) : 1390 _tag_map(tag_map), 1391 _klass(klass), 1392 _heap_filter(heap_filter), 1393 _callbacks(heap_callbacks), 1394 _user_data(user_data), 1395 _iteration_aborted(false) 1396 { 1397 } 1398 1399 void do_object(oop o); 1400 }; 1401 1402 // invoked for each object in the heap 1403 void IterateThroughHeapObjectClosure::do_object(oop obj) { 1404 // check if iteration has been halted 1405 if (is_iteration_aborted()) return; 1406 1407 // ignore any objects that aren't visible to profiler 1408 if (!ServiceUtil::visible_oop(obj)) return; 1409 1410 // apply class filter 1411 if (is_filtered_by_klass_filter(obj, klass())) return; 1412 1413 // prepare for callback 1414 CallbackWrapper wrapper(tag_map(), obj); 1415 1416 // check if filtered by the heap filter 1417 if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) { 1418 return; 1419 } 1420 1421 // for arrays we need the length, otherwise -1 1422 bool is_array = obj->is_array(); 1423 int len = is_array ? arrayOop(obj)->length() : -1; 1424 1425 // invoke the object callback (if callback is provided) 1426 if (callbacks()->heap_iteration_callback != NULL) { 1427 jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback; 1428 jint res = (*cb)(wrapper.klass_tag(), 1429 wrapper.obj_size(), 1430 wrapper.obj_tag_p(), 1431 (jint)len, 1432 (void*)user_data()); 1433 if (check_flags_for_abort(res)) return; 1434 } 1435 1436 // for objects and classes we report primitive fields if callback provided 1437 if (callbacks()->primitive_field_callback != NULL && obj->is_instance()) { 1438 jint res; 1439 jvmtiPrimitiveFieldCallback cb = callbacks()->primitive_field_callback; 1440 if (obj->klass() == SystemDictionary::Class_klass()) { 1441 res = invoke_primitive_field_callback_for_static_fields(&wrapper, 1442 obj, 1443 cb, 1444 (void*)user_data()); 1445 } else { 1446 res = invoke_primitive_field_callback_for_instance_fields(&wrapper, 1447 obj, 1448 cb, 1449 (void*)user_data()); 1450 } 1451 if (check_flags_for_abort(res)) return; 1452 } 1453 1454 // string callback 1455 if (!is_array && 1456 callbacks()->string_primitive_value_callback != NULL && 1457 obj->klass() == SystemDictionary::String_klass()) { 1458 jint res = invoke_string_value_callback( 1459 callbacks()->string_primitive_value_callback, 1460 &wrapper, 1461 obj, 1462 (void*)user_data() ); 1463 if (check_flags_for_abort(res)) return; 1464 } 1465 1466 // array callback 1467 if (is_array && 1468 callbacks()->array_primitive_value_callback != NULL && 1469 obj->is_typeArray()) { 1470 jint res = invoke_array_primitive_value_callback( 1471 callbacks()->array_primitive_value_callback, 1472 &wrapper, 1473 obj, 1474 (void*)user_data() ); 1475 if (check_flags_for_abort(res)) return; 1476 } 1477 }; 1478 1479 1480 // Deprecated function to iterate over all objects in the heap 1481 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter, 1482 KlassHandle klass, 1483 jvmtiHeapObjectCallback heap_object_callback, 1484 const void* user_data) 1485 { 1486 MutexLocker ml(Heap_lock); 1487 IterateOverHeapObjectClosure blk(this, 1488 klass, 1489 object_filter, 1490 heap_object_callback, 1491 user_data); 1492 VM_HeapIterateOperation op(&blk); 1493 VMThread::execute(&op); 1494 } 1495 1496 1497 // Iterates over all objects in the heap 1498 void JvmtiTagMap::iterate_through_heap(jint heap_filter, 1499 KlassHandle klass, 1500 const jvmtiHeapCallbacks* callbacks, 1501 const void* user_data) 1502 { 1503 MutexLocker ml(Heap_lock); 1504 IterateThroughHeapObjectClosure blk(this, 1505 klass, 1506 heap_filter, 1507 callbacks, 1508 user_data); 1509 VM_HeapIterateOperation op(&blk); 1510 VMThread::execute(&op); 1511 } 1512 1513 // support class for get_objects_with_tags 1514 1515 class TagObjectCollector : public JvmtiTagHashmapEntryClosure { 1516 private: 1517 JvmtiEnv* _env; 1518 jlong* _tags; 1519 jint _tag_count; 1520 1521 GrowableArray<jobject>* _object_results; // collected objects (JNI weak refs) 1522 GrowableArray<uint64_t>* _tag_results; // collected tags 1523 1524 public: 1525 TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) { 1526 _env = env; 1527 _tags = (jlong*)tags; 1528 _tag_count = tag_count; 1529 _object_results = new (ResourceObj::C_HEAP) GrowableArray<jobject>(1,true); 1530 _tag_results = new (ResourceObj::C_HEAP) GrowableArray<uint64_t>(1,true); 1531 } 1532 1533 ~TagObjectCollector() { 1534 delete _object_results; 1535 delete _tag_results; 1536 } 1537 1538 // for each tagged object check if the tag value matches 1539 // - if it matches then we create a JNI local reference to the object 1540 // and record the reference and tag value. 1541 // 1542 void do_entry(JvmtiTagHashmapEntry* entry) { 1543 for (int i=0; i<_tag_count; i++) { 1544 if (_tags[i] == entry->tag()) { 1545 oop o = entry->object(); 1546 assert(o != NULL, "sanity check"); 1547 1548 // the mirror is tagged 1549 if (o->is_klass()) { 1550 klassOop k = (klassOop)o; 1551 o = Klass::cast(k)->java_mirror(); 1552 } 1553 1554 jobject ref = JNIHandles::make_local(JavaThread::current(), o); 1555 _object_results->append(ref); 1556 _tag_results->append((uint64_t)entry->tag()); 1557 } 1558 } 1559 } 1560 1561 // return the results from the collection 1562 // 1563 jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { 1564 jvmtiError error; 1565 int count = _object_results->length(); 1566 assert(count >= 0, "sanity check"); 1567 1568 // if object_result_ptr is not NULL then allocate the result and copy 1569 // in the object references. 1570 if (object_result_ptr != NULL) { 1571 error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr); 1572 if (error != JVMTI_ERROR_NONE) { 1573 return error; 1574 } 1575 for (int i=0; i<count; i++) { 1576 (*object_result_ptr)[i] = _object_results->at(i); 1577 } 1578 } 1579 1580 // if tag_result_ptr is not NULL then allocate the result and copy 1581 // in the tag values. 1582 if (tag_result_ptr != NULL) { 1583 error = _env->Allocate(count * sizeof(jlong), (unsigned char**)tag_result_ptr); 1584 if (error != JVMTI_ERROR_NONE) { 1585 if (object_result_ptr != NULL) { 1586 _env->Deallocate((unsigned char*)object_result_ptr); 1587 } 1588 return error; 1589 } 1590 for (int i=0; i<count; i++) { 1591 (*tag_result_ptr)[i] = (jlong)_tag_results->at(i); 1592 } 1593 } 1594 1595 *count_ptr = count; 1596 return JVMTI_ERROR_NONE; 1597 } 1598 }; 1599 1600 // return the list of objects with the specified tags 1601 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags, 1602 jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) { 1603 1604 TagObjectCollector collector(env(), tags, count); 1605 { 1606 // iterate over all tagged objects 1607 MutexLocker ml(lock()); 1608 entry_iterate(&collector); 1609 } 1610 return collector.result(count_ptr, object_result_ptr, tag_result_ptr); 1611 } 1612 1613 1614 // ObjectMarker is used to support the marking objects when walking the 1615 // heap. 1616 // 1617 // This implementation uses the existing mark bits in an object for 1618 // marking. Objects that are marked must later have their headers restored. 1619 // As most objects are unlocked and don't have their identity hash computed 1620 // we don't have to save their headers. Instead we save the headers that 1621 // are "interesting". Later when the headers are restored this implementation 1622 // restores all headers to their initial value and then restores the few 1623 // objects that had interesting headers. 1624 // 1625 // Future work: This implementation currently uses growable arrays to save 1626 // the oop and header of interesting objects. As an optimization we could 1627 // use the same technique as the GC and make use of the unused area 1628 // between top() and end(). 1629 // 1630 1631 // An ObjectClosure used to restore the mark bits of an object 1632 class RestoreMarksClosure : public ObjectClosure { 1633 public: 1634 void do_object(oop o) { 1635 if (o != NULL) { 1636 markOop mark = o->mark(); 1637 if (mark->is_marked()) { 1638 o->init_mark(); 1639 } 1640 } 1641 } 1642 }; 1643 1644 // ObjectMarker provides the mark and visited functions 1645 class ObjectMarker : AllStatic { 1646 private: 1647 // saved headers 1648 static GrowableArray<oop>* _saved_oop_stack; 1649 static GrowableArray<markOop>* _saved_mark_stack; 1650 1651 public: 1652 static void init(); // initialize 1653 static void done(); // clean-up 1654 1655 static inline void mark(oop o); // mark an object 1656 static inline bool visited(oop o); // check if object has been visited 1657 }; 1658 1659 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; 1660 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL; 1661 1662 // initialize ObjectMarker - prepares for object marking 1663 void ObjectMarker::init() { 1664 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 1665 1666 // prepare heap for iteration 1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs 1668 1669 // create stacks for interesting headers 1670 _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true); 1671 _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true); 1672 1673 if (UseBiasedLocking) { 1674 BiasedLocking::preserve_marks(); 1675 } 1676 } 1677 1678 // Object marking is done so restore object headers 1679 void ObjectMarker::done() { 1680 // iterate over all objects and restore the mark bits to 1681 // their initial value 1682 RestoreMarksClosure blk; 1683 Universe::heap()->object_iterate(&blk); 1684 1685 // When sharing is enabled we need to restore the headers of the objects 1686 // in the readwrite space too. 1687 if (UseSharedSpaces) { 1688 GenCollectedHeap* gch = GenCollectedHeap::heap(); 1689 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen(); 1690 gen->rw_space()->object_iterate(&blk); 1691 } 1692 1693 // now restore the interesting headers 1694 for (int i = 0; i < _saved_oop_stack->length(); i++) { 1695 oop o = _saved_oop_stack->at(i); 1696 markOop mark = _saved_mark_stack->at(i); 1697 o->set_mark(mark); 1698 } 1699 1700 if (UseBiasedLocking) { 1701 BiasedLocking::restore_marks(); 1702 } 1703 1704 // free the stacks 1705 delete _saved_oop_stack; 1706 delete _saved_mark_stack; 1707 } 1708 1709 // mark an object 1710 inline void ObjectMarker::mark(oop o) { 1711 assert(Universe::heap()->is_in(o), "sanity check"); 1712 assert(!o->mark()->is_marked(), "should only mark an object once"); 1713 1714 // object's mark word 1715 markOop mark = o->mark(); 1716 1717 if (mark->must_be_preserved(o)) { 1718 _saved_mark_stack->push(mark); 1719 _saved_oop_stack->push(o); 1720 } 1721 1722 // mark the object 1723 o->set_mark(markOopDesc::prototype()->set_marked()); 1724 } 1725 1726 // return true if object is marked 1727 inline bool ObjectMarker::visited(oop o) { 1728 return o->mark()->is_marked(); 1729 } 1730 1731 // Stack allocated class to help ensure that ObjectMarker is used 1732 // correctly. Constructor initializes ObjectMarker, destructor calls 1733 // ObjectMarker's done() function to restore object headers. 1734 class ObjectMarkerController : public StackObj { 1735 public: 1736 ObjectMarkerController() { 1737 ObjectMarker::init(); 1738 } 1739 ~ObjectMarkerController() { 1740 ObjectMarker::done(); 1741 } 1742 }; 1743 1744 1745 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind 1746 // (not performance critical as only used for roots) 1747 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) { 1748 switch (kind) { 1749 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL; 1750 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS; 1751 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR; 1752 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL; 1753 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL; 1754 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD; 1755 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER; 1756 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER; 1757 } 1758 } 1759 1760 // Base class for all heap walk contexts. The base class maintains a flag 1761 // to indicate if the context is valid or not. 1762 class HeapWalkContext VALUE_OBJ_CLASS_SPEC { 1763 private: 1764 bool _valid; 1765 public: 1766 HeapWalkContext(bool valid) { _valid = valid; } 1767 void invalidate() { _valid = false; } 1768 bool is_valid() const { return _valid; } 1769 }; 1770 1771 // A basic heap walk context for the deprecated heap walking functions. 1772 // The context for a basic heap walk are the callbacks and fields used by 1773 // the referrer caching scheme. 1774 class BasicHeapWalkContext: public HeapWalkContext { 1775 private: 1776 jvmtiHeapRootCallback _heap_root_callback; 1777 jvmtiStackReferenceCallback _stack_ref_callback; 1778 jvmtiObjectReferenceCallback _object_ref_callback; 1779 1780 // used for caching 1781 oop _last_referrer; 1782 jlong _last_referrer_tag; 1783 1784 public: 1785 BasicHeapWalkContext() : HeapWalkContext(false) { } 1786 1787 BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback, 1788 jvmtiStackReferenceCallback stack_ref_callback, 1789 jvmtiObjectReferenceCallback object_ref_callback) : 1790 HeapWalkContext(true), 1791 _heap_root_callback(heap_root_callback), 1792 _stack_ref_callback(stack_ref_callback), 1793 _object_ref_callback(object_ref_callback), 1794 _last_referrer(NULL), 1795 _last_referrer_tag(0) { 1796 } 1797 1798 // accessors 1799 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; } 1800 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; } 1801 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; } 1802 1803 oop last_referrer() const { return _last_referrer; } 1804 void set_last_referrer(oop referrer) { _last_referrer = referrer; } 1805 jlong last_referrer_tag() const { return _last_referrer_tag; } 1806 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; } 1807 }; 1808 1809 // The advanced heap walk context for the FollowReferences functions. 1810 // The context is the callbacks, and the fields used for filtering. 1811 class AdvancedHeapWalkContext: public HeapWalkContext { 1812 private: 1813 jint _heap_filter; 1814 KlassHandle _klass_filter; 1815 const jvmtiHeapCallbacks* _heap_callbacks; 1816 1817 public: 1818 AdvancedHeapWalkContext() : HeapWalkContext(false) { } 1819 1820 AdvancedHeapWalkContext(jint heap_filter, 1821 KlassHandle klass_filter, 1822 const jvmtiHeapCallbacks* heap_callbacks) : 1823 HeapWalkContext(true), 1824 _heap_filter(heap_filter), 1825 _klass_filter(klass_filter), 1826 _heap_callbacks(heap_callbacks) { 1827 } 1828 1829 // accessors 1830 jint heap_filter() const { return _heap_filter; } 1831 KlassHandle klass_filter() const { return _klass_filter; } 1832 1833 const jvmtiHeapReferenceCallback heap_reference_callback() const { 1834 return _heap_callbacks->heap_reference_callback; 1835 }; 1836 const jvmtiPrimitiveFieldCallback primitive_field_callback() const { 1837 return _heap_callbacks->primitive_field_callback; 1838 } 1839 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const { 1840 return _heap_callbacks->array_primitive_value_callback; 1841 } 1842 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const { 1843 return _heap_callbacks->string_primitive_value_callback; 1844 } 1845 }; 1846 1847 // The CallbackInvoker is a class with static functions that the heap walk can call 1848 // into to invoke callbacks. It works in one of two modes. The "basic" mode is 1849 // used for the deprecated IterateOverReachableObjects functions. The "advanced" 1850 // mode is for the newer FollowReferences function which supports a lot of 1851 // additional callbacks. 1852 class CallbackInvoker : AllStatic { 1853 private: 1854 // heap walk styles 1855 enum { basic, advanced }; 1856 static int _heap_walk_type; 1857 static bool is_basic_heap_walk() { return _heap_walk_type == basic; } 1858 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; } 1859 1860 // context for basic style heap walk 1861 static BasicHeapWalkContext _basic_context; 1862 static BasicHeapWalkContext* basic_context() { 1863 assert(_basic_context.is_valid(), "invalid"); 1864 return &_basic_context; 1865 } 1866 1867 // context for advanced style heap walk 1868 static AdvancedHeapWalkContext _advanced_context; 1869 static AdvancedHeapWalkContext* advanced_context() { 1870 assert(_advanced_context.is_valid(), "invalid"); 1871 return &_advanced_context; 1872 } 1873 1874 // context needed for all heap walks 1875 static JvmtiTagMap* _tag_map; 1876 static const void* _user_data; 1877 static GrowableArray<oop>* _visit_stack; 1878 1879 // accessors 1880 static JvmtiTagMap* tag_map() { return _tag_map; } 1881 static const void* user_data() { return _user_data; } 1882 static GrowableArray<oop>* visit_stack() { return _visit_stack; } 1883 1884 // if the object hasn't been visited then push it onto the visit stack 1885 // so that it will be visited later 1886 static inline bool check_for_visit(oop obj) { 1887 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj); 1888 return true; 1889 } 1890 1891 // invoke basic style callbacks 1892 static inline bool invoke_basic_heap_root_callback 1893 (jvmtiHeapRootKind root_kind, oop obj); 1894 static inline bool invoke_basic_stack_ref_callback 1895 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method, 1896 int slot, oop obj); 1897 static inline bool invoke_basic_object_reference_callback 1898 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index); 1899 1900 // invoke advanced style callbacks 1901 static inline bool invoke_advanced_heap_root_callback 1902 (jvmtiHeapReferenceKind ref_kind, oop obj); 1903 static inline bool invoke_advanced_stack_ref_callback 1904 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth, 1905 jmethodID method, jlocation bci, jint slot, oop obj); 1906 static inline bool invoke_advanced_object_reference_callback 1907 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index); 1908 1909 // used to report the value of primitive fields 1910 static inline bool report_primitive_field 1911 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type); 1912 1913 public: 1914 // initialize for basic mode 1915 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map, 1916 GrowableArray<oop>* visit_stack, 1917 const void* user_data, 1918 BasicHeapWalkContext context); 1919 1920 // initialize for advanced mode 1921 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map, 1922 GrowableArray<oop>* visit_stack, 1923 const void* user_data, 1924 AdvancedHeapWalkContext context); 1925 1926 // functions to report roots 1927 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o); 1928 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth, 1929 jmethodID m, oop o); 1930 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth, 1931 jmethodID method, jlocation bci, jint slot, oop o); 1932 1933 // functions to report references 1934 static inline bool report_array_element_reference(oop referrer, oop referree, jint index); 1935 static inline bool report_class_reference(oop referrer, oop referree); 1936 static inline bool report_class_loader_reference(oop referrer, oop referree); 1937 static inline bool report_signers_reference(oop referrer, oop referree); 1938 static inline bool report_protection_domain_reference(oop referrer, oop referree); 1939 static inline bool report_superclass_reference(oop referrer, oop referree); 1940 static inline bool report_interface_reference(oop referrer, oop referree); 1941 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot); 1942 static inline bool report_field_reference(oop referrer, oop referree, jint slot); 1943 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index); 1944 static inline bool report_primitive_array_values(oop array); 1945 static inline bool report_string_value(oop str); 1946 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type); 1947 static inline bool report_primitive_static_field(oop o, jint index, address value, char type); 1948 }; 1949 1950 // statics 1951 int CallbackInvoker::_heap_walk_type; 1952 BasicHeapWalkContext CallbackInvoker::_basic_context; 1953 AdvancedHeapWalkContext CallbackInvoker::_advanced_context; 1954 JvmtiTagMap* CallbackInvoker::_tag_map; 1955 const void* CallbackInvoker::_user_data; 1956 GrowableArray<oop>* CallbackInvoker::_visit_stack; 1957 1958 // initialize for basic heap walk (IterateOverReachableObjects et al) 1959 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map, 1960 GrowableArray<oop>* visit_stack, 1961 const void* user_data, 1962 BasicHeapWalkContext context) { 1963 _tag_map = tag_map; 1964 _visit_stack = visit_stack; 1965 _user_data = user_data; 1966 _basic_context = context; 1967 _advanced_context.invalidate(); // will trigger assertion if used 1968 _heap_walk_type = basic; 1969 } 1970 1971 // initialize for advanced heap walk (FollowReferences) 1972 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map, 1973 GrowableArray<oop>* visit_stack, 1974 const void* user_data, 1975 AdvancedHeapWalkContext context) { 1976 _tag_map = tag_map; 1977 _visit_stack = visit_stack; 1978 _user_data = user_data; 1979 _advanced_context = context; 1980 _basic_context.invalidate(); // will trigger assertion if used 1981 _heap_walk_type = advanced; 1982 } 1983 1984 1985 // invoke basic style heap root callback 1986 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) { 1987 assert(ServiceUtil::visible_oop(obj), "checking"); 1988 1989 // if we heap roots should be reported 1990 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback(); 1991 if (cb == NULL) { 1992 return check_for_visit(obj); 1993 } 1994 1995 CallbackWrapper wrapper(tag_map(), obj); 1996 jvmtiIterationControl control = (*cb)(root_kind, 1997 wrapper.klass_tag(), 1998 wrapper.obj_size(), 1999 wrapper.obj_tag_p(), 2000 (void*)user_data()); 2001 // push root to visit stack when following references 2002 if (control == JVMTI_ITERATION_CONTINUE && 2003 basic_context()->object_ref_callback() != NULL) { 2004 visit_stack()->push(obj); 2005 } 2006 return control != JVMTI_ITERATION_ABORT; 2007 } 2008 2009 // invoke basic style stack ref callback 2010 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind, 2011 jlong thread_tag, 2012 jint depth, 2013 jmethodID method, 2014 jint slot, 2015 oop obj) { 2016 assert(ServiceUtil::visible_oop(obj), "checking"); 2017 2018 // if we stack refs should be reported 2019 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback(); 2020 if (cb == NULL) { 2021 return check_for_visit(obj); 2022 } 2023 2024 CallbackWrapper wrapper(tag_map(), obj); 2025 jvmtiIterationControl control = (*cb)(root_kind, 2026 wrapper.klass_tag(), 2027 wrapper.obj_size(), 2028 wrapper.obj_tag_p(), 2029 thread_tag, 2030 depth, 2031 method, 2032 slot, 2033 (void*)user_data()); 2034 // push root to visit stack when following references 2035 if (control == JVMTI_ITERATION_CONTINUE && 2036 basic_context()->object_ref_callback() != NULL) { 2037 visit_stack()->push(obj); 2038 } 2039 return control != JVMTI_ITERATION_ABORT; 2040 } 2041 2042 // invoke basic style object reference callback 2043 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind, 2044 oop referrer, 2045 oop referree, 2046 jint index) { 2047 2048 assert(ServiceUtil::visible_oop(referrer), "checking"); 2049 assert(ServiceUtil::visible_oop(referree), "checking"); 2050 2051 BasicHeapWalkContext* context = basic_context(); 2052 2053 // callback requires the referrer's tag. If it's the same referrer 2054 // as the last call then we use the cached value. 2055 jlong referrer_tag; 2056 if (referrer == context->last_referrer()) { 2057 referrer_tag = context->last_referrer_tag(); 2058 } else { 2059 referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer)); 2060 } 2061 2062 // do the callback 2063 CallbackWrapper wrapper(tag_map(), referree); 2064 jvmtiObjectReferenceCallback cb = context->object_ref_callback(); 2065 jvmtiIterationControl control = (*cb)(ref_kind, 2066 wrapper.klass_tag(), 2067 wrapper.obj_size(), 2068 wrapper.obj_tag_p(), 2069 referrer_tag, 2070 index, 2071 (void*)user_data()); 2072 2073 // record referrer and referrer tag. For self-references record the 2074 // tag value from the callback as this might differ from referrer_tag. 2075 context->set_last_referrer(referrer); 2076 if (referrer == referree) { 2077 context->set_last_referrer_tag(*wrapper.obj_tag_p()); 2078 } else { 2079 context->set_last_referrer_tag(referrer_tag); 2080 } 2081 2082 if (control == JVMTI_ITERATION_CONTINUE) { 2083 return check_for_visit(referree); 2084 } else { 2085 return control != JVMTI_ITERATION_ABORT; 2086 } 2087 } 2088 2089 // invoke advanced style heap root callback 2090 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind, 2091 oop obj) { 2092 assert(ServiceUtil::visible_oop(obj), "checking"); 2093 2094 AdvancedHeapWalkContext* context = advanced_context(); 2095 2096 // check that callback is provided 2097 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2098 if (cb == NULL) { 2099 return check_for_visit(obj); 2100 } 2101 2102 // apply class filter 2103 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2104 return check_for_visit(obj); 2105 } 2106 2107 // setup the callback wrapper 2108 CallbackWrapper wrapper(tag_map(), obj); 2109 2110 // apply tag filter 2111 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2112 wrapper.klass_tag(), 2113 context->heap_filter())) { 2114 return check_for_visit(obj); 2115 } 2116 2117 // for arrays we need the length, otherwise -1 2118 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2119 2120 // invoke the callback 2121 jint res = (*cb)(ref_kind, 2122 NULL, // referrer info 2123 wrapper.klass_tag(), 2124 0, // referrer_class_tag is 0 for heap root 2125 wrapper.obj_size(), 2126 wrapper.obj_tag_p(), 2127 NULL, // referrer_tag_p 2128 len, 2129 (void*)user_data()); 2130 if (res & JVMTI_VISIT_ABORT) { 2131 return false;// referrer class tag 2132 } 2133 if (res & JVMTI_VISIT_OBJECTS) { 2134 check_for_visit(obj); 2135 } 2136 return true; 2137 } 2138 2139 // report a reference from a thread stack to an object 2140 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind, 2141 jlong thread_tag, 2142 jlong tid, 2143 int depth, 2144 jmethodID method, 2145 jlocation bci, 2146 jint slot, 2147 oop obj) { 2148 assert(ServiceUtil::visible_oop(obj), "checking"); 2149 2150 AdvancedHeapWalkContext* context = advanced_context(); 2151 2152 // check that callback is provider 2153 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2154 if (cb == NULL) { 2155 return check_for_visit(obj); 2156 } 2157 2158 // apply class filter 2159 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2160 return check_for_visit(obj); 2161 } 2162 2163 // setup the callback wrapper 2164 CallbackWrapper wrapper(tag_map(), obj); 2165 2166 // apply tag filter 2167 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2168 wrapper.klass_tag(), 2169 context->heap_filter())) { 2170 return check_for_visit(obj); 2171 } 2172 2173 // setup the referrer info 2174 jvmtiHeapReferenceInfo reference_info; 2175 reference_info.stack_local.thread_tag = thread_tag; 2176 reference_info.stack_local.thread_id = tid; 2177 reference_info.stack_local.depth = depth; 2178 reference_info.stack_local.method = method; 2179 reference_info.stack_local.location = bci; 2180 reference_info.stack_local.slot = slot; 2181 2182 // for arrays we need the length, otherwise -1 2183 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2184 2185 // call into the agent 2186 int res = (*cb)(ref_kind, 2187 &reference_info, 2188 wrapper.klass_tag(), 2189 0, // referrer_class_tag is 0 for heap root (stack) 2190 wrapper.obj_size(), 2191 wrapper.obj_tag_p(), 2192 NULL, // referrer_tag is 0 for root 2193 len, 2194 (void*)user_data()); 2195 2196 if (res & JVMTI_VISIT_ABORT) { 2197 return false; 2198 } 2199 if (res & JVMTI_VISIT_OBJECTS) { 2200 check_for_visit(obj); 2201 } 2202 return true; 2203 } 2204 2205 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback 2206 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed. 2207 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \ 2208 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \ 2209 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \ 2210 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \ 2211 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \ 2212 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL)) 2213 2214 // invoke the object reference callback to report a reference 2215 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind, 2216 oop referrer, 2217 oop obj, 2218 jint index) 2219 { 2220 // field index is only valid field in reference_info 2221 static jvmtiHeapReferenceInfo reference_info = { 0 }; 2222 2223 assert(ServiceUtil::visible_oop(referrer), "checking"); 2224 assert(ServiceUtil::visible_oop(obj), "checking"); 2225 2226 AdvancedHeapWalkContext* context = advanced_context(); 2227 2228 // check that callback is provider 2229 jvmtiHeapReferenceCallback cb = context->heap_reference_callback(); 2230 if (cb == NULL) { 2231 return check_for_visit(obj); 2232 } 2233 2234 // apply class filter 2235 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2236 return check_for_visit(obj); 2237 } 2238 2239 // setup the callback wrapper 2240 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj); 2241 2242 // apply tag filter 2243 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2244 wrapper.klass_tag(), 2245 context->heap_filter())) { 2246 return check_for_visit(obj); 2247 } 2248 2249 // field index is only valid field in reference_info 2250 reference_info.field.index = index; 2251 2252 // for arrays we need the length, otherwise -1 2253 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); 2254 2255 // invoke the callback 2256 int res = (*cb)(ref_kind, 2257 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL, 2258 wrapper.klass_tag(), 2259 wrapper.referrer_klass_tag(), 2260 wrapper.obj_size(), 2261 wrapper.obj_tag_p(), 2262 wrapper.referrer_tag_p(), 2263 len, 2264 (void*)user_data()); 2265 2266 if (res & JVMTI_VISIT_ABORT) { 2267 return false; 2268 } 2269 if (res & JVMTI_VISIT_OBJECTS) { 2270 check_for_visit(obj); 2271 } 2272 return true; 2273 } 2274 2275 // report a "simple root" 2276 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) { 2277 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL && 2278 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root"); 2279 assert(ServiceUtil::visible_oop(obj), "checking"); 2280 2281 if (is_basic_heap_walk()) { 2282 // map to old style root kind 2283 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind); 2284 return invoke_basic_heap_root_callback(root_kind, obj); 2285 } else { 2286 assert(is_advanced_heap_walk(), "wrong heap walk type"); 2287 return invoke_advanced_heap_root_callback(kind, obj); 2288 } 2289 } 2290 2291 2292 // invoke the primitive array values 2293 inline bool CallbackInvoker::report_primitive_array_values(oop obj) { 2294 assert(obj->is_typeArray(), "not a primitive array"); 2295 2296 AdvancedHeapWalkContext* context = advanced_context(); 2297 assert(context->array_primitive_value_callback() != NULL, "no callback"); 2298 2299 // apply class filter 2300 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2301 return true; 2302 } 2303 2304 CallbackWrapper wrapper(tag_map(), obj); 2305 2306 // apply tag filter 2307 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2308 wrapper.klass_tag(), 2309 context->heap_filter())) { 2310 return true; 2311 } 2312 2313 // invoke the callback 2314 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(), 2315 &wrapper, 2316 obj, 2317 (void*)user_data()); 2318 return (!(res & JVMTI_VISIT_ABORT)); 2319 } 2320 2321 // invoke the string value callback 2322 inline bool CallbackInvoker::report_string_value(oop str) { 2323 assert(str->klass() == SystemDictionary::String_klass(), "not a string"); 2324 2325 AdvancedHeapWalkContext* context = advanced_context(); 2326 assert(context->string_primitive_value_callback() != NULL, "no callback"); 2327 2328 // apply class filter 2329 if (is_filtered_by_klass_filter(str, context->klass_filter())) { 2330 return true; 2331 } 2332 2333 CallbackWrapper wrapper(tag_map(), str); 2334 2335 // apply tag filter 2336 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2337 wrapper.klass_tag(), 2338 context->heap_filter())) { 2339 return true; 2340 } 2341 2342 // invoke the callback 2343 int res = invoke_string_value_callback(context->string_primitive_value_callback(), 2344 &wrapper, 2345 str, 2346 (void*)user_data()); 2347 return (!(res & JVMTI_VISIT_ABORT)); 2348 } 2349 2350 // invoke the primitive field callback 2351 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind, 2352 oop obj, 2353 jint index, 2354 address addr, 2355 char type) 2356 { 2357 // for primitive fields only the index will be set 2358 static jvmtiHeapReferenceInfo reference_info = { 0 }; 2359 2360 AdvancedHeapWalkContext* context = advanced_context(); 2361 assert(context->primitive_field_callback() != NULL, "no callback"); 2362 2363 // apply class filter 2364 if (is_filtered_by_klass_filter(obj, context->klass_filter())) { 2365 return true; 2366 } 2367 2368 CallbackWrapper wrapper(tag_map(), obj); 2369 2370 // apply tag filter 2371 if (is_filtered_by_heap_filter(wrapper.obj_tag(), 2372 wrapper.klass_tag(), 2373 context->heap_filter())) { 2374 return true; 2375 } 2376 2377 // the field index in the referrer 2378 reference_info.field.index = index; 2379 2380 // map the type 2381 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type; 2382 2383 // setup the jvalue 2384 jvalue value; 2385 copy_to_jvalue(&value, addr, value_type); 2386 2387 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback(); 2388 int res = (*cb)(ref_kind, 2389 &reference_info, 2390 wrapper.klass_tag(), 2391 wrapper.obj_tag_p(), 2392 value, 2393 value_type, 2394 (void*)user_data()); 2395 return (!(res & JVMTI_VISIT_ABORT)); 2396 } 2397 2398 2399 // instance field 2400 inline bool CallbackInvoker::report_primitive_instance_field(oop obj, 2401 jint index, 2402 address value, 2403 char type) { 2404 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD, 2405 obj, 2406 index, 2407 value, 2408 type); 2409 } 2410 2411 // static field 2412 inline bool CallbackInvoker::report_primitive_static_field(oop obj, 2413 jint index, 2414 address value, 2415 char type) { 2416 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD, 2417 obj, 2418 index, 2419 value, 2420 type); 2421 } 2422 2423 // report a JNI local (root object) to the profiler 2424 inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) { 2425 if (is_basic_heap_walk()) { 2426 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL, 2427 thread_tag, 2428 depth, 2429 m, 2430 -1, 2431 obj); 2432 } else { 2433 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL, 2434 thread_tag, tid, 2435 depth, 2436 m, 2437 (jlocation)-1, 2438 -1, 2439 obj); 2440 } 2441 } 2442 2443 2444 // report a local (stack reference, root object) 2445 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag, 2446 jlong tid, 2447 jint depth, 2448 jmethodID method, 2449 jlocation bci, 2450 jint slot, 2451 oop obj) { 2452 if (is_basic_heap_walk()) { 2453 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL, 2454 thread_tag, 2455 depth, 2456 method, 2457 slot, 2458 obj); 2459 } else { 2460 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL, 2461 thread_tag, 2462 tid, 2463 depth, 2464 method, 2465 bci, 2466 slot, 2467 obj); 2468 } 2469 } 2470 2471 // report an object referencing a class. 2472 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) { 2473 if (is_basic_heap_walk()) { 2474 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1); 2475 } else { 2476 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1); 2477 } 2478 } 2479 2480 // report a class referencing its class loader. 2481 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) { 2482 if (is_basic_heap_walk()) { 2483 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1); 2484 } else { 2485 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1); 2486 } 2487 } 2488 2489 // report a class referencing its signers. 2490 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) { 2491 if (is_basic_heap_walk()) { 2492 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1); 2493 } else { 2494 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1); 2495 } 2496 } 2497 2498 // report a class referencing its protection domain.. 2499 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) { 2500 if (is_basic_heap_walk()) { 2501 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1); 2502 } else { 2503 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1); 2504 } 2505 } 2506 2507 // report a class referencing its superclass. 2508 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) { 2509 if (is_basic_heap_walk()) { 2510 // Send this to be consistent with past implementation 2511 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1); 2512 } else { 2513 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1); 2514 } 2515 } 2516 2517 // report a class referencing one of its interfaces. 2518 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) { 2519 if (is_basic_heap_walk()) { 2520 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1); 2521 } else { 2522 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1); 2523 } 2524 } 2525 2526 // report a class referencing one of its static fields. 2527 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) { 2528 if (is_basic_heap_walk()) { 2529 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot); 2530 } else { 2531 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot); 2532 } 2533 } 2534 2535 // report an array referencing an element object 2536 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) { 2537 if (is_basic_heap_walk()) { 2538 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index); 2539 } else { 2540 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index); 2541 } 2542 } 2543 2544 // report an object referencing an instance field object 2545 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) { 2546 if (is_basic_heap_walk()) { 2547 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot); 2548 } else { 2549 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot); 2550 } 2551 } 2552 2553 // report an array referencing an element object 2554 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) { 2555 if (is_basic_heap_walk()) { 2556 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index); 2557 } else { 2558 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index); 2559 } 2560 } 2561 2562 // A supporting closure used to process simple roots 2563 class SimpleRootsClosure : public OopClosure { 2564 private: 2565 jvmtiHeapReferenceKind _kind; 2566 bool _continue; 2567 2568 jvmtiHeapReferenceKind root_kind() { return _kind; } 2569 2570 public: 2571 void set_kind(jvmtiHeapReferenceKind kind) { 2572 _kind = kind; 2573 _continue = true; 2574 } 2575 2576 inline bool stopped() { 2577 return !_continue; 2578 } 2579 2580 void do_oop(oop* obj_p) { 2581 // iteration has terminated 2582 if (stopped()) { 2583 return; 2584 } 2585 2586 // ignore null or deleted handles 2587 oop o = *obj_p; 2588 if (o == NULL || o == JNIHandles::deleted_handle()) { 2589 return; 2590 } 2591 2592 jvmtiHeapReferenceKind kind = root_kind(); 2593 2594 // many roots are Klasses so we use the java mirror 2595 if (o->is_klass()) { 2596 klassOop k = (klassOop)o; 2597 o = Klass::cast(k)->java_mirror(); 2598 if (o == NULL) { 2599 // Classes without mirrors don't correspond to real Java 2600 // classes so just ignore them. 2601 return; 2602 } 2603 } else { 2604 2605 // SystemDictionary::always_strong_oops_do reports the application 2606 // class loader as a root. We want this root to be reported as 2607 // a root kind of "OTHER" rather than "SYSTEM_CLASS". 2608 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { 2609 kind = JVMTI_HEAP_REFERENCE_OTHER; 2610 } 2611 } 2612 2613 // some objects are ignored - in the case of simple 2614 // roots it's mostly Symbol*s that we are skipping 2615 // here. 2616 if (!ServiceUtil::visible_oop(o)) { 2617 return; 2618 } 2619 2620 // invoke the callback 2621 _continue = CallbackInvoker::report_simple_root(kind, o); 2622 2623 } 2624 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } 2625 }; 2626 2627 // A supporting closure used to process JNI locals 2628 class JNILocalRootsClosure : public OopClosure { 2629 private: 2630 jlong _thread_tag; 2631 jlong _tid; 2632 jint _depth; 2633 jmethodID _method; 2634 bool _continue; 2635 public: 2636 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) { 2637 _thread_tag = thread_tag; 2638 _tid = tid; 2639 _depth = depth; 2640 _method = method; 2641 _continue = true; 2642 } 2643 2644 inline bool stopped() { 2645 return !_continue; 2646 } 2647 2648 void do_oop(oop* obj_p) { 2649 // iteration has terminated 2650 if (stopped()) { 2651 return; 2652 } 2653 2654 // ignore null or deleted handles 2655 oop o = *obj_p; 2656 if (o == NULL || o == JNIHandles::deleted_handle()) { 2657 return; 2658 } 2659 2660 if (!ServiceUtil::visible_oop(o)) { 2661 return; 2662 } 2663 2664 // invoke the callback 2665 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o); 2666 } 2667 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); } 2668 }; 2669 2670 2671 // A VM operation to iterate over objects that are reachable from 2672 // a set of roots or an initial object. 2673 // 2674 // For VM_HeapWalkOperation the set of roots used is :- 2675 // 2676 // - All JNI global references 2677 // - All inflated monitors 2678 // - All classes loaded by the boot class loader (or all classes 2679 // in the event that class unloading is disabled) 2680 // - All java threads 2681 // - For each java thread then all locals and JNI local references 2682 // on the thread's execution stack 2683 // - All visible/explainable objects from Universes::oops_do 2684 // 2685 class VM_HeapWalkOperation: public VM_Operation { 2686 private: 2687 enum { 2688 initial_visit_stack_size = 4000 2689 }; 2690 2691 bool _is_advanced_heap_walk; // indicates FollowReferences 2692 JvmtiTagMap* _tag_map; 2693 Handle _initial_object; 2694 GrowableArray<oop>* _visit_stack; // the visit stack 2695 2696 bool _collecting_heap_roots; // are we collecting roots 2697 bool _following_object_refs; // are we following object references 2698 2699 bool _reporting_primitive_fields; // optional reporting 2700 bool _reporting_primitive_array_values; 2701 bool _reporting_string_values; 2702 2703 GrowableArray<oop>* create_visit_stack() { 2704 return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true); 2705 } 2706 2707 // accessors 2708 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; } 2709 JvmtiTagMap* tag_map() const { return _tag_map; } 2710 Handle initial_object() const { return _initial_object; } 2711 2712 bool is_following_references() const { return _following_object_refs; } 2713 2714 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; } 2715 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; } 2716 bool is_reporting_string_values() const { return _reporting_string_values; } 2717 2718 GrowableArray<oop>* visit_stack() const { return _visit_stack; } 2719 2720 // iterate over the various object types 2721 inline bool iterate_over_array(oop o); 2722 inline bool iterate_over_type_array(oop o); 2723 inline bool iterate_over_class(klassOop o); 2724 inline bool iterate_over_object(oop o); 2725 2726 // root collection 2727 inline bool collect_simple_roots(); 2728 inline bool collect_stack_roots(); 2729 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk); 2730 2731 // visit an object 2732 inline bool visit(oop o); 2733 2734 public: 2735 VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2736 Handle initial_object, 2737 BasicHeapWalkContext callbacks, 2738 const void* user_data); 2739 2740 VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2741 Handle initial_object, 2742 AdvancedHeapWalkContext callbacks, 2743 const void* user_data); 2744 2745 ~VM_HeapWalkOperation(); 2746 2747 VMOp_Type type() const { return VMOp_HeapWalkOperation; } 2748 void doit(); 2749 }; 2750 2751 2752 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2753 Handle initial_object, 2754 BasicHeapWalkContext callbacks, 2755 const void* user_data) { 2756 _is_advanced_heap_walk = false; 2757 _tag_map = tag_map; 2758 _initial_object = initial_object; 2759 _following_object_refs = (callbacks.object_ref_callback() != NULL); 2760 _reporting_primitive_fields = false; 2761 _reporting_primitive_array_values = false; 2762 _reporting_string_values = false; 2763 _visit_stack = create_visit_stack(); 2764 2765 2766 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks); 2767 } 2768 2769 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, 2770 Handle initial_object, 2771 AdvancedHeapWalkContext callbacks, 2772 const void* user_data) { 2773 _is_advanced_heap_walk = true; 2774 _tag_map = tag_map; 2775 _initial_object = initial_object; 2776 _following_object_refs = true; 2777 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);; 2778 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);; 2779 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);; 2780 _visit_stack = create_visit_stack(); 2781 2782 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks); 2783 } 2784 2785 VM_HeapWalkOperation::~VM_HeapWalkOperation() { 2786 if (_following_object_refs) { 2787 assert(_visit_stack != NULL, "checking"); 2788 delete _visit_stack; 2789 _visit_stack = NULL; 2790 } 2791 } 2792 2793 // an array references its class and has a reference to 2794 // each element in the array 2795 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) { 2796 objArrayOop array = objArrayOop(o); 2797 if (array->klass() == Universe::systemObjArrayKlassObj()) { 2798 // filtered out 2799 return true; 2800 } 2801 2802 // array reference to its class 2803 oop mirror = objArrayKlass::cast(array->klass())->java_mirror(); 2804 if (!CallbackInvoker::report_class_reference(o, mirror)) { 2805 return false; 2806 } 2807 2808 // iterate over the array and report each reference to a 2809 // non-null element 2810 for (int index=0; index<array->length(); index++) { 2811 oop elem = array->obj_at(index); 2812 if (elem == NULL) { 2813 continue; 2814 } 2815 2816 // report the array reference o[index] = elem 2817 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) { 2818 return false; 2819 } 2820 } 2821 return true; 2822 } 2823 2824 // a type array references its class 2825 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) { 2826 klassOop k = o->klass(); 2827 oop mirror = Klass::cast(k)->java_mirror(); 2828 if (!CallbackInvoker::report_class_reference(o, mirror)) { 2829 return false; 2830 } 2831 2832 // report the array contents if required 2833 if (is_reporting_primitive_array_values()) { 2834 if (!CallbackInvoker::report_primitive_array_values(o)) { 2835 return false; 2836 } 2837 } 2838 return true; 2839 } 2840 2841 // verify that a static oop field is in range 2842 static inline bool verify_static_oop(instanceKlass* ik, 2843 oop mirror, int offset) { 2844 address obj_p = (address)mirror + offset; 2845 address start = (address)instanceMirrorKlass::start_of_static_fields(mirror); 2846 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize); 2847 assert(end >= start, "sanity check"); 2848 2849 if (obj_p >= start && obj_p < end) { 2850 return true; 2851 } else { 2852 return false; 2853 } 2854 } 2855 2856 // a class references its super class, interfaces, class loader, ... 2857 // and finally its static fields 2858 inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) { 2859 int i; 2860 Klass* klass = klassOop(k)->klass_part(); 2861 2862 if (klass->oop_is_instance()) { 2863 instanceKlass* ik = instanceKlass::cast(k); 2864 2865 // ignore the class if it's has been initialized yet 2866 if (!ik->is_linked()) { 2867 return true; 2868 } 2869 2870 // get the java mirror 2871 oop mirror = klass->java_mirror(); 2872 2873 // super (only if something more interesting than java.lang.Object) 2874 klassOop java_super = ik->java_super(); 2875 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) { 2876 oop super = Klass::cast(java_super)->java_mirror(); 2877 if (!CallbackInvoker::report_superclass_reference(mirror, super)) { 2878 return false; 2879 } 2880 } 2881 2882 // class loader 2883 oop cl = ik->class_loader(); 2884 if (cl != NULL) { 2885 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) { 2886 return false; 2887 } 2888 } 2889 2890 // protection domain 2891 oop pd = ik->protection_domain(); 2892 if (pd != NULL) { 2893 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) { 2894 return false; 2895 } 2896 } 2897 2898 // signers 2899 oop signers = ik->signers(); 2900 if (signers != NULL) { 2901 if (!CallbackInvoker::report_signers_reference(mirror, signers)) { 2902 return false; 2903 } 2904 } 2905 2906 // references from the constant pool 2907 { 2908 const constantPoolOop pool = ik->constants(); 2909 for (int i = 1; i < pool->length(); i++) { 2910 constantTag tag = pool->tag_at(i).value(); 2911 if (tag.is_string() || tag.is_klass()) { 2912 oop entry; 2913 if (tag.is_string()) { 2914 entry = pool->resolved_string_at(i); 2915 assert(java_lang_String::is_instance(entry), "must be string"); 2916 } else { 2917 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror(); 2918 } 2919 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) { 2920 return false; 2921 } 2922 } 2923 } 2924 } 2925 2926 // interfaces 2927 // (These will already have been reported as references from the constant pool 2928 // but are specified by IterateOverReachableObjects and must be reported). 2929 objArrayOop interfaces = ik->local_interfaces(); 2930 for (i = 0; i < interfaces->length(); i++) { 2931 oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror(); 2932 if (interf == NULL) { 2933 continue; 2934 } 2935 if (!CallbackInvoker::report_interface_reference(mirror, interf)) { 2936 return false; 2937 } 2938 } 2939 2940 // iterate over the static fields 2941 2942 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k); 2943 for (i=0; i<field_map->field_count(); i++) { 2944 ClassFieldDescriptor* field = field_map->field_at(i); 2945 char type = field->field_type(); 2946 if (!is_primitive_field_type(type)) { 2947 oop fld_o = mirror->obj_field(field->field_offset()); 2948 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check"); 2949 if (fld_o != NULL) { 2950 int slot = field->field_index(); 2951 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) { 2952 delete field_map; 2953 return false; 2954 } 2955 } 2956 } else { 2957 if (is_reporting_primitive_fields()) { 2958 address addr = (address)mirror + field->field_offset(); 2959 int slot = field->field_index(); 2960 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) { 2961 delete field_map; 2962 return false; 2963 } 2964 } 2965 } 2966 } 2967 delete field_map; 2968 2969 return true; 2970 } 2971 2972 return true; 2973 } 2974 2975 // an object references a class and its instance fields 2976 // (static fields are ignored here as we report these as 2977 // references from the class). 2978 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) { 2979 // reference to the class 2980 if (!CallbackInvoker::report_class_reference(o, Klass::cast(o->klass())->java_mirror())) { 2981 return false; 2982 } 2983 2984 // iterate over instance fields 2985 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o); 2986 for (int i=0; i<field_map->field_count(); i++) { 2987 ClassFieldDescriptor* field = field_map->field_at(i); 2988 char type = field->field_type(); 2989 if (!is_primitive_field_type(type)) { 2990 oop fld_o = o->obj_field(field->field_offset()); 2991 if (fld_o != NULL) { 2992 // reflection code may have a reference to a klassOop. 2993 // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe 2994 if (fld_o->is_klass()) { 2995 klassOop k = (klassOop)fld_o; 2996 fld_o = Klass::cast(k)->java_mirror(); 2997 } 2998 int slot = field->field_index(); 2999 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { 3000 return false; 3001 } 3002 } 3003 } else { 3004 if (is_reporting_primitive_fields()) { 3005 // primitive instance field 3006 address addr = (address)o + field->field_offset(); 3007 int slot = field->field_index(); 3008 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) { 3009 return false; 3010 } 3011 } 3012 } 3013 } 3014 3015 // if the object is a java.lang.String 3016 if (is_reporting_string_values() && 3017 o->klass() == SystemDictionary::String_klass()) { 3018 if (!CallbackInvoker::report_string_value(o)) { 3019 return false; 3020 } 3021 } 3022 return true; 3023 } 3024 3025 3026 // collects all simple (non-stack) roots. 3027 // if there's a heap root callback provided then the callback is 3028 // invoked for each simple root. 3029 // if an object reference callback is provided then all simple 3030 // roots are pushed onto the marking stack so that they can be 3031 // processed later 3032 // 3033 inline bool VM_HeapWalkOperation::collect_simple_roots() { 3034 SimpleRootsClosure blk; 3035 3036 // JNI globals 3037 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL); 3038 JNIHandles::oops_do(&blk); 3039 if (blk.stopped()) { 3040 return false; 3041 } 3042 3043 // Preloaded classes and loader from the system dictionary 3044 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS); 3045 SystemDictionary::always_strong_oops_do(&blk); 3046 if (blk.stopped()) { 3047 return false; 3048 } 3049 3050 // Inflated monitors 3051 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR); 3052 ObjectSynchronizer::oops_do(&blk); 3053 if (blk.stopped()) { 3054 return false; 3055 } 3056 3057 // Threads 3058 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 3059 oop threadObj = thread->threadObj(); 3060 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 3061 bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj); 3062 if (!cont) { 3063 return false; 3064 } 3065 } 3066 } 3067 3068 // Other kinds of roots maintained by HotSpot 3069 // Many of these won't be visible but others (such as instances of important 3070 // exceptions) will be visible. 3071 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); 3072 Universe::oops_do(&blk); 3073 3074 // If there are any non-perm roots in the code cache, visit them. 3075 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); 3076 CodeBlobToOopClosure look_in_blobs(&blk, false); 3077 CodeCache::scavenge_root_nmethods_do(&look_in_blobs); 3078 3079 return true; 3080 } 3081 3082 // Walk the stack of a given thread and find all references (locals 3083 // and JNI calls) and report these as stack references 3084 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread, 3085 JNILocalRootsClosure* blk) 3086 { 3087 oop threadObj = java_thread->threadObj(); 3088 assert(threadObj != NULL, "sanity check"); 3089 3090 // only need to get the thread's tag once per thread 3091 jlong thread_tag = tag_for(_tag_map, threadObj); 3092 3093 // also need the thread id 3094 jlong tid = java_lang_Thread::thread_id(threadObj); 3095 3096 3097 if (java_thread->has_last_Java_frame()) { 3098 3099 // vframes are resource allocated 3100 Thread* current_thread = Thread::current(); 3101 ResourceMark rm(current_thread); 3102 HandleMark hm(current_thread); 3103 3104 RegisterMap reg_map(java_thread); 3105 frame f = java_thread->last_frame(); 3106 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread); 3107 3108 bool is_top_frame = true; 3109 int depth = 0; 3110 frame* last_entry_frame = NULL; 3111 3112 while (vf != NULL) { 3113 if (vf->is_java_frame()) { 3114 3115 // java frame (interpreted, compiled, ...) 3116 javaVFrame *jvf = javaVFrame::cast(vf); 3117 3118 // the jmethodID 3119 jmethodID method = jvf->method()->jmethod_id(); 3120 3121 if (!(jvf->method()->is_native())) { 3122 jlocation bci = (jlocation)jvf->bci(); 3123 StackValueCollection* locals = jvf->locals(); 3124 for (int slot=0; slot<locals->size(); slot++) { 3125 if (locals->at(slot)->type() == T_OBJECT) { 3126 oop o = locals->obj_at(slot)(); 3127 if (o == NULL) { 3128 continue; 3129 } 3130 3131 // stack reference 3132 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method, 3133 bci, slot, o)) { 3134 return false; 3135 } 3136 } 3137 } 3138 } else { 3139 blk->set_context(thread_tag, tid, depth, method); 3140 if (is_top_frame) { 3141 // JNI locals for the top frame. 3142 java_thread->active_handles()->oops_do(blk); 3143 } else { 3144 if (last_entry_frame != NULL) { 3145 // JNI locals for the entry frame 3146 assert(last_entry_frame->is_entry_frame(), "checking"); 3147 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk); 3148 } 3149 } 3150 } 3151 last_entry_frame = NULL; 3152 depth++; 3153 } else { 3154 // externalVFrame - for an entry frame then we report the JNI locals 3155 // when we find the corresponding javaVFrame 3156 frame* fr = vf->frame_pointer(); 3157 assert(fr != NULL, "sanity check"); 3158 if (fr->is_entry_frame()) { 3159 last_entry_frame = fr; 3160 } 3161 } 3162 3163 vf = vf->sender(); 3164 is_top_frame = false; 3165 } 3166 } else { 3167 // no last java frame but there may be JNI locals 3168 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL); 3169 java_thread->active_handles()->oops_do(blk); 3170 } 3171 return true; 3172 } 3173 3174 3175 // collects all stack roots - for each thread it walks the execution 3176 // stack to find all references and local JNI refs. 3177 inline bool VM_HeapWalkOperation::collect_stack_roots() { 3178 JNILocalRootsClosure blk; 3179 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 3180 oop threadObj = thread->threadObj(); 3181 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 3182 if (!collect_stack_roots(thread, &blk)) { 3183 return false; 3184 } 3185 } 3186 } 3187 return true; 3188 } 3189 3190 // visit an object 3191 // first mark the object as visited 3192 // second get all the outbound references from this object (in other words, all 3193 // the objects referenced by this object). 3194 // 3195 bool VM_HeapWalkOperation::visit(oop o) { 3196 // mark object as visited 3197 assert(!ObjectMarker::visited(o), "can't visit same object more than once"); 3198 ObjectMarker::mark(o); 3199 3200 // instance 3201 if (o->is_instance()) { 3202 if (o->klass() == SystemDictionary::Class_klass()) { 3203 o = klassOop_if_java_lang_Class(o); 3204 if (o->is_klass()) { 3205 // a java.lang.Class 3206 return iterate_over_class(klassOop(o)); 3207 } 3208 } else { 3209 return iterate_over_object(o); 3210 } 3211 } 3212 3213 // object array 3214 if (o->is_objArray()) { 3215 return iterate_over_array(o); 3216 } 3217 3218 // type array 3219 if (o->is_typeArray()) { 3220 return iterate_over_type_array(o); 3221 } 3222 3223 return true; 3224 } 3225 3226 void VM_HeapWalkOperation::doit() { 3227 ResourceMark rm; 3228 ObjectMarkerController marker; 3229 ClassFieldMapCacheMark cm; 3230 3231 assert(visit_stack()->is_empty(), "visit stack must be empty"); 3232 3233 // the heap walk starts with an initial object or the heap roots 3234 if (initial_object().is_null()) { 3235 if (!collect_simple_roots()) return; 3236 if (!collect_stack_roots()) return; 3237 } else { 3238 visit_stack()->push(initial_object()()); 3239 } 3240 3241 // object references required 3242 if (is_following_references()) { 3243 3244 // visit each object until all reachable objects have been 3245 // visited or the callback asked to terminate the iteration. 3246 while (!visit_stack()->is_empty()) { 3247 oop o = visit_stack()->pop(); 3248 if (!ObjectMarker::visited(o)) { 3249 if (!visit(o)) { 3250 break; 3251 } 3252 } 3253 } 3254 } 3255 } 3256 3257 // iterate over all objects that are reachable from a set of roots 3258 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback, 3259 jvmtiStackReferenceCallback stack_ref_callback, 3260 jvmtiObjectReferenceCallback object_ref_callback, 3261 const void* user_data) { 3262 MutexLocker ml(Heap_lock); 3263 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback); 3264 VM_HeapWalkOperation op(this, Handle(), context, user_data); 3265 VMThread::execute(&op); 3266 } 3267 3268 // iterate over all objects that are reachable from a given object 3269 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object, 3270 jvmtiObjectReferenceCallback object_ref_callback, 3271 const void* user_data) { 3272 oop obj = JNIHandles::resolve(object); 3273 Handle initial_object(Thread::current(), obj); 3274 3275 MutexLocker ml(Heap_lock); 3276 BasicHeapWalkContext context(NULL, NULL, object_ref_callback); 3277 VM_HeapWalkOperation op(this, initial_object, context, user_data); 3278 VMThread::execute(&op); 3279 } 3280 3281 // follow references from an initial object or the GC roots 3282 void JvmtiTagMap::follow_references(jint heap_filter, 3283 KlassHandle klass, 3284 jobject object, 3285 const jvmtiHeapCallbacks* callbacks, 3286 const void* user_data) 3287 { 3288 oop obj = JNIHandles::resolve(object); 3289 Handle initial_object(Thread::current(), obj); 3290 3291 MutexLocker ml(Heap_lock); 3292 AdvancedHeapWalkContext context(heap_filter, klass, callbacks); 3293 VM_HeapWalkOperation op(this, initial_object, context, user_data); 3294 VMThread::execute(&op); 3295 } 3296 3297 3298 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 3299 // No locks during VM bring-up (0 threads) and no safepoints after main 3300 // thread creation and before VMThread creation (1 thread); initial GC 3301 // verification can happen in that window which gets to here. 3302 assert(Threads::number_of_threads() <= 1 || 3303 SafepointSynchronize::is_at_safepoint(), 3304 "must be executed at a safepoint"); 3305 if (JvmtiEnv::environments_might_exist()) { 3306 JvmtiEnvIterator it; 3307 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { 3308 JvmtiTagMap* tag_map = env->tag_map(); 3309 if (tag_map != NULL && !tag_map->is_empty()) { 3310 tag_map->do_weak_oops(is_alive, f); 3311 } 3312 } 3313 } 3314 } 3315 3316 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) { 3317 3318 // does this environment have the OBJECT_FREE event enabled 3319 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE); 3320 3321 // counters used for trace message 3322 int freed = 0; 3323 int moved = 0; 3324 3325 JvmtiTagHashmap* hashmap = this->hashmap(); 3326 3327 // reenable sizing (if disabled) 3328 hashmap->set_resizing_enabled(true); 3329 3330 // if the hashmap is empty then we can skip it 3331 if (hashmap->_entry_count == 0) { 3332 return; 3333 } 3334 3335 // now iterate through each entry in the table 3336 3337 JvmtiTagHashmapEntry** table = hashmap->table(); 3338 int size = hashmap->size(); 3339 3340 JvmtiTagHashmapEntry* delayed_add = NULL; 3341 3342 for (int pos = 0; pos < size; ++pos) { 3343 JvmtiTagHashmapEntry* entry = table[pos]; 3344 JvmtiTagHashmapEntry* prev = NULL; 3345 3346 while (entry != NULL) { 3347 JvmtiTagHashmapEntry* next = entry->next(); 3348 3349 oop* obj = entry->object_addr(); 3350 3351 // has object been GC'ed 3352 if (!is_alive->do_object_b(entry->object())) { 3353 // grab the tag 3354 jlong tag = entry->tag(); 3355 guarantee(tag != 0, "checking"); 3356 3357 // remove GC'ed entry from hashmap and return the 3358 // entry to the free list 3359 hashmap->remove(prev, pos, entry); 3360 destroy_entry(entry); 3361 3362 // post the event to the profiler 3363 if (post_object_free) { 3364 JvmtiExport::post_object_free(env(), tag); 3365 } 3366 3367 ++freed; 3368 } else { 3369 f->do_oop(entry->object_addr()); 3370 oop new_oop = entry->object(); 3371 3372 // if the object has moved then re-hash it and move its 3373 // entry to its new location. 3374 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size); 3375 if (new_pos != (unsigned int)pos) { 3376 if (prev == NULL) { 3377 table[pos] = next; 3378 } else { 3379 prev->set_next(next); 3380 } 3381 if (new_pos < (unsigned int)pos) { 3382 entry->set_next(table[new_pos]); 3383 table[new_pos] = entry; 3384 } else { 3385 // Delay adding this entry to it's new position as we'd end up 3386 // hitting it again during this iteration. 3387 entry->set_next(delayed_add); 3388 delayed_add = entry; 3389 } 3390 moved++; 3391 } else { 3392 // object didn't move 3393 prev = entry; 3394 } 3395 } 3396 3397 entry = next; 3398 } 3399 } 3400 3401 // Re-add all the entries which were kept aside 3402 while (delayed_add != NULL) { 3403 JvmtiTagHashmapEntry* next = delayed_add->next(); 3404 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size); 3405 delayed_add->set_next(table[pos]); 3406 table[pos] = delayed_add; 3407 delayed_add = next; 3408 } 3409 3410 // stats 3411 if (TraceJVMTIObjectTagging) { 3412 int post_total = hashmap->_entry_count; 3413 int pre_total = post_total + freed; 3414 3415 tty->print_cr("(%d->%d, %d freed, %d total moves)", 3416 pre_total, post_total, freed, moved); 3417 } 3418 }