Tue, 13 Mar 2012 13:50:48 -0400
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
Summary: Fold instanceKlass::_enclosing_method_class_index and instanceKlass::_enclosing_method_method_index into the instanceKlass::_inner_classes array.
Reviewed-by: never, coleenp
Contributed-by: Jiangli Zhou <jiangli.zhou@oracle.com>
1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
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
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.
58 class JvmtiTagHashmapEntry : public CHeapObj {
59 private:
60 friend class JvmtiTagMap;
62 oop _object; // tagged object
63 jlong _tag; // the tag
64 JvmtiTagHashmapEntry* _next; // next on the list
66 inline void init(oop object, jlong tag) {
67 _object = object;
68 _tag = tag;
69 _next = NULL;
70 }
72 // constructor
73 JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); }
75 public:
77 // accessor methods
78 inline oop object() const { return _object; }
79 inline oop* object_addr() { return &_object; }
80 inline jlong tag() const { return _tag; }
82 inline void set_tag(jlong tag) {
83 assert(tag != 0, "can't be zero");
84 _tag = tag;
85 }
87 inline JvmtiTagHashmapEntry* next() const { return _next; }
88 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; }
89 };
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.
109 class JvmtiTagHashmap : public CHeapObj {
110 private:
111 friend class JvmtiTagMap;
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 };
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
124 int _entry_count; // number of entries in the hashmap
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
130 int _trace_threshold; // threshold for trace messages
132 JvmtiTagHashmapEntry** _table; // the table of entries.
134 // private accessors
135 int resize_threshold() const { return _resize_threshold; }
136 int trace_threshold() const { return _trace_threshold; }
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 }
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 }
174 // hash a given key (oop)
175 unsigned int hash(oop key) {
176 return hash(key, _size);
177 }
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 }
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 }
198 // initialize new table
199 int i;
200 for (i=0; i<new_size; i++) {
201 new_table[i] = NULL;
202 }
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 }
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;
230 // compute new resize threshold
231 _resize_threshold = (int)(_load_factor * _size);
232 }
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 }
248 // resizing switch
249 bool is_resizing_enabled() const { return _resizing_enabled; }
250 void set_resizing_enabled(bool enable) { _resizing_enabled = enable; }
252 // debugging
253 void print_memory_usage();
254 void compute_next_trace_threshold();
256 public:
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 }
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 }
279 // create a JvmtiTagHashmap with default settings
280 JvmtiTagHashmap() {
281 init();
282 }
284 // release table when JvmtiTagHashmap destroyed
285 ~JvmtiTagHashmap() {
286 if (_table != NULL) {
287 os::free((void*)_table);
288 _table = NULL;
289 }
290 }
292 // accessors
293 int size() const { return _size; }
294 JvmtiTagHashmapEntry** table() const { return _table; }
295 int entry_count() const { return _entry_count; }
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 }
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 }
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 }
332 // if the number of entries exceed the threshold then resize
333 if (entry_count() > resize_threshold() && is_resizing_enabled()) {
334 resize();
335 }
336 }
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 }
356 // iterate over all entries in the hashmap
357 void entry_iterate(JvmtiTagHashmapEntryClosure* closure);
358 };
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 };
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 };
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 }
390 // debugging
391 void JvmtiTagHashmap::print_memory_usage() {
392 intptr_t p = (intptr_t)this;
393 tty->print("[JvmtiTagHashmap @ " INTPTR_FORMAT, p);
395 // table + entries in KB
396 int hashmap_usage = (size()*sizeof(JvmtiTagHashmapEntry*) +
397 entry_count()*sizeof(JvmtiTagHashmapEntry))/K;
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 }
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 }
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");
427 _hashmap = new JvmtiTagHashmap();
429 // finally add us to the environment
430 ((JvmtiEnvBase *)env)->set_tag_map(this);
431 }
434 // destroy a JvmtiTagMap
435 JvmtiTagMap::~JvmtiTagMap() {
437 // no lock acquired as we assume the enclosing environment is
438 // also being destroryed.
439 ((JvmtiEnvBase *)_env)->set_tag_map(NULL);
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 }
451 // finally destroy the hashmap
452 delete _hashmap;
453 _hashmap = NULL;
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 }
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 }
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 }
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 }
512 // iterate over all entries in the tag map.
513 void JvmtiTagMap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) {
514 hashmap()->entry_iterate(closure);
515 }
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 }
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 }
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 }
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;
573 protected:
574 JvmtiTagMap* tag_map() const { return _tag_map; }
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");
584 // for Classes the klassOop is tagged
585 _o = klassOop_if_java_lang_Class(o);
587 // object size
588 _obj_size = _o->size() * wordSize;
590 // record the context
591 _tag_map = tag_map;
592 _hashmap = tag_map->hashmap();
593 _entry = _hashmap->find(_o);
595 // get object tag
596 _obj_tag = (_entry == NULL) ? 0 : _entry->tag();
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 }
609 ~CallbackWrapper() {
610 post_callback_tag_update(_o, _hashmap, _entry, _obj_tag);
611 }
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 };
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) {
639 JvmtiTagHashmapEntry* entry_removed = hashmap->remove(o);
640 assert(entry_removed == entry, "checking");
641 tag_map()->destroy_entry(entry);
643 } else {
644 if (obj_tag != entry->tag()) {
645 entry->set_tag(obj_tag);
646 }
647 }
648 }
649 }
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;
676 bool is_reference_to_self() const { return _is_reference_to_self; }
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);
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);
695 // get object tag
696 _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag();
697 _referrer_tag_p = &_referrer_obj_tag;
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 }
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 }
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; }
720 // referrer's class tag
721 inline jlong referrer_klass_tag() { return _referrer_klass_tag; }
722 };
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());
732 // resolve the object
733 oop o = JNIHandles::resolve_non_null(object);
735 // for Classes we tag the klassOop
736 o = klassOop_if_java_lang_Class(o);
738 // see if the object is already tagged
739 JvmtiTagHashmap* hashmap = _hashmap;
740 JvmtiTagHashmapEntry* entry = hashmap->find(o);
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 }
763 // get the tag for an object
764 jlong JvmtiTagMap::get_tag(jobject object) {
765 MutexLocker ml(lock());
767 // resolve the object
768 oop o = JNIHandles::resolve_non_null(object);
770 // for Classes get the tag from the klassOop
771 return tag_for(this, klassOop_if_java_lang_Class(o));
772 }
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.
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 };
793 class ClassFieldMap: public CHeapObj {
794 private:
795 enum {
796 initial_field_count = 5
797 };
799 // list of field descriptors
800 GrowableArray<ClassFieldDescriptor*>* _fields;
802 // constructor
803 ClassFieldMap();
805 // add a field
806 void add(int index, char type, int offset);
808 // returns the field count for the given class
809 static int compute_field_count(instanceKlassHandle ikh);
811 public:
812 ~ClassFieldMap();
814 // access
815 int field_count() { return _fields->length(); }
816 ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
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 };
823 ClassFieldMap::ClassFieldMap() {
824 _fields = new (ResourceObj::C_HEAP) GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
825 }
827 ClassFieldMap::~ClassFieldMap() {
828 for (int i=0; i<_fields->length(); i++) {
829 delete _fields->at(i);
830 }
831 delete _fields;
832 }
834 void ClassFieldMap::add(int index, char type, int offset) {
835 ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset);
836 _fields->append(field);
837 }
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);
846 // create the field map
847 ClassFieldMap* field_map = new ClassFieldMap();
849 FilteredFieldStream f(ikh, false, false);
850 int max_field_index = f.field_count()-1;
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 }
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());
871 // create the field map
872 ClassFieldMap* field_map = new ClassFieldMap();
874 FilteredFieldStream f(ikh, false, false);
876 int max_field_index = f.field_count()-1;
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 }
887 return field_map;
888 }
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;
902 ClassFieldMap* field_map() const { return _field_map; }
904 JvmtiCachedClassFieldMap(ClassFieldMap* field_map);
905 ~JvmtiCachedClassFieldMap();
907 static GrowableArray<instanceKlass*>* _class_list;
908 static void add_to_class_list(instanceKlass* ik);
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);
915 // removes the field map from all instanceKlasses - should be
916 // called before VM operation completes
917 static void clear_cache();
919 // returns the number of ClassFieldMap cached by instanceKlasses
920 static int cached_field_map_count();
921 };
923 GrowableArray<instanceKlass*>* JvmtiCachedClassFieldMap::_class_list;
925 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) {
926 _field_map = field_map;
927 }
929 JvmtiCachedClassFieldMap::~JvmtiCachedClassFieldMap() {
930 if (_field_map != NULL) {
931 delete _field_map;
932 }
933 }
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 };
954 bool ClassFieldMapCacheMark::_is_active;
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 }
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");
971 klassOop k = obj->klass();
972 instanceKlass* ik = instanceKlass::cast(k);
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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");
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 }
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 }
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");
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);
1105 // jvmtiPrimitiveType is defined so this mapping is always correct
1106 jvmtiPrimitiveType elem_type = (jvmtiPrimitiveType)type2char(type);
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 }
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 };
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();
1135 // ignore classes for object and type arrays
1136 if (!klass->oop_is_instance()) {
1137 return 0;
1138 }
1140 // ignore classes which aren't linked yet
1141 instanceKlass* ik = instanceKlass::cast(k);
1142 if (!ik->is_linked()) {
1143 return 0;
1144 }
1146 // get the field map
1147 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
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);
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;
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);
1167 // field index
1168 reference_info.field.index = field->field_index();
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 }
1184 delete field_map;
1185 return 0;
1186 }
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 };
1199 // get the map of the instance fields
1200 ClassFieldMap* fields = JvmtiCachedClassFieldMap::get_map_of_instance_fields(obj);
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);
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;
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);
1220 // field index
1221 reference_info.field.index = field->field_index();
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 }
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; }
1247 VMOp_Type type() const { return VMOp_HeapIterateOperation; }
1248 void doit() {
1249 // allows class files maps to be cached during iteration
1250 ClassFieldMapCacheMark cm;
1252 // make sure that heap is parsable (fills TLABs with filler objects)
1253 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
1255 // Verify heap before iteration - if the heap gets corrupted then
1256 // JVMTI's IterateOverHeap will crash.
1257 if (VerifyBeforeIteration) {
1258 Universe::verify();
1259 }
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);
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 }
1276 };
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;
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; }
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; }
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 }
1316 void do_object(oop o);
1317 };
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;
1324 // ignore any objects that aren't visible to profiler
1325 if (!ServiceUtil::visible_oop(o)) return;
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);
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 }
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 }
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;
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; }
1369 // indicates if the iteration has been aborted
1370 bool _iteration_aborted;
1371 bool is_iteration_aborted() const { return _iteration_aborted; }
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 }
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 }
1399 void do_object(oop o);
1400 };
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;
1407 // ignore any objects that aren't visible to profiler
1408 if (!ServiceUtil::visible_oop(obj)) return;
1410 // apply class filter
1411 if (is_filtered_by_klass_filter(obj, klass())) return;
1413 // prepare for callback
1414 CallbackWrapper wrapper(tag_map(), obj);
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 }
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;
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 }
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 }
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 }
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 };
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 }
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 }
1513 // support class for get_objects_with_tags
1515 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
1516 private:
1517 JvmtiEnv* _env;
1518 jlong* _tags;
1519 jint _tag_count;
1521 GrowableArray<jobject>* _object_results; // collected objects (JNI weak refs)
1522 GrowableArray<uint64_t>* _tag_results; // collected tags
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 }
1533 ~TagObjectCollector() {
1534 delete _object_results;
1535 delete _tag_results;
1536 }
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");
1548 // the mirror is tagged
1549 if (o->is_klass()) {
1550 klassOop k = (klassOop)o;
1551 o = Klass::cast(k)->java_mirror();
1552 }
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 }
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");
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 }
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 }
1595 *count_ptr = count;
1596 return JVMTI_ERROR_NONE;
1597 }
1598 };
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) {
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 }
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 //
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 };
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 static bool _needs_reset; // do we need to reset mark bits?
1652 public:
1653 static void init(); // initialize
1654 static void done(); // clean-up
1656 static inline void mark(oop o); // mark an object
1657 static inline bool visited(oop o); // check if object has been visited
1659 static inline bool needs_reset() { return _needs_reset; }
1660 static inline void set_needs_reset(bool v) { _needs_reset = v; }
1661 };
1663 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1664 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
1665 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default
1667 // initialize ObjectMarker - prepares for object marking
1668 void ObjectMarker::init() {
1669 assert(Thread::current()->is_VM_thread(), "must be VMThread");
1671 // prepare heap for iteration
1672 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
1674 // create stacks for interesting headers
1675 _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true);
1676 _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
1678 if (UseBiasedLocking) {
1679 BiasedLocking::preserve_marks();
1680 }
1681 }
1683 // Object marking is done so restore object headers
1684 void ObjectMarker::done() {
1685 // iterate over all objects and restore the mark bits to
1686 // their initial value
1687 RestoreMarksClosure blk;
1688 if (needs_reset()) {
1689 Universe::heap()->object_iterate(&blk);
1690 } else {
1691 // We don't need to reset mark bits on this call, but reset the
1692 // flag to the default for the next call.
1693 set_needs_reset(true);
1694 }
1696 // When sharing is enabled we need to restore the headers of the objects
1697 // in the readwrite space too.
1698 if (UseSharedSpaces) {
1699 GenCollectedHeap* gch = GenCollectedHeap::heap();
1700 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen();
1701 gen->rw_space()->object_iterate(&blk);
1702 }
1704 // now restore the interesting headers
1705 for (int i = 0; i < _saved_oop_stack->length(); i++) {
1706 oop o = _saved_oop_stack->at(i);
1707 markOop mark = _saved_mark_stack->at(i);
1708 o->set_mark(mark);
1709 }
1711 if (UseBiasedLocking) {
1712 BiasedLocking::restore_marks();
1713 }
1715 // free the stacks
1716 delete _saved_oop_stack;
1717 delete _saved_mark_stack;
1718 }
1720 // mark an object
1721 inline void ObjectMarker::mark(oop o) {
1722 assert(Universe::heap()->is_in(o), "sanity check");
1723 assert(!o->mark()->is_marked(), "should only mark an object once");
1725 // object's mark word
1726 markOop mark = o->mark();
1728 if (mark->must_be_preserved(o)) {
1729 _saved_mark_stack->push(mark);
1730 _saved_oop_stack->push(o);
1731 }
1733 // mark the object
1734 o->set_mark(markOopDesc::prototype()->set_marked());
1735 }
1737 // return true if object is marked
1738 inline bool ObjectMarker::visited(oop o) {
1739 return o->mark()->is_marked();
1740 }
1742 // Stack allocated class to help ensure that ObjectMarker is used
1743 // correctly. Constructor initializes ObjectMarker, destructor calls
1744 // ObjectMarker's done() function to restore object headers.
1745 class ObjectMarkerController : public StackObj {
1746 public:
1747 ObjectMarkerController() {
1748 ObjectMarker::init();
1749 }
1750 ~ObjectMarkerController() {
1751 ObjectMarker::done();
1752 }
1753 };
1756 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1757 // (not performance critical as only used for roots)
1758 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1759 switch (kind) {
1760 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1761 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1762 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
1763 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
1764 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
1765 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
1766 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
1767 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
1768 }
1769 }
1771 // Base class for all heap walk contexts. The base class maintains a flag
1772 // to indicate if the context is valid or not.
1773 class HeapWalkContext VALUE_OBJ_CLASS_SPEC {
1774 private:
1775 bool _valid;
1776 public:
1777 HeapWalkContext(bool valid) { _valid = valid; }
1778 void invalidate() { _valid = false; }
1779 bool is_valid() const { return _valid; }
1780 };
1782 // A basic heap walk context for the deprecated heap walking functions.
1783 // The context for a basic heap walk are the callbacks and fields used by
1784 // the referrer caching scheme.
1785 class BasicHeapWalkContext: public HeapWalkContext {
1786 private:
1787 jvmtiHeapRootCallback _heap_root_callback;
1788 jvmtiStackReferenceCallback _stack_ref_callback;
1789 jvmtiObjectReferenceCallback _object_ref_callback;
1791 // used for caching
1792 oop _last_referrer;
1793 jlong _last_referrer_tag;
1795 public:
1796 BasicHeapWalkContext() : HeapWalkContext(false) { }
1798 BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback,
1799 jvmtiStackReferenceCallback stack_ref_callback,
1800 jvmtiObjectReferenceCallback object_ref_callback) :
1801 HeapWalkContext(true),
1802 _heap_root_callback(heap_root_callback),
1803 _stack_ref_callback(stack_ref_callback),
1804 _object_ref_callback(object_ref_callback),
1805 _last_referrer(NULL),
1806 _last_referrer_tag(0) {
1807 }
1809 // accessors
1810 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; }
1811 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; }
1812 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; }
1814 oop last_referrer() const { return _last_referrer; }
1815 void set_last_referrer(oop referrer) { _last_referrer = referrer; }
1816 jlong last_referrer_tag() const { return _last_referrer_tag; }
1817 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
1818 };
1820 // The advanced heap walk context for the FollowReferences functions.
1821 // The context is the callbacks, and the fields used for filtering.
1822 class AdvancedHeapWalkContext: public HeapWalkContext {
1823 private:
1824 jint _heap_filter;
1825 KlassHandle _klass_filter;
1826 const jvmtiHeapCallbacks* _heap_callbacks;
1828 public:
1829 AdvancedHeapWalkContext() : HeapWalkContext(false) { }
1831 AdvancedHeapWalkContext(jint heap_filter,
1832 KlassHandle klass_filter,
1833 const jvmtiHeapCallbacks* heap_callbacks) :
1834 HeapWalkContext(true),
1835 _heap_filter(heap_filter),
1836 _klass_filter(klass_filter),
1837 _heap_callbacks(heap_callbacks) {
1838 }
1840 // accessors
1841 jint heap_filter() const { return _heap_filter; }
1842 KlassHandle klass_filter() const { return _klass_filter; }
1844 const jvmtiHeapReferenceCallback heap_reference_callback() const {
1845 return _heap_callbacks->heap_reference_callback;
1846 };
1847 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1848 return _heap_callbacks->primitive_field_callback;
1849 }
1850 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1851 return _heap_callbacks->array_primitive_value_callback;
1852 }
1853 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1854 return _heap_callbacks->string_primitive_value_callback;
1855 }
1856 };
1858 // The CallbackInvoker is a class with static functions that the heap walk can call
1859 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1860 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1861 // mode is for the newer FollowReferences function which supports a lot of
1862 // additional callbacks.
1863 class CallbackInvoker : AllStatic {
1864 private:
1865 // heap walk styles
1866 enum { basic, advanced };
1867 static int _heap_walk_type;
1868 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
1869 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
1871 // context for basic style heap walk
1872 static BasicHeapWalkContext _basic_context;
1873 static BasicHeapWalkContext* basic_context() {
1874 assert(_basic_context.is_valid(), "invalid");
1875 return &_basic_context;
1876 }
1878 // context for advanced style heap walk
1879 static AdvancedHeapWalkContext _advanced_context;
1880 static AdvancedHeapWalkContext* advanced_context() {
1881 assert(_advanced_context.is_valid(), "invalid");
1882 return &_advanced_context;
1883 }
1885 // context needed for all heap walks
1886 static JvmtiTagMap* _tag_map;
1887 static const void* _user_data;
1888 static GrowableArray<oop>* _visit_stack;
1890 // accessors
1891 static JvmtiTagMap* tag_map() { return _tag_map; }
1892 static const void* user_data() { return _user_data; }
1893 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
1895 // if the object hasn't been visited then push it onto the visit stack
1896 // so that it will be visited later
1897 static inline bool check_for_visit(oop obj) {
1898 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
1899 return true;
1900 }
1902 // invoke basic style callbacks
1903 static inline bool invoke_basic_heap_root_callback
1904 (jvmtiHeapRootKind root_kind, oop obj);
1905 static inline bool invoke_basic_stack_ref_callback
1906 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1907 int slot, oop obj);
1908 static inline bool invoke_basic_object_reference_callback
1909 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1911 // invoke advanced style callbacks
1912 static inline bool invoke_advanced_heap_root_callback
1913 (jvmtiHeapReferenceKind ref_kind, oop obj);
1914 static inline bool invoke_advanced_stack_ref_callback
1915 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1916 jmethodID method, jlocation bci, jint slot, oop obj);
1917 static inline bool invoke_advanced_object_reference_callback
1918 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1920 // used to report the value of primitive fields
1921 static inline bool report_primitive_field
1922 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
1924 public:
1925 // initialize for basic mode
1926 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1927 GrowableArray<oop>* visit_stack,
1928 const void* user_data,
1929 BasicHeapWalkContext context);
1931 // initialize for advanced mode
1932 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1933 GrowableArray<oop>* visit_stack,
1934 const void* user_data,
1935 AdvancedHeapWalkContext context);
1937 // functions to report roots
1938 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
1939 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
1940 jmethodID m, oop o);
1941 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
1942 jmethodID method, jlocation bci, jint slot, oop o);
1944 // functions to report references
1945 static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
1946 static inline bool report_class_reference(oop referrer, oop referree);
1947 static inline bool report_class_loader_reference(oop referrer, oop referree);
1948 static inline bool report_signers_reference(oop referrer, oop referree);
1949 static inline bool report_protection_domain_reference(oop referrer, oop referree);
1950 static inline bool report_superclass_reference(oop referrer, oop referree);
1951 static inline bool report_interface_reference(oop referrer, oop referree);
1952 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1953 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1954 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1955 static inline bool report_primitive_array_values(oop array);
1956 static inline bool report_string_value(oop str);
1957 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1958 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1959 };
1961 // statics
1962 int CallbackInvoker::_heap_walk_type;
1963 BasicHeapWalkContext CallbackInvoker::_basic_context;
1964 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1965 JvmtiTagMap* CallbackInvoker::_tag_map;
1966 const void* CallbackInvoker::_user_data;
1967 GrowableArray<oop>* CallbackInvoker::_visit_stack;
1969 // initialize for basic heap walk (IterateOverReachableObjects et al)
1970 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1971 GrowableArray<oop>* visit_stack,
1972 const void* user_data,
1973 BasicHeapWalkContext context) {
1974 _tag_map = tag_map;
1975 _visit_stack = visit_stack;
1976 _user_data = user_data;
1977 _basic_context = context;
1978 _advanced_context.invalidate(); // will trigger assertion if used
1979 _heap_walk_type = basic;
1980 }
1982 // initialize for advanced heap walk (FollowReferences)
1983 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1984 GrowableArray<oop>* visit_stack,
1985 const void* user_data,
1986 AdvancedHeapWalkContext context) {
1987 _tag_map = tag_map;
1988 _visit_stack = visit_stack;
1989 _user_data = user_data;
1990 _advanced_context = context;
1991 _basic_context.invalidate(); // will trigger assertion if used
1992 _heap_walk_type = advanced;
1993 }
1996 // invoke basic style heap root callback
1997 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1998 assert(ServiceUtil::visible_oop(obj), "checking");
2000 // if we heap roots should be reported
2001 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
2002 if (cb == NULL) {
2003 return check_for_visit(obj);
2004 }
2006 CallbackWrapper wrapper(tag_map(), obj);
2007 jvmtiIterationControl control = (*cb)(root_kind,
2008 wrapper.klass_tag(),
2009 wrapper.obj_size(),
2010 wrapper.obj_tag_p(),
2011 (void*)user_data());
2012 // push root to visit stack when following references
2013 if (control == JVMTI_ITERATION_CONTINUE &&
2014 basic_context()->object_ref_callback() != NULL) {
2015 visit_stack()->push(obj);
2016 }
2017 return control != JVMTI_ITERATION_ABORT;
2018 }
2020 // invoke basic style stack ref callback
2021 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
2022 jlong thread_tag,
2023 jint depth,
2024 jmethodID method,
2025 jint slot,
2026 oop obj) {
2027 assert(ServiceUtil::visible_oop(obj), "checking");
2029 // if we stack refs should be reported
2030 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
2031 if (cb == NULL) {
2032 return check_for_visit(obj);
2033 }
2035 CallbackWrapper wrapper(tag_map(), obj);
2036 jvmtiIterationControl control = (*cb)(root_kind,
2037 wrapper.klass_tag(),
2038 wrapper.obj_size(),
2039 wrapper.obj_tag_p(),
2040 thread_tag,
2041 depth,
2042 method,
2043 slot,
2044 (void*)user_data());
2045 // push root to visit stack when following references
2046 if (control == JVMTI_ITERATION_CONTINUE &&
2047 basic_context()->object_ref_callback() != NULL) {
2048 visit_stack()->push(obj);
2049 }
2050 return control != JVMTI_ITERATION_ABORT;
2051 }
2053 // invoke basic style object reference callback
2054 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
2055 oop referrer,
2056 oop referree,
2057 jint index) {
2059 assert(ServiceUtil::visible_oop(referrer), "checking");
2060 assert(ServiceUtil::visible_oop(referree), "checking");
2062 BasicHeapWalkContext* context = basic_context();
2064 // callback requires the referrer's tag. If it's the same referrer
2065 // as the last call then we use the cached value.
2066 jlong referrer_tag;
2067 if (referrer == context->last_referrer()) {
2068 referrer_tag = context->last_referrer_tag();
2069 } else {
2070 referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer));
2071 }
2073 // do the callback
2074 CallbackWrapper wrapper(tag_map(), referree);
2075 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
2076 jvmtiIterationControl control = (*cb)(ref_kind,
2077 wrapper.klass_tag(),
2078 wrapper.obj_size(),
2079 wrapper.obj_tag_p(),
2080 referrer_tag,
2081 index,
2082 (void*)user_data());
2084 // record referrer and referrer tag. For self-references record the
2085 // tag value from the callback as this might differ from referrer_tag.
2086 context->set_last_referrer(referrer);
2087 if (referrer == referree) {
2088 context->set_last_referrer_tag(*wrapper.obj_tag_p());
2089 } else {
2090 context->set_last_referrer_tag(referrer_tag);
2091 }
2093 if (control == JVMTI_ITERATION_CONTINUE) {
2094 return check_for_visit(referree);
2095 } else {
2096 return control != JVMTI_ITERATION_ABORT;
2097 }
2098 }
2100 // invoke advanced style heap root callback
2101 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
2102 oop obj) {
2103 assert(ServiceUtil::visible_oop(obj), "checking");
2105 AdvancedHeapWalkContext* context = advanced_context();
2107 // check that callback is provided
2108 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2109 if (cb == NULL) {
2110 return check_for_visit(obj);
2111 }
2113 // apply class filter
2114 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2115 return check_for_visit(obj);
2116 }
2118 // setup the callback wrapper
2119 CallbackWrapper wrapper(tag_map(), obj);
2121 // apply tag filter
2122 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2123 wrapper.klass_tag(),
2124 context->heap_filter())) {
2125 return check_for_visit(obj);
2126 }
2128 // for arrays we need the length, otherwise -1
2129 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2131 // invoke the callback
2132 jint res = (*cb)(ref_kind,
2133 NULL, // referrer info
2134 wrapper.klass_tag(),
2135 0, // referrer_class_tag is 0 for heap root
2136 wrapper.obj_size(),
2137 wrapper.obj_tag_p(),
2138 NULL, // referrer_tag_p
2139 len,
2140 (void*)user_data());
2141 if (res & JVMTI_VISIT_ABORT) {
2142 return false;// referrer class tag
2143 }
2144 if (res & JVMTI_VISIT_OBJECTS) {
2145 check_for_visit(obj);
2146 }
2147 return true;
2148 }
2150 // report a reference from a thread stack to an object
2151 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
2152 jlong thread_tag,
2153 jlong tid,
2154 int depth,
2155 jmethodID method,
2156 jlocation bci,
2157 jint slot,
2158 oop obj) {
2159 assert(ServiceUtil::visible_oop(obj), "checking");
2161 AdvancedHeapWalkContext* context = advanced_context();
2163 // check that callback is provider
2164 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2165 if (cb == NULL) {
2166 return check_for_visit(obj);
2167 }
2169 // apply class filter
2170 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2171 return check_for_visit(obj);
2172 }
2174 // setup the callback wrapper
2175 CallbackWrapper wrapper(tag_map(), obj);
2177 // apply tag filter
2178 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2179 wrapper.klass_tag(),
2180 context->heap_filter())) {
2181 return check_for_visit(obj);
2182 }
2184 // setup the referrer info
2185 jvmtiHeapReferenceInfo reference_info;
2186 reference_info.stack_local.thread_tag = thread_tag;
2187 reference_info.stack_local.thread_id = tid;
2188 reference_info.stack_local.depth = depth;
2189 reference_info.stack_local.method = method;
2190 reference_info.stack_local.location = bci;
2191 reference_info.stack_local.slot = slot;
2193 // for arrays we need the length, otherwise -1
2194 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2196 // call into the agent
2197 int res = (*cb)(ref_kind,
2198 &reference_info,
2199 wrapper.klass_tag(),
2200 0, // referrer_class_tag is 0 for heap root (stack)
2201 wrapper.obj_size(),
2202 wrapper.obj_tag_p(),
2203 NULL, // referrer_tag is 0 for root
2204 len,
2205 (void*)user_data());
2207 if (res & JVMTI_VISIT_ABORT) {
2208 return false;
2209 }
2210 if (res & JVMTI_VISIT_OBJECTS) {
2211 check_for_visit(obj);
2212 }
2213 return true;
2214 }
2216 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
2217 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
2218 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
2219 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
2220 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
2221 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
2222 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
2223 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
2225 // invoke the object reference callback to report a reference
2226 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
2227 oop referrer,
2228 oop obj,
2229 jint index)
2230 {
2231 // field index is only valid field in reference_info
2232 static jvmtiHeapReferenceInfo reference_info = { 0 };
2234 assert(ServiceUtil::visible_oop(referrer), "checking");
2235 assert(ServiceUtil::visible_oop(obj), "checking");
2237 AdvancedHeapWalkContext* context = advanced_context();
2239 // check that callback is provider
2240 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2241 if (cb == NULL) {
2242 return check_for_visit(obj);
2243 }
2245 // apply class filter
2246 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2247 return check_for_visit(obj);
2248 }
2250 // setup the callback wrapper
2251 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
2253 // apply tag filter
2254 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2255 wrapper.klass_tag(),
2256 context->heap_filter())) {
2257 return check_for_visit(obj);
2258 }
2260 // field index is only valid field in reference_info
2261 reference_info.field.index = index;
2263 // for arrays we need the length, otherwise -1
2264 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2266 // invoke the callback
2267 int res = (*cb)(ref_kind,
2268 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
2269 wrapper.klass_tag(),
2270 wrapper.referrer_klass_tag(),
2271 wrapper.obj_size(),
2272 wrapper.obj_tag_p(),
2273 wrapper.referrer_tag_p(),
2274 len,
2275 (void*)user_data());
2277 if (res & JVMTI_VISIT_ABORT) {
2278 return false;
2279 }
2280 if (res & JVMTI_VISIT_OBJECTS) {
2281 check_for_visit(obj);
2282 }
2283 return true;
2284 }
2286 // report a "simple root"
2287 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
2288 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
2289 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
2290 assert(ServiceUtil::visible_oop(obj), "checking");
2292 if (is_basic_heap_walk()) {
2293 // map to old style root kind
2294 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
2295 return invoke_basic_heap_root_callback(root_kind, obj);
2296 } else {
2297 assert(is_advanced_heap_walk(), "wrong heap walk type");
2298 return invoke_advanced_heap_root_callback(kind, obj);
2299 }
2300 }
2303 // invoke the primitive array values
2304 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
2305 assert(obj->is_typeArray(), "not a primitive array");
2307 AdvancedHeapWalkContext* context = advanced_context();
2308 assert(context->array_primitive_value_callback() != NULL, "no callback");
2310 // apply class filter
2311 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2312 return true;
2313 }
2315 CallbackWrapper wrapper(tag_map(), obj);
2317 // apply tag filter
2318 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2319 wrapper.klass_tag(),
2320 context->heap_filter())) {
2321 return true;
2322 }
2324 // invoke the callback
2325 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(),
2326 &wrapper,
2327 obj,
2328 (void*)user_data());
2329 return (!(res & JVMTI_VISIT_ABORT));
2330 }
2332 // invoke the string value callback
2333 inline bool CallbackInvoker::report_string_value(oop str) {
2334 assert(str->klass() == SystemDictionary::String_klass(), "not a string");
2336 AdvancedHeapWalkContext* context = advanced_context();
2337 assert(context->string_primitive_value_callback() != NULL, "no callback");
2339 // apply class filter
2340 if (is_filtered_by_klass_filter(str, context->klass_filter())) {
2341 return true;
2342 }
2344 CallbackWrapper wrapper(tag_map(), str);
2346 // apply tag filter
2347 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2348 wrapper.klass_tag(),
2349 context->heap_filter())) {
2350 return true;
2351 }
2353 // invoke the callback
2354 int res = invoke_string_value_callback(context->string_primitive_value_callback(),
2355 &wrapper,
2356 str,
2357 (void*)user_data());
2358 return (!(res & JVMTI_VISIT_ABORT));
2359 }
2361 // invoke the primitive field callback
2362 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind,
2363 oop obj,
2364 jint index,
2365 address addr,
2366 char type)
2367 {
2368 // for primitive fields only the index will be set
2369 static jvmtiHeapReferenceInfo reference_info = { 0 };
2371 AdvancedHeapWalkContext* context = advanced_context();
2372 assert(context->primitive_field_callback() != NULL, "no callback");
2374 // apply class filter
2375 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2376 return true;
2377 }
2379 CallbackWrapper wrapper(tag_map(), obj);
2381 // apply tag filter
2382 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2383 wrapper.klass_tag(),
2384 context->heap_filter())) {
2385 return true;
2386 }
2388 // the field index in the referrer
2389 reference_info.field.index = index;
2391 // map the type
2392 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
2394 // setup the jvalue
2395 jvalue value;
2396 copy_to_jvalue(&value, addr, value_type);
2398 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback();
2399 int res = (*cb)(ref_kind,
2400 &reference_info,
2401 wrapper.klass_tag(),
2402 wrapper.obj_tag_p(),
2403 value,
2404 value_type,
2405 (void*)user_data());
2406 return (!(res & JVMTI_VISIT_ABORT));
2407 }
2410 // instance field
2411 inline bool CallbackInvoker::report_primitive_instance_field(oop obj,
2412 jint index,
2413 address value,
2414 char type) {
2415 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD,
2416 obj,
2417 index,
2418 value,
2419 type);
2420 }
2422 // static field
2423 inline bool CallbackInvoker::report_primitive_static_field(oop obj,
2424 jint index,
2425 address value,
2426 char type) {
2427 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
2428 obj,
2429 index,
2430 value,
2431 type);
2432 }
2434 // report a JNI local (root object) to the profiler
2435 inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) {
2436 if (is_basic_heap_walk()) {
2437 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL,
2438 thread_tag,
2439 depth,
2440 m,
2441 -1,
2442 obj);
2443 } else {
2444 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL,
2445 thread_tag, tid,
2446 depth,
2447 m,
2448 (jlocation)-1,
2449 -1,
2450 obj);
2451 }
2452 }
2455 // report a local (stack reference, root object)
2456 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
2457 jlong tid,
2458 jint depth,
2459 jmethodID method,
2460 jlocation bci,
2461 jint slot,
2462 oop obj) {
2463 if (is_basic_heap_walk()) {
2464 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL,
2465 thread_tag,
2466 depth,
2467 method,
2468 slot,
2469 obj);
2470 } else {
2471 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL,
2472 thread_tag,
2473 tid,
2474 depth,
2475 method,
2476 bci,
2477 slot,
2478 obj);
2479 }
2480 }
2482 // report an object referencing a class.
2483 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) {
2484 if (is_basic_heap_walk()) {
2485 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
2486 } else {
2487 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1);
2488 }
2489 }
2491 // report a class referencing its class loader.
2492 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) {
2493 if (is_basic_heap_walk()) {
2494 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1);
2495 } else {
2496 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1);
2497 }
2498 }
2500 // report a class referencing its signers.
2501 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) {
2502 if (is_basic_heap_walk()) {
2503 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1);
2504 } else {
2505 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1);
2506 }
2507 }
2509 // report a class referencing its protection domain..
2510 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) {
2511 if (is_basic_heap_walk()) {
2512 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
2513 } else {
2514 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
2515 }
2516 }
2518 // report a class referencing its superclass.
2519 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) {
2520 if (is_basic_heap_walk()) {
2521 // Send this to be consistent with past implementation
2522 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
2523 } else {
2524 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1);
2525 }
2526 }
2528 // report a class referencing one of its interfaces.
2529 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) {
2530 if (is_basic_heap_walk()) {
2531 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1);
2532 } else {
2533 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1);
2534 }
2535 }
2537 // report a class referencing one of its static fields.
2538 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) {
2539 if (is_basic_heap_walk()) {
2540 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot);
2541 } else {
2542 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot);
2543 }
2544 }
2546 // report an array referencing an element object
2547 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) {
2548 if (is_basic_heap_walk()) {
2549 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
2550 } else {
2551 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
2552 }
2553 }
2555 // report an object referencing an instance field object
2556 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
2557 if (is_basic_heap_walk()) {
2558 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
2559 } else {
2560 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
2561 }
2562 }
2564 // report an array referencing an element object
2565 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
2566 if (is_basic_heap_walk()) {
2567 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2568 } else {
2569 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2570 }
2571 }
2573 // A supporting closure used to process simple roots
2574 class SimpleRootsClosure : public OopClosure {
2575 private:
2576 jvmtiHeapReferenceKind _kind;
2577 bool _continue;
2579 jvmtiHeapReferenceKind root_kind() { return _kind; }
2581 public:
2582 void set_kind(jvmtiHeapReferenceKind kind) {
2583 _kind = kind;
2584 _continue = true;
2585 }
2587 inline bool stopped() {
2588 return !_continue;
2589 }
2591 void do_oop(oop* obj_p) {
2592 // iteration has terminated
2593 if (stopped()) {
2594 return;
2595 }
2597 // ignore null or deleted handles
2598 oop o = *obj_p;
2599 if (o == NULL || o == JNIHandles::deleted_handle()) {
2600 return;
2601 }
2603 jvmtiHeapReferenceKind kind = root_kind();
2605 // many roots are Klasses so we use the java mirror
2606 if (o->is_klass()) {
2607 klassOop k = (klassOop)o;
2608 o = Klass::cast(k)->java_mirror();
2609 if (o == NULL) {
2610 // Classes without mirrors don't correspond to real Java
2611 // classes so just ignore them.
2612 return;
2613 }
2614 } else {
2616 // SystemDictionary::always_strong_oops_do reports the application
2617 // class loader as a root. We want this root to be reported as
2618 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2619 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2620 kind = JVMTI_HEAP_REFERENCE_OTHER;
2621 }
2622 }
2624 // some objects are ignored - in the case of simple
2625 // roots it's mostly Symbol*s that we are skipping
2626 // here.
2627 if (!ServiceUtil::visible_oop(o)) {
2628 return;
2629 }
2631 // invoke the callback
2632 _continue = CallbackInvoker::report_simple_root(kind, o);
2634 }
2635 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2636 };
2638 // A supporting closure used to process JNI locals
2639 class JNILocalRootsClosure : public OopClosure {
2640 private:
2641 jlong _thread_tag;
2642 jlong _tid;
2643 jint _depth;
2644 jmethodID _method;
2645 bool _continue;
2646 public:
2647 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
2648 _thread_tag = thread_tag;
2649 _tid = tid;
2650 _depth = depth;
2651 _method = method;
2652 _continue = true;
2653 }
2655 inline bool stopped() {
2656 return !_continue;
2657 }
2659 void do_oop(oop* obj_p) {
2660 // iteration has terminated
2661 if (stopped()) {
2662 return;
2663 }
2665 // ignore null or deleted handles
2666 oop o = *obj_p;
2667 if (o == NULL || o == JNIHandles::deleted_handle()) {
2668 return;
2669 }
2671 if (!ServiceUtil::visible_oop(o)) {
2672 return;
2673 }
2675 // invoke the callback
2676 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
2677 }
2678 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2679 };
2682 // A VM operation to iterate over objects that are reachable from
2683 // a set of roots or an initial object.
2684 //
2685 // For VM_HeapWalkOperation the set of roots used is :-
2686 //
2687 // - All JNI global references
2688 // - All inflated monitors
2689 // - All classes loaded by the boot class loader (or all classes
2690 // in the event that class unloading is disabled)
2691 // - All java threads
2692 // - For each java thread then all locals and JNI local references
2693 // on the thread's execution stack
2694 // - All visible/explainable objects from Universes::oops_do
2695 //
2696 class VM_HeapWalkOperation: public VM_Operation {
2697 private:
2698 enum {
2699 initial_visit_stack_size = 4000
2700 };
2702 bool _is_advanced_heap_walk; // indicates FollowReferences
2703 JvmtiTagMap* _tag_map;
2704 Handle _initial_object;
2705 GrowableArray<oop>* _visit_stack; // the visit stack
2707 bool _collecting_heap_roots; // are we collecting roots
2708 bool _following_object_refs; // are we following object references
2710 bool _reporting_primitive_fields; // optional reporting
2711 bool _reporting_primitive_array_values;
2712 bool _reporting_string_values;
2714 GrowableArray<oop>* create_visit_stack() {
2715 return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true);
2716 }
2718 // accessors
2719 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; }
2720 JvmtiTagMap* tag_map() const { return _tag_map; }
2721 Handle initial_object() const { return _initial_object; }
2723 bool is_following_references() const { return _following_object_refs; }
2725 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; }
2726 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; }
2727 bool is_reporting_string_values() const { return _reporting_string_values; }
2729 GrowableArray<oop>* visit_stack() const { return _visit_stack; }
2731 // iterate over the various object types
2732 inline bool iterate_over_array(oop o);
2733 inline bool iterate_over_type_array(oop o);
2734 inline bool iterate_over_class(klassOop o);
2735 inline bool iterate_over_object(oop o);
2737 // root collection
2738 inline bool collect_simple_roots();
2739 inline bool collect_stack_roots();
2740 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk);
2742 // visit an object
2743 inline bool visit(oop o);
2745 public:
2746 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2747 Handle initial_object,
2748 BasicHeapWalkContext callbacks,
2749 const void* user_data);
2751 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2752 Handle initial_object,
2753 AdvancedHeapWalkContext callbacks,
2754 const void* user_data);
2756 ~VM_HeapWalkOperation();
2758 VMOp_Type type() const { return VMOp_HeapWalkOperation; }
2759 void doit();
2760 };
2763 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2764 Handle initial_object,
2765 BasicHeapWalkContext callbacks,
2766 const void* user_data) {
2767 _is_advanced_heap_walk = false;
2768 _tag_map = tag_map;
2769 _initial_object = initial_object;
2770 _following_object_refs = (callbacks.object_ref_callback() != NULL);
2771 _reporting_primitive_fields = false;
2772 _reporting_primitive_array_values = false;
2773 _reporting_string_values = false;
2774 _visit_stack = create_visit_stack();
2777 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2778 }
2780 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2781 Handle initial_object,
2782 AdvancedHeapWalkContext callbacks,
2783 const void* user_data) {
2784 _is_advanced_heap_walk = true;
2785 _tag_map = tag_map;
2786 _initial_object = initial_object;
2787 _following_object_refs = true;
2788 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
2789 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
2790 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
2791 _visit_stack = create_visit_stack();
2793 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2794 }
2796 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
2797 if (_following_object_refs) {
2798 assert(_visit_stack != NULL, "checking");
2799 delete _visit_stack;
2800 _visit_stack = NULL;
2801 }
2802 }
2804 // an array references its class and has a reference to
2805 // each element in the array
2806 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
2807 objArrayOop array = objArrayOop(o);
2808 if (array->klass() == Universe::systemObjArrayKlassObj()) {
2809 // filtered out
2810 return true;
2811 }
2813 // array reference to its class
2814 oop mirror = objArrayKlass::cast(array->klass())->java_mirror();
2815 if (!CallbackInvoker::report_class_reference(o, mirror)) {
2816 return false;
2817 }
2819 // iterate over the array and report each reference to a
2820 // non-null element
2821 for (int index=0; index<array->length(); index++) {
2822 oop elem = array->obj_at(index);
2823 if (elem == NULL) {
2824 continue;
2825 }
2827 // report the array reference o[index] = elem
2828 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) {
2829 return false;
2830 }
2831 }
2832 return true;
2833 }
2835 // a type array references its class
2836 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
2837 klassOop k = o->klass();
2838 oop mirror = Klass::cast(k)->java_mirror();
2839 if (!CallbackInvoker::report_class_reference(o, mirror)) {
2840 return false;
2841 }
2843 // report the array contents if required
2844 if (is_reporting_primitive_array_values()) {
2845 if (!CallbackInvoker::report_primitive_array_values(o)) {
2846 return false;
2847 }
2848 }
2849 return true;
2850 }
2852 // verify that a static oop field is in range
2853 static inline bool verify_static_oop(instanceKlass* ik,
2854 oop mirror, int offset) {
2855 address obj_p = (address)mirror + offset;
2856 address start = (address)instanceMirrorKlass::start_of_static_fields(mirror);
2857 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
2858 assert(end >= start, "sanity check");
2860 if (obj_p >= start && obj_p < end) {
2861 return true;
2862 } else {
2863 return false;
2864 }
2865 }
2867 // a class references its super class, interfaces, class loader, ...
2868 // and finally its static fields
2869 inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) {
2870 int i;
2871 Klass* klass = klassOop(k)->klass_part();
2873 if (klass->oop_is_instance()) {
2874 instanceKlass* ik = instanceKlass::cast(k);
2876 // ignore the class if it's has been initialized yet
2877 if (!ik->is_linked()) {
2878 return true;
2879 }
2881 // get the java mirror
2882 oop mirror = klass->java_mirror();
2884 // super (only if something more interesting than java.lang.Object)
2885 klassOop java_super = ik->java_super();
2886 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
2887 oop super = Klass::cast(java_super)->java_mirror();
2888 if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
2889 return false;
2890 }
2891 }
2893 // class loader
2894 oop cl = ik->class_loader();
2895 if (cl != NULL) {
2896 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) {
2897 return false;
2898 }
2899 }
2901 // protection domain
2902 oop pd = ik->protection_domain();
2903 if (pd != NULL) {
2904 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) {
2905 return false;
2906 }
2907 }
2909 // signers
2910 oop signers = ik->signers();
2911 if (signers != NULL) {
2912 if (!CallbackInvoker::report_signers_reference(mirror, signers)) {
2913 return false;
2914 }
2915 }
2917 // references from the constant pool
2918 {
2919 const constantPoolOop pool = ik->constants();
2920 for (int i = 1; i < pool->length(); i++) {
2921 constantTag tag = pool->tag_at(i).value();
2922 if (tag.is_string() || tag.is_klass()) {
2923 oop entry;
2924 if (tag.is_string()) {
2925 entry = pool->resolved_string_at(i);
2926 assert(java_lang_String::is_instance(entry), "must be string");
2927 } else {
2928 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
2929 }
2930 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
2931 return false;
2932 }
2933 }
2934 }
2935 }
2937 // interfaces
2938 // (These will already have been reported as references from the constant pool
2939 // but are specified by IterateOverReachableObjects and must be reported).
2940 objArrayOop interfaces = ik->local_interfaces();
2941 for (i = 0; i < interfaces->length(); i++) {
2942 oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror();
2943 if (interf == NULL) {
2944 continue;
2945 }
2946 if (!CallbackInvoker::report_interface_reference(mirror, interf)) {
2947 return false;
2948 }
2949 }
2951 // iterate over the static fields
2953 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
2954 for (i=0; i<field_map->field_count(); i++) {
2955 ClassFieldDescriptor* field = field_map->field_at(i);
2956 char type = field->field_type();
2957 if (!is_primitive_field_type(type)) {
2958 oop fld_o = mirror->obj_field(field->field_offset());
2959 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
2960 if (fld_o != NULL) {
2961 int slot = field->field_index();
2962 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
2963 delete field_map;
2964 return false;
2965 }
2966 }
2967 } else {
2968 if (is_reporting_primitive_fields()) {
2969 address addr = (address)mirror + field->field_offset();
2970 int slot = field->field_index();
2971 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
2972 delete field_map;
2973 return false;
2974 }
2975 }
2976 }
2977 }
2978 delete field_map;
2980 return true;
2981 }
2983 return true;
2984 }
2986 // an object references a class and its instance fields
2987 // (static fields are ignored here as we report these as
2988 // references from the class).
2989 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2990 // reference to the class
2991 if (!CallbackInvoker::report_class_reference(o, Klass::cast(o->klass())->java_mirror())) {
2992 return false;
2993 }
2995 // iterate over instance fields
2996 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2997 for (int i=0; i<field_map->field_count(); i++) {
2998 ClassFieldDescriptor* field = field_map->field_at(i);
2999 char type = field->field_type();
3000 if (!is_primitive_field_type(type)) {
3001 oop fld_o = o->obj_field(field->field_offset());
3002 // ignore any objects that aren't visible to profiler
3003 if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
3004 // reflection code may have a reference to a klassOop.
3005 // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
3006 if (fld_o->is_klass()) {
3007 klassOop k = (klassOop)fld_o;
3008 fld_o = Klass::cast(k)->java_mirror();
3009 }
3010 int slot = field->field_index();
3011 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
3012 return false;
3013 }
3014 }
3015 } else {
3016 if (is_reporting_primitive_fields()) {
3017 // primitive instance field
3018 address addr = (address)o + field->field_offset();
3019 int slot = field->field_index();
3020 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
3021 return false;
3022 }
3023 }
3024 }
3025 }
3027 // if the object is a java.lang.String
3028 if (is_reporting_string_values() &&
3029 o->klass() == SystemDictionary::String_klass()) {
3030 if (!CallbackInvoker::report_string_value(o)) {
3031 return false;
3032 }
3033 }
3034 return true;
3035 }
3038 // Collects all simple (non-stack) roots except for threads;
3039 // threads are handled in collect_stack_roots() as an optimization.
3040 // if there's a heap root callback provided then the callback is
3041 // invoked for each simple root.
3042 // if an object reference callback is provided then all simple
3043 // roots are pushed onto the marking stack so that they can be
3044 // processed later
3045 //
3046 inline bool VM_HeapWalkOperation::collect_simple_roots() {
3047 SimpleRootsClosure blk;
3049 // JNI globals
3050 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL);
3051 JNIHandles::oops_do(&blk);
3052 if (blk.stopped()) {
3053 return false;
3054 }
3056 // Preloaded classes and loader from the system dictionary
3057 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
3058 SystemDictionary::always_strong_oops_do(&blk);
3059 if (blk.stopped()) {
3060 return false;
3061 }
3063 // Inflated monitors
3064 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR);
3065 ObjectSynchronizer::oops_do(&blk);
3066 if (blk.stopped()) {
3067 return false;
3068 }
3070 // threads are now handled in collect_stack_roots()
3072 // Other kinds of roots maintained by HotSpot
3073 // Many of these won't be visible but others (such as instances of important
3074 // exceptions) will be visible.
3075 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
3076 Universe::oops_do(&blk);
3078 // If there are any non-perm roots in the code cache, visit them.
3079 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
3080 CodeBlobToOopClosure look_in_blobs(&blk, false);
3081 CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
3083 return true;
3084 }
3086 // Walk the stack of a given thread and find all references (locals
3087 // and JNI calls) and report these as stack references
3088 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread,
3089 JNILocalRootsClosure* blk)
3090 {
3091 oop threadObj = java_thread->threadObj();
3092 assert(threadObj != NULL, "sanity check");
3094 // only need to get the thread's tag once per thread
3095 jlong thread_tag = tag_for(_tag_map, threadObj);
3097 // also need the thread id
3098 jlong tid = java_lang_Thread::thread_id(threadObj);
3101 if (java_thread->has_last_Java_frame()) {
3103 // vframes are resource allocated
3104 Thread* current_thread = Thread::current();
3105 ResourceMark rm(current_thread);
3106 HandleMark hm(current_thread);
3108 RegisterMap reg_map(java_thread);
3109 frame f = java_thread->last_frame();
3110 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread);
3112 bool is_top_frame = true;
3113 int depth = 0;
3114 frame* last_entry_frame = NULL;
3116 while (vf != NULL) {
3117 if (vf->is_java_frame()) {
3119 // java frame (interpreted, compiled, ...)
3120 javaVFrame *jvf = javaVFrame::cast(vf);
3122 // the jmethodID
3123 jmethodID method = jvf->method()->jmethod_id();
3125 if (!(jvf->method()->is_native())) {
3126 jlocation bci = (jlocation)jvf->bci();
3127 StackValueCollection* locals = jvf->locals();
3128 for (int slot=0; slot<locals->size(); slot++) {
3129 if (locals->at(slot)->type() == T_OBJECT) {
3130 oop o = locals->obj_at(slot)();
3131 if (o == NULL) {
3132 continue;
3133 }
3135 // stack reference
3136 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method,
3137 bci, slot, o)) {
3138 return false;
3139 }
3140 }
3141 }
3142 } else {
3143 blk->set_context(thread_tag, tid, depth, method);
3144 if (is_top_frame) {
3145 // JNI locals for the top frame.
3146 java_thread->active_handles()->oops_do(blk);
3147 } else {
3148 if (last_entry_frame != NULL) {
3149 // JNI locals for the entry frame
3150 assert(last_entry_frame->is_entry_frame(), "checking");
3151 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk);
3152 }
3153 }
3154 }
3155 last_entry_frame = NULL;
3156 depth++;
3157 } else {
3158 // externalVFrame - for an entry frame then we report the JNI locals
3159 // when we find the corresponding javaVFrame
3160 frame* fr = vf->frame_pointer();
3161 assert(fr != NULL, "sanity check");
3162 if (fr->is_entry_frame()) {
3163 last_entry_frame = fr;
3164 }
3165 if (fr->is_ricochet_frame()) {
3166 fr->oops_ricochet_do(blk, vf->register_map());
3167 }
3168 }
3170 vf = vf->sender();
3171 is_top_frame = false;
3172 }
3173 } else {
3174 // no last java frame but there may be JNI locals
3175 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL);
3176 java_thread->active_handles()->oops_do(blk);
3177 }
3178 return true;
3179 }
3182 // Collects the simple roots for all threads and collects all
3183 // stack roots - for each thread it walks the execution
3184 // stack to find all references and local JNI refs.
3185 inline bool VM_HeapWalkOperation::collect_stack_roots() {
3186 JNILocalRootsClosure blk;
3187 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
3188 oop threadObj = thread->threadObj();
3189 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3190 // Collect the simple root for this thread before we
3191 // collect its stack roots
3192 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
3193 threadObj)) {
3194 return false;
3195 }
3196 if (!collect_stack_roots(thread, &blk)) {
3197 return false;
3198 }
3199 }
3200 }
3201 return true;
3202 }
3204 // visit an object
3205 // first mark the object as visited
3206 // second get all the outbound references from this object (in other words, all
3207 // the objects referenced by this object).
3208 //
3209 bool VM_HeapWalkOperation::visit(oop o) {
3210 // mark object as visited
3211 assert(!ObjectMarker::visited(o), "can't visit same object more than once");
3212 ObjectMarker::mark(o);
3214 // instance
3215 if (o->is_instance()) {
3216 if (o->klass() == SystemDictionary::Class_klass()) {
3217 o = klassOop_if_java_lang_Class(o);
3218 if (o->is_klass()) {
3219 // a java.lang.Class
3220 return iterate_over_class(klassOop(o));
3221 }
3222 } else {
3223 return iterate_over_object(o);
3224 }
3225 }
3227 // object array
3228 if (o->is_objArray()) {
3229 return iterate_over_array(o);
3230 }
3232 // type array
3233 if (o->is_typeArray()) {
3234 return iterate_over_type_array(o);
3235 }
3237 return true;
3238 }
3240 void VM_HeapWalkOperation::doit() {
3241 ResourceMark rm;
3242 ObjectMarkerController marker;
3243 ClassFieldMapCacheMark cm;
3245 assert(visit_stack()->is_empty(), "visit stack must be empty");
3247 // the heap walk starts with an initial object or the heap roots
3248 if (initial_object().is_null()) {
3249 // If either collect_stack_roots() or collect_simple_roots()
3250 // returns false at this point, then there are no mark bits
3251 // to reset.
3252 ObjectMarker::set_needs_reset(false);
3254 // Calling collect_stack_roots() before collect_simple_roots()
3255 // can result in a big performance boost for an agent that is
3256 // focused on analyzing references in the thread stacks.
3257 if (!collect_stack_roots()) return;
3259 if (!collect_simple_roots()) return;
3261 // no early return so enable heap traversal to reset the mark bits
3262 ObjectMarker::set_needs_reset(true);
3263 } else {
3264 visit_stack()->push(initial_object()());
3265 }
3267 // object references required
3268 if (is_following_references()) {
3270 // visit each object until all reachable objects have been
3271 // visited or the callback asked to terminate the iteration.
3272 while (!visit_stack()->is_empty()) {
3273 oop o = visit_stack()->pop();
3274 if (!ObjectMarker::visited(o)) {
3275 if (!visit(o)) {
3276 break;
3277 }
3278 }
3279 }
3280 }
3281 }
3283 // iterate over all objects that are reachable from a set of roots
3284 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3285 jvmtiStackReferenceCallback stack_ref_callback,
3286 jvmtiObjectReferenceCallback object_ref_callback,
3287 const void* user_data) {
3288 MutexLocker ml(Heap_lock);
3289 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3290 VM_HeapWalkOperation op(this, Handle(), context, user_data);
3291 VMThread::execute(&op);
3292 }
3294 // iterate over all objects that are reachable from a given object
3295 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3296 jvmtiObjectReferenceCallback object_ref_callback,
3297 const void* user_data) {
3298 oop obj = JNIHandles::resolve(object);
3299 Handle initial_object(Thread::current(), obj);
3301 MutexLocker ml(Heap_lock);
3302 BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3303 VM_HeapWalkOperation op(this, initial_object, context, user_data);
3304 VMThread::execute(&op);
3305 }
3307 // follow references from an initial object or the GC roots
3308 void JvmtiTagMap::follow_references(jint heap_filter,
3309 KlassHandle klass,
3310 jobject object,
3311 const jvmtiHeapCallbacks* callbacks,
3312 const void* user_data)
3313 {
3314 oop obj = JNIHandles::resolve(object);
3315 Handle initial_object(Thread::current(), obj);
3317 MutexLocker ml(Heap_lock);
3318 AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3319 VM_HeapWalkOperation op(this, initial_object, context, user_data);
3320 VMThread::execute(&op);
3321 }
3324 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3325 // No locks during VM bring-up (0 threads) and no safepoints after main
3326 // thread creation and before VMThread creation (1 thread); initial GC
3327 // verification can happen in that window which gets to here.
3328 assert(Threads::number_of_threads() <= 1 ||
3329 SafepointSynchronize::is_at_safepoint(),
3330 "must be executed at a safepoint");
3331 if (JvmtiEnv::environments_might_exist()) {
3332 JvmtiEnvIterator it;
3333 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
3334 JvmtiTagMap* tag_map = env->tag_map();
3335 if (tag_map != NULL && !tag_map->is_empty()) {
3336 tag_map->do_weak_oops(is_alive, f);
3337 }
3338 }
3339 }
3340 }
3342 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) {
3344 // does this environment have the OBJECT_FREE event enabled
3345 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE);
3347 // counters used for trace message
3348 int freed = 0;
3349 int moved = 0;
3351 JvmtiTagHashmap* hashmap = this->hashmap();
3353 // reenable sizing (if disabled)
3354 hashmap->set_resizing_enabled(true);
3356 // if the hashmap is empty then we can skip it
3357 if (hashmap->_entry_count == 0) {
3358 return;
3359 }
3361 // now iterate through each entry in the table
3363 JvmtiTagHashmapEntry** table = hashmap->table();
3364 int size = hashmap->size();
3366 JvmtiTagHashmapEntry* delayed_add = NULL;
3368 for (int pos = 0; pos < size; ++pos) {
3369 JvmtiTagHashmapEntry* entry = table[pos];
3370 JvmtiTagHashmapEntry* prev = NULL;
3372 while (entry != NULL) {
3373 JvmtiTagHashmapEntry* next = entry->next();
3375 oop* obj = entry->object_addr();
3377 // has object been GC'ed
3378 if (!is_alive->do_object_b(entry->object())) {
3379 // grab the tag
3380 jlong tag = entry->tag();
3381 guarantee(tag != 0, "checking");
3383 // remove GC'ed entry from hashmap and return the
3384 // entry to the free list
3385 hashmap->remove(prev, pos, entry);
3386 destroy_entry(entry);
3388 // post the event to the profiler
3389 if (post_object_free) {
3390 JvmtiExport::post_object_free(env(), tag);
3391 }
3393 ++freed;
3394 } else {
3395 f->do_oop(entry->object_addr());
3396 oop new_oop = entry->object();
3398 // if the object has moved then re-hash it and move its
3399 // entry to its new location.
3400 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size);
3401 if (new_pos != (unsigned int)pos) {
3402 if (prev == NULL) {
3403 table[pos] = next;
3404 } else {
3405 prev->set_next(next);
3406 }
3407 if (new_pos < (unsigned int)pos) {
3408 entry->set_next(table[new_pos]);
3409 table[new_pos] = entry;
3410 } else {
3411 // Delay adding this entry to it's new position as we'd end up
3412 // hitting it again during this iteration.
3413 entry->set_next(delayed_add);
3414 delayed_add = entry;
3415 }
3416 moved++;
3417 } else {
3418 // object didn't move
3419 prev = entry;
3420 }
3421 }
3423 entry = next;
3424 }
3425 }
3427 // Re-add all the entries which were kept aside
3428 while (delayed_add != NULL) {
3429 JvmtiTagHashmapEntry* next = delayed_add->next();
3430 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size);
3431 delayed_add->set_next(table[pos]);
3432 table[pos] = delayed_add;
3433 delayed_add = next;
3434 }
3436 // stats
3437 if (TraceJVMTIObjectTagging) {
3438 int post_total = hashmap->_entry_count;
3439 int pre_total = post_total + freed;
3441 tty->print_cr("(%d->%d, %d freed, %d total moves)",
3442 pre_total, post_total, freed, moved);
3443 }
3444 }