Thu, 23 Jun 2011 17:14:06 -0700
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
Reviewed-by: never
1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
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;
1651 public:
1652 static void init(); // initialize
1653 static void done(); // clean-up
1655 static inline void mark(oop o); // mark an object
1656 static inline bool visited(oop o); // check if object has been visited
1657 };
1659 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1660 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
1662 // initialize ObjectMarker - prepares for object marking
1663 void ObjectMarker::init() {
1664 assert(Thread::current()->is_VM_thread(), "must be VMThread");
1666 // prepare heap for iteration
1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
1669 // create stacks for interesting headers
1670 _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true);
1671 _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
1673 if (UseBiasedLocking) {
1674 BiasedLocking::preserve_marks();
1675 }
1676 }
1678 // Object marking is done so restore object headers
1679 void ObjectMarker::done() {
1680 // iterate over all objects and restore the mark bits to
1681 // their initial value
1682 RestoreMarksClosure blk;
1683 Universe::heap()->object_iterate(&blk);
1685 // When sharing is enabled we need to restore the headers of the objects
1686 // in the readwrite space too.
1687 if (UseSharedSpaces) {
1688 GenCollectedHeap* gch = GenCollectedHeap::heap();
1689 CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen();
1690 gen->rw_space()->object_iterate(&blk);
1691 }
1693 // now restore the interesting headers
1694 for (int i = 0; i < _saved_oop_stack->length(); i++) {
1695 oop o = _saved_oop_stack->at(i);
1696 markOop mark = _saved_mark_stack->at(i);
1697 o->set_mark(mark);
1698 }
1700 if (UseBiasedLocking) {
1701 BiasedLocking::restore_marks();
1702 }
1704 // free the stacks
1705 delete _saved_oop_stack;
1706 delete _saved_mark_stack;
1707 }
1709 // mark an object
1710 inline void ObjectMarker::mark(oop o) {
1711 assert(Universe::heap()->is_in(o), "sanity check");
1712 assert(!o->mark()->is_marked(), "should only mark an object once");
1714 // object's mark word
1715 markOop mark = o->mark();
1717 if (mark->must_be_preserved(o)) {
1718 _saved_mark_stack->push(mark);
1719 _saved_oop_stack->push(o);
1720 }
1722 // mark the object
1723 o->set_mark(markOopDesc::prototype()->set_marked());
1724 }
1726 // return true if object is marked
1727 inline bool ObjectMarker::visited(oop o) {
1728 return o->mark()->is_marked();
1729 }
1731 // Stack allocated class to help ensure that ObjectMarker is used
1732 // correctly. Constructor initializes ObjectMarker, destructor calls
1733 // ObjectMarker's done() function to restore object headers.
1734 class ObjectMarkerController : public StackObj {
1735 public:
1736 ObjectMarkerController() {
1737 ObjectMarker::init();
1738 }
1739 ~ObjectMarkerController() {
1740 ObjectMarker::done();
1741 }
1742 };
1745 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1746 // (not performance critical as only used for roots)
1747 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1748 switch (kind) {
1749 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1750 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1751 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
1752 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
1753 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
1754 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
1755 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
1756 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
1757 }
1758 }
1760 // Base class for all heap walk contexts. The base class maintains a flag
1761 // to indicate if the context is valid or not.
1762 class HeapWalkContext VALUE_OBJ_CLASS_SPEC {
1763 private:
1764 bool _valid;
1765 public:
1766 HeapWalkContext(bool valid) { _valid = valid; }
1767 void invalidate() { _valid = false; }
1768 bool is_valid() const { return _valid; }
1769 };
1771 // A basic heap walk context for the deprecated heap walking functions.
1772 // The context for a basic heap walk are the callbacks and fields used by
1773 // the referrer caching scheme.
1774 class BasicHeapWalkContext: public HeapWalkContext {
1775 private:
1776 jvmtiHeapRootCallback _heap_root_callback;
1777 jvmtiStackReferenceCallback _stack_ref_callback;
1778 jvmtiObjectReferenceCallback _object_ref_callback;
1780 // used for caching
1781 oop _last_referrer;
1782 jlong _last_referrer_tag;
1784 public:
1785 BasicHeapWalkContext() : HeapWalkContext(false) { }
1787 BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback,
1788 jvmtiStackReferenceCallback stack_ref_callback,
1789 jvmtiObjectReferenceCallback object_ref_callback) :
1790 HeapWalkContext(true),
1791 _heap_root_callback(heap_root_callback),
1792 _stack_ref_callback(stack_ref_callback),
1793 _object_ref_callback(object_ref_callback),
1794 _last_referrer(NULL),
1795 _last_referrer_tag(0) {
1796 }
1798 // accessors
1799 jvmtiHeapRootCallback heap_root_callback() const { return _heap_root_callback; }
1800 jvmtiStackReferenceCallback stack_ref_callback() const { return _stack_ref_callback; }
1801 jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback; }
1803 oop last_referrer() const { return _last_referrer; }
1804 void set_last_referrer(oop referrer) { _last_referrer = referrer; }
1805 jlong last_referrer_tag() const { return _last_referrer_tag; }
1806 void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
1807 };
1809 // The advanced heap walk context for the FollowReferences functions.
1810 // The context is the callbacks, and the fields used for filtering.
1811 class AdvancedHeapWalkContext: public HeapWalkContext {
1812 private:
1813 jint _heap_filter;
1814 KlassHandle _klass_filter;
1815 const jvmtiHeapCallbacks* _heap_callbacks;
1817 public:
1818 AdvancedHeapWalkContext() : HeapWalkContext(false) { }
1820 AdvancedHeapWalkContext(jint heap_filter,
1821 KlassHandle klass_filter,
1822 const jvmtiHeapCallbacks* heap_callbacks) :
1823 HeapWalkContext(true),
1824 _heap_filter(heap_filter),
1825 _klass_filter(klass_filter),
1826 _heap_callbacks(heap_callbacks) {
1827 }
1829 // accessors
1830 jint heap_filter() const { return _heap_filter; }
1831 KlassHandle klass_filter() const { return _klass_filter; }
1833 const jvmtiHeapReferenceCallback heap_reference_callback() const {
1834 return _heap_callbacks->heap_reference_callback;
1835 };
1836 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1837 return _heap_callbacks->primitive_field_callback;
1838 }
1839 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1840 return _heap_callbacks->array_primitive_value_callback;
1841 }
1842 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1843 return _heap_callbacks->string_primitive_value_callback;
1844 }
1845 };
1847 // The CallbackInvoker is a class with static functions that the heap walk can call
1848 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1849 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1850 // mode is for the newer FollowReferences function which supports a lot of
1851 // additional callbacks.
1852 class CallbackInvoker : AllStatic {
1853 private:
1854 // heap walk styles
1855 enum { basic, advanced };
1856 static int _heap_walk_type;
1857 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
1858 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
1860 // context for basic style heap walk
1861 static BasicHeapWalkContext _basic_context;
1862 static BasicHeapWalkContext* basic_context() {
1863 assert(_basic_context.is_valid(), "invalid");
1864 return &_basic_context;
1865 }
1867 // context for advanced style heap walk
1868 static AdvancedHeapWalkContext _advanced_context;
1869 static AdvancedHeapWalkContext* advanced_context() {
1870 assert(_advanced_context.is_valid(), "invalid");
1871 return &_advanced_context;
1872 }
1874 // context needed for all heap walks
1875 static JvmtiTagMap* _tag_map;
1876 static const void* _user_data;
1877 static GrowableArray<oop>* _visit_stack;
1879 // accessors
1880 static JvmtiTagMap* tag_map() { return _tag_map; }
1881 static const void* user_data() { return _user_data; }
1882 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
1884 // if the object hasn't been visited then push it onto the visit stack
1885 // so that it will be visited later
1886 static inline bool check_for_visit(oop obj) {
1887 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
1888 return true;
1889 }
1891 // invoke basic style callbacks
1892 static inline bool invoke_basic_heap_root_callback
1893 (jvmtiHeapRootKind root_kind, oop obj);
1894 static inline bool invoke_basic_stack_ref_callback
1895 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1896 int slot, oop obj);
1897 static inline bool invoke_basic_object_reference_callback
1898 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1900 // invoke advanced style callbacks
1901 static inline bool invoke_advanced_heap_root_callback
1902 (jvmtiHeapReferenceKind ref_kind, oop obj);
1903 static inline bool invoke_advanced_stack_ref_callback
1904 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1905 jmethodID method, jlocation bci, jint slot, oop obj);
1906 static inline bool invoke_advanced_object_reference_callback
1907 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1909 // used to report the value of primitive fields
1910 static inline bool report_primitive_field
1911 (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
1913 public:
1914 // initialize for basic mode
1915 static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1916 GrowableArray<oop>* visit_stack,
1917 const void* user_data,
1918 BasicHeapWalkContext context);
1920 // initialize for advanced mode
1921 static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1922 GrowableArray<oop>* visit_stack,
1923 const void* user_data,
1924 AdvancedHeapWalkContext context);
1926 // functions to report roots
1927 static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
1928 static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
1929 jmethodID m, oop o);
1930 static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
1931 jmethodID method, jlocation bci, jint slot, oop o);
1933 // functions to report references
1934 static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
1935 static inline bool report_class_reference(oop referrer, oop referree);
1936 static inline bool report_class_loader_reference(oop referrer, oop referree);
1937 static inline bool report_signers_reference(oop referrer, oop referree);
1938 static inline bool report_protection_domain_reference(oop referrer, oop referree);
1939 static inline bool report_superclass_reference(oop referrer, oop referree);
1940 static inline bool report_interface_reference(oop referrer, oop referree);
1941 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1942 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1943 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1944 static inline bool report_primitive_array_values(oop array);
1945 static inline bool report_string_value(oop str);
1946 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1947 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1948 };
1950 // statics
1951 int CallbackInvoker::_heap_walk_type;
1952 BasicHeapWalkContext CallbackInvoker::_basic_context;
1953 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1954 JvmtiTagMap* CallbackInvoker::_tag_map;
1955 const void* CallbackInvoker::_user_data;
1956 GrowableArray<oop>* CallbackInvoker::_visit_stack;
1958 // initialize for basic heap walk (IterateOverReachableObjects et al)
1959 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1960 GrowableArray<oop>* visit_stack,
1961 const void* user_data,
1962 BasicHeapWalkContext context) {
1963 _tag_map = tag_map;
1964 _visit_stack = visit_stack;
1965 _user_data = user_data;
1966 _basic_context = context;
1967 _advanced_context.invalidate(); // will trigger assertion if used
1968 _heap_walk_type = basic;
1969 }
1971 // initialize for advanced heap walk (FollowReferences)
1972 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1973 GrowableArray<oop>* visit_stack,
1974 const void* user_data,
1975 AdvancedHeapWalkContext context) {
1976 _tag_map = tag_map;
1977 _visit_stack = visit_stack;
1978 _user_data = user_data;
1979 _advanced_context = context;
1980 _basic_context.invalidate(); // will trigger assertion if used
1981 _heap_walk_type = advanced;
1982 }
1985 // invoke basic style heap root callback
1986 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1987 assert(ServiceUtil::visible_oop(obj), "checking");
1989 // if we heap roots should be reported
1990 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
1991 if (cb == NULL) {
1992 return check_for_visit(obj);
1993 }
1995 CallbackWrapper wrapper(tag_map(), obj);
1996 jvmtiIterationControl control = (*cb)(root_kind,
1997 wrapper.klass_tag(),
1998 wrapper.obj_size(),
1999 wrapper.obj_tag_p(),
2000 (void*)user_data());
2001 // push root to visit stack when following references
2002 if (control == JVMTI_ITERATION_CONTINUE &&
2003 basic_context()->object_ref_callback() != NULL) {
2004 visit_stack()->push(obj);
2005 }
2006 return control != JVMTI_ITERATION_ABORT;
2007 }
2009 // invoke basic style stack ref callback
2010 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
2011 jlong thread_tag,
2012 jint depth,
2013 jmethodID method,
2014 jint slot,
2015 oop obj) {
2016 assert(ServiceUtil::visible_oop(obj), "checking");
2018 // if we stack refs should be reported
2019 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
2020 if (cb == NULL) {
2021 return check_for_visit(obj);
2022 }
2024 CallbackWrapper wrapper(tag_map(), obj);
2025 jvmtiIterationControl control = (*cb)(root_kind,
2026 wrapper.klass_tag(),
2027 wrapper.obj_size(),
2028 wrapper.obj_tag_p(),
2029 thread_tag,
2030 depth,
2031 method,
2032 slot,
2033 (void*)user_data());
2034 // push root to visit stack when following references
2035 if (control == JVMTI_ITERATION_CONTINUE &&
2036 basic_context()->object_ref_callback() != NULL) {
2037 visit_stack()->push(obj);
2038 }
2039 return control != JVMTI_ITERATION_ABORT;
2040 }
2042 // invoke basic style object reference callback
2043 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
2044 oop referrer,
2045 oop referree,
2046 jint index) {
2048 assert(ServiceUtil::visible_oop(referrer), "checking");
2049 assert(ServiceUtil::visible_oop(referree), "checking");
2051 BasicHeapWalkContext* context = basic_context();
2053 // callback requires the referrer's tag. If it's the same referrer
2054 // as the last call then we use the cached value.
2055 jlong referrer_tag;
2056 if (referrer == context->last_referrer()) {
2057 referrer_tag = context->last_referrer_tag();
2058 } else {
2059 referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer));
2060 }
2062 // do the callback
2063 CallbackWrapper wrapper(tag_map(), referree);
2064 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
2065 jvmtiIterationControl control = (*cb)(ref_kind,
2066 wrapper.klass_tag(),
2067 wrapper.obj_size(),
2068 wrapper.obj_tag_p(),
2069 referrer_tag,
2070 index,
2071 (void*)user_data());
2073 // record referrer and referrer tag. For self-references record the
2074 // tag value from the callback as this might differ from referrer_tag.
2075 context->set_last_referrer(referrer);
2076 if (referrer == referree) {
2077 context->set_last_referrer_tag(*wrapper.obj_tag_p());
2078 } else {
2079 context->set_last_referrer_tag(referrer_tag);
2080 }
2082 if (control == JVMTI_ITERATION_CONTINUE) {
2083 return check_for_visit(referree);
2084 } else {
2085 return control != JVMTI_ITERATION_ABORT;
2086 }
2087 }
2089 // invoke advanced style heap root callback
2090 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
2091 oop obj) {
2092 assert(ServiceUtil::visible_oop(obj), "checking");
2094 AdvancedHeapWalkContext* context = advanced_context();
2096 // check that callback is provided
2097 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2098 if (cb == NULL) {
2099 return check_for_visit(obj);
2100 }
2102 // apply class filter
2103 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2104 return check_for_visit(obj);
2105 }
2107 // setup the callback wrapper
2108 CallbackWrapper wrapper(tag_map(), obj);
2110 // apply tag filter
2111 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2112 wrapper.klass_tag(),
2113 context->heap_filter())) {
2114 return check_for_visit(obj);
2115 }
2117 // for arrays we need the length, otherwise -1
2118 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2120 // invoke the callback
2121 jint res = (*cb)(ref_kind,
2122 NULL, // referrer info
2123 wrapper.klass_tag(),
2124 0, // referrer_class_tag is 0 for heap root
2125 wrapper.obj_size(),
2126 wrapper.obj_tag_p(),
2127 NULL, // referrer_tag_p
2128 len,
2129 (void*)user_data());
2130 if (res & JVMTI_VISIT_ABORT) {
2131 return false;// referrer class tag
2132 }
2133 if (res & JVMTI_VISIT_OBJECTS) {
2134 check_for_visit(obj);
2135 }
2136 return true;
2137 }
2139 // report a reference from a thread stack to an object
2140 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
2141 jlong thread_tag,
2142 jlong tid,
2143 int depth,
2144 jmethodID method,
2145 jlocation bci,
2146 jint slot,
2147 oop obj) {
2148 assert(ServiceUtil::visible_oop(obj), "checking");
2150 AdvancedHeapWalkContext* context = advanced_context();
2152 // check that callback is provider
2153 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2154 if (cb == NULL) {
2155 return check_for_visit(obj);
2156 }
2158 // apply class filter
2159 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2160 return check_for_visit(obj);
2161 }
2163 // setup the callback wrapper
2164 CallbackWrapper wrapper(tag_map(), obj);
2166 // apply tag filter
2167 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2168 wrapper.klass_tag(),
2169 context->heap_filter())) {
2170 return check_for_visit(obj);
2171 }
2173 // setup the referrer info
2174 jvmtiHeapReferenceInfo reference_info;
2175 reference_info.stack_local.thread_tag = thread_tag;
2176 reference_info.stack_local.thread_id = tid;
2177 reference_info.stack_local.depth = depth;
2178 reference_info.stack_local.method = method;
2179 reference_info.stack_local.location = bci;
2180 reference_info.stack_local.slot = slot;
2182 // for arrays we need the length, otherwise -1
2183 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2185 // call into the agent
2186 int res = (*cb)(ref_kind,
2187 &reference_info,
2188 wrapper.klass_tag(),
2189 0, // referrer_class_tag is 0 for heap root (stack)
2190 wrapper.obj_size(),
2191 wrapper.obj_tag_p(),
2192 NULL, // referrer_tag is 0 for root
2193 len,
2194 (void*)user_data());
2196 if (res & JVMTI_VISIT_ABORT) {
2197 return false;
2198 }
2199 if (res & JVMTI_VISIT_OBJECTS) {
2200 check_for_visit(obj);
2201 }
2202 return true;
2203 }
2205 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
2206 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
2207 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
2208 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
2209 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
2210 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
2211 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
2212 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
2214 // invoke the object reference callback to report a reference
2215 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
2216 oop referrer,
2217 oop obj,
2218 jint index)
2219 {
2220 // field index is only valid field in reference_info
2221 static jvmtiHeapReferenceInfo reference_info = { 0 };
2223 assert(ServiceUtil::visible_oop(referrer), "checking");
2224 assert(ServiceUtil::visible_oop(obj), "checking");
2226 AdvancedHeapWalkContext* context = advanced_context();
2228 // check that callback is provider
2229 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2230 if (cb == NULL) {
2231 return check_for_visit(obj);
2232 }
2234 // apply class filter
2235 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2236 return check_for_visit(obj);
2237 }
2239 // setup the callback wrapper
2240 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
2242 // apply tag filter
2243 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2244 wrapper.klass_tag(),
2245 context->heap_filter())) {
2246 return check_for_visit(obj);
2247 }
2249 // field index is only valid field in reference_info
2250 reference_info.field.index = index;
2252 // for arrays we need the length, otherwise -1
2253 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
2255 // invoke the callback
2256 int res = (*cb)(ref_kind,
2257 (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
2258 wrapper.klass_tag(),
2259 wrapper.referrer_klass_tag(),
2260 wrapper.obj_size(),
2261 wrapper.obj_tag_p(),
2262 wrapper.referrer_tag_p(),
2263 len,
2264 (void*)user_data());
2266 if (res & JVMTI_VISIT_ABORT) {
2267 return false;
2268 }
2269 if (res & JVMTI_VISIT_OBJECTS) {
2270 check_for_visit(obj);
2271 }
2272 return true;
2273 }
2275 // report a "simple root"
2276 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
2277 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
2278 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
2279 assert(ServiceUtil::visible_oop(obj), "checking");
2281 if (is_basic_heap_walk()) {
2282 // map to old style root kind
2283 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
2284 return invoke_basic_heap_root_callback(root_kind, obj);
2285 } else {
2286 assert(is_advanced_heap_walk(), "wrong heap walk type");
2287 return invoke_advanced_heap_root_callback(kind, obj);
2288 }
2289 }
2292 // invoke the primitive array values
2293 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
2294 assert(obj->is_typeArray(), "not a primitive array");
2296 AdvancedHeapWalkContext* context = advanced_context();
2297 assert(context->array_primitive_value_callback() != NULL, "no callback");
2299 // apply class filter
2300 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2301 return true;
2302 }
2304 CallbackWrapper wrapper(tag_map(), obj);
2306 // apply tag filter
2307 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2308 wrapper.klass_tag(),
2309 context->heap_filter())) {
2310 return true;
2311 }
2313 // invoke the callback
2314 int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(),
2315 &wrapper,
2316 obj,
2317 (void*)user_data());
2318 return (!(res & JVMTI_VISIT_ABORT));
2319 }
2321 // invoke the string value callback
2322 inline bool CallbackInvoker::report_string_value(oop str) {
2323 assert(str->klass() == SystemDictionary::String_klass(), "not a string");
2325 AdvancedHeapWalkContext* context = advanced_context();
2326 assert(context->string_primitive_value_callback() != NULL, "no callback");
2328 // apply class filter
2329 if (is_filtered_by_klass_filter(str, context->klass_filter())) {
2330 return true;
2331 }
2333 CallbackWrapper wrapper(tag_map(), str);
2335 // apply tag filter
2336 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2337 wrapper.klass_tag(),
2338 context->heap_filter())) {
2339 return true;
2340 }
2342 // invoke the callback
2343 int res = invoke_string_value_callback(context->string_primitive_value_callback(),
2344 &wrapper,
2345 str,
2346 (void*)user_data());
2347 return (!(res & JVMTI_VISIT_ABORT));
2348 }
2350 // invoke the primitive field callback
2351 inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind,
2352 oop obj,
2353 jint index,
2354 address addr,
2355 char type)
2356 {
2357 // for primitive fields only the index will be set
2358 static jvmtiHeapReferenceInfo reference_info = { 0 };
2360 AdvancedHeapWalkContext* context = advanced_context();
2361 assert(context->primitive_field_callback() != NULL, "no callback");
2363 // apply class filter
2364 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2365 return true;
2366 }
2368 CallbackWrapper wrapper(tag_map(), obj);
2370 // apply tag filter
2371 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2372 wrapper.klass_tag(),
2373 context->heap_filter())) {
2374 return true;
2375 }
2377 // the field index in the referrer
2378 reference_info.field.index = index;
2380 // map the type
2381 jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
2383 // setup the jvalue
2384 jvalue value;
2385 copy_to_jvalue(&value, addr, value_type);
2387 jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback();
2388 int res = (*cb)(ref_kind,
2389 &reference_info,
2390 wrapper.klass_tag(),
2391 wrapper.obj_tag_p(),
2392 value,
2393 value_type,
2394 (void*)user_data());
2395 return (!(res & JVMTI_VISIT_ABORT));
2396 }
2399 // instance field
2400 inline bool CallbackInvoker::report_primitive_instance_field(oop obj,
2401 jint index,
2402 address value,
2403 char type) {
2404 return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD,
2405 obj,
2406 index,
2407 value,
2408 type);
2409 }
2411 // static field
2412 inline bool CallbackInvoker::report_primitive_static_field(oop obj,
2413 jint index,
2414 address value,
2415 char type) {
2416 return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
2417 obj,
2418 index,
2419 value,
2420 type);
2421 }
2423 // report a JNI local (root object) to the profiler
2424 inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) {
2425 if (is_basic_heap_walk()) {
2426 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL,
2427 thread_tag,
2428 depth,
2429 m,
2430 -1,
2431 obj);
2432 } else {
2433 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL,
2434 thread_tag, tid,
2435 depth,
2436 m,
2437 (jlocation)-1,
2438 -1,
2439 obj);
2440 }
2441 }
2444 // report a local (stack reference, root object)
2445 inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
2446 jlong tid,
2447 jint depth,
2448 jmethodID method,
2449 jlocation bci,
2450 jint slot,
2451 oop obj) {
2452 if (is_basic_heap_walk()) {
2453 return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL,
2454 thread_tag,
2455 depth,
2456 method,
2457 slot,
2458 obj);
2459 } else {
2460 return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL,
2461 thread_tag,
2462 tid,
2463 depth,
2464 method,
2465 bci,
2466 slot,
2467 obj);
2468 }
2469 }
2471 // report an object referencing a class.
2472 inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) {
2473 if (is_basic_heap_walk()) {
2474 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
2475 } else {
2476 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1);
2477 }
2478 }
2480 // report a class referencing its class loader.
2481 inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) {
2482 if (is_basic_heap_walk()) {
2483 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1);
2484 } else {
2485 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1);
2486 }
2487 }
2489 // report a class referencing its signers.
2490 inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) {
2491 if (is_basic_heap_walk()) {
2492 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1);
2493 } else {
2494 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1);
2495 }
2496 }
2498 // report a class referencing its protection domain..
2499 inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) {
2500 if (is_basic_heap_walk()) {
2501 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
2502 } else {
2503 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
2504 }
2505 }
2507 // report a class referencing its superclass.
2508 inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) {
2509 if (is_basic_heap_walk()) {
2510 // Send this to be consistent with past implementation
2511 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
2512 } else {
2513 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1);
2514 }
2515 }
2517 // report a class referencing one of its interfaces.
2518 inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) {
2519 if (is_basic_heap_walk()) {
2520 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1);
2521 } else {
2522 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1);
2523 }
2524 }
2526 // report a class referencing one of its static fields.
2527 inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) {
2528 if (is_basic_heap_walk()) {
2529 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot);
2530 } else {
2531 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot);
2532 }
2533 }
2535 // report an array referencing an element object
2536 inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) {
2537 if (is_basic_heap_walk()) {
2538 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
2539 } else {
2540 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
2541 }
2542 }
2544 // report an object referencing an instance field object
2545 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
2546 if (is_basic_heap_walk()) {
2547 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
2548 } else {
2549 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
2550 }
2551 }
2553 // report an array referencing an element object
2554 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
2555 if (is_basic_heap_walk()) {
2556 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2557 } else {
2558 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2559 }
2560 }
2562 // A supporting closure used to process simple roots
2563 class SimpleRootsClosure : public OopClosure {
2564 private:
2565 jvmtiHeapReferenceKind _kind;
2566 bool _continue;
2568 jvmtiHeapReferenceKind root_kind() { return _kind; }
2570 public:
2571 void set_kind(jvmtiHeapReferenceKind kind) {
2572 _kind = kind;
2573 _continue = true;
2574 }
2576 inline bool stopped() {
2577 return !_continue;
2578 }
2580 void do_oop(oop* obj_p) {
2581 // iteration has terminated
2582 if (stopped()) {
2583 return;
2584 }
2586 // ignore null or deleted handles
2587 oop o = *obj_p;
2588 if (o == NULL || o == JNIHandles::deleted_handle()) {
2589 return;
2590 }
2592 jvmtiHeapReferenceKind kind = root_kind();
2594 // many roots are Klasses so we use the java mirror
2595 if (o->is_klass()) {
2596 klassOop k = (klassOop)o;
2597 o = Klass::cast(k)->java_mirror();
2598 if (o == NULL) {
2599 // Classes without mirrors don't correspond to real Java
2600 // classes so just ignore them.
2601 return;
2602 }
2603 } else {
2605 // SystemDictionary::always_strong_oops_do reports the application
2606 // class loader as a root. We want this root to be reported as
2607 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2608 if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2609 kind = JVMTI_HEAP_REFERENCE_OTHER;
2610 }
2611 }
2613 // some objects are ignored - in the case of simple
2614 // roots it's mostly Symbol*s that we are skipping
2615 // here.
2616 if (!ServiceUtil::visible_oop(o)) {
2617 return;
2618 }
2620 // invoke the callback
2621 _continue = CallbackInvoker::report_simple_root(kind, o);
2623 }
2624 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2625 };
2627 // A supporting closure used to process JNI locals
2628 class JNILocalRootsClosure : public OopClosure {
2629 private:
2630 jlong _thread_tag;
2631 jlong _tid;
2632 jint _depth;
2633 jmethodID _method;
2634 bool _continue;
2635 public:
2636 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
2637 _thread_tag = thread_tag;
2638 _tid = tid;
2639 _depth = depth;
2640 _method = method;
2641 _continue = true;
2642 }
2644 inline bool stopped() {
2645 return !_continue;
2646 }
2648 void do_oop(oop* obj_p) {
2649 // iteration has terminated
2650 if (stopped()) {
2651 return;
2652 }
2654 // ignore null or deleted handles
2655 oop o = *obj_p;
2656 if (o == NULL || o == JNIHandles::deleted_handle()) {
2657 return;
2658 }
2660 if (!ServiceUtil::visible_oop(o)) {
2661 return;
2662 }
2664 // invoke the callback
2665 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
2666 }
2667 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2668 };
2671 // A VM operation to iterate over objects that are reachable from
2672 // a set of roots or an initial object.
2673 //
2674 // For VM_HeapWalkOperation the set of roots used is :-
2675 //
2676 // - All JNI global references
2677 // - All inflated monitors
2678 // - All classes loaded by the boot class loader (or all classes
2679 // in the event that class unloading is disabled)
2680 // - All java threads
2681 // - For each java thread then all locals and JNI local references
2682 // on the thread's execution stack
2683 // - All visible/explainable objects from Universes::oops_do
2684 //
2685 class VM_HeapWalkOperation: public VM_Operation {
2686 private:
2687 enum {
2688 initial_visit_stack_size = 4000
2689 };
2691 bool _is_advanced_heap_walk; // indicates FollowReferences
2692 JvmtiTagMap* _tag_map;
2693 Handle _initial_object;
2694 GrowableArray<oop>* _visit_stack; // the visit stack
2696 bool _collecting_heap_roots; // are we collecting roots
2697 bool _following_object_refs; // are we following object references
2699 bool _reporting_primitive_fields; // optional reporting
2700 bool _reporting_primitive_array_values;
2701 bool _reporting_string_values;
2703 GrowableArray<oop>* create_visit_stack() {
2704 return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true);
2705 }
2707 // accessors
2708 bool is_advanced_heap_walk() const { return _is_advanced_heap_walk; }
2709 JvmtiTagMap* tag_map() const { return _tag_map; }
2710 Handle initial_object() const { return _initial_object; }
2712 bool is_following_references() const { return _following_object_refs; }
2714 bool is_reporting_primitive_fields() const { return _reporting_primitive_fields; }
2715 bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; }
2716 bool is_reporting_string_values() const { return _reporting_string_values; }
2718 GrowableArray<oop>* visit_stack() const { return _visit_stack; }
2720 // iterate over the various object types
2721 inline bool iterate_over_array(oop o);
2722 inline bool iterate_over_type_array(oop o);
2723 inline bool iterate_over_class(klassOop o);
2724 inline bool iterate_over_object(oop o);
2726 // root collection
2727 inline bool collect_simple_roots();
2728 inline bool collect_stack_roots();
2729 inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk);
2731 // visit an object
2732 inline bool visit(oop o);
2734 public:
2735 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2736 Handle initial_object,
2737 BasicHeapWalkContext callbacks,
2738 const void* user_data);
2740 VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2741 Handle initial_object,
2742 AdvancedHeapWalkContext callbacks,
2743 const void* user_data);
2745 ~VM_HeapWalkOperation();
2747 VMOp_Type type() const { return VMOp_HeapWalkOperation; }
2748 void doit();
2749 };
2752 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2753 Handle initial_object,
2754 BasicHeapWalkContext callbacks,
2755 const void* user_data) {
2756 _is_advanced_heap_walk = false;
2757 _tag_map = tag_map;
2758 _initial_object = initial_object;
2759 _following_object_refs = (callbacks.object_ref_callback() != NULL);
2760 _reporting_primitive_fields = false;
2761 _reporting_primitive_array_values = false;
2762 _reporting_string_values = false;
2763 _visit_stack = create_visit_stack();
2766 CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2767 }
2769 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2770 Handle initial_object,
2771 AdvancedHeapWalkContext callbacks,
2772 const void* user_data) {
2773 _is_advanced_heap_walk = true;
2774 _tag_map = tag_map;
2775 _initial_object = initial_object;
2776 _following_object_refs = true;
2777 _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
2778 _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
2779 _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
2780 _visit_stack = create_visit_stack();
2782 CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2783 }
2785 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
2786 if (_following_object_refs) {
2787 assert(_visit_stack != NULL, "checking");
2788 delete _visit_stack;
2789 _visit_stack = NULL;
2790 }
2791 }
2793 // an array references its class and has a reference to
2794 // each element in the array
2795 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
2796 objArrayOop array = objArrayOop(o);
2797 if (array->klass() == Universe::systemObjArrayKlassObj()) {
2798 // filtered out
2799 return true;
2800 }
2802 // array reference to its class
2803 oop mirror = objArrayKlass::cast(array->klass())->java_mirror();
2804 if (!CallbackInvoker::report_class_reference(o, mirror)) {
2805 return false;
2806 }
2808 // iterate over the array and report each reference to a
2809 // non-null element
2810 for (int index=0; index<array->length(); index++) {
2811 oop elem = array->obj_at(index);
2812 if (elem == NULL) {
2813 continue;
2814 }
2816 // report the array reference o[index] = elem
2817 if (!CallbackInvoker::report_array_element_reference(o, elem, index)) {
2818 return false;
2819 }
2820 }
2821 return true;
2822 }
2824 // a type array references its class
2825 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
2826 klassOop k = o->klass();
2827 oop mirror = Klass::cast(k)->java_mirror();
2828 if (!CallbackInvoker::report_class_reference(o, mirror)) {
2829 return false;
2830 }
2832 // report the array contents if required
2833 if (is_reporting_primitive_array_values()) {
2834 if (!CallbackInvoker::report_primitive_array_values(o)) {
2835 return false;
2836 }
2837 }
2838 return true;
2839 }
2841 // verify that a static oop field is in range
2842 static inline bool verify_static_oop(instanceKlass* ik,
2843 oop mirror, int offset) {
2844 address obj_p = (address)mirror + offset;
2845 address start = (address)instanceMirrorKlass::start_of_static_fields(mirror);
2846 address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
2847 assert(end >= start, "sanity check");
2849 if (obj_p >= start && obj_p < end) {
2850 return true;
2851 } else {
2852 return false;
2853 }
2854 }
2856 // a class references its super class, interfaces, class loader, ...
2857 // and finally its static fields
2858 inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) {
2859 int i;
2860 Klass* klass = klassOop(k)->klass_part();
2862 if (klass->oop_is_instance()) {
2863 instanceKlass* ik = instanceKlass::cast(k);
2865 // ignore the class if it's has been initialized yet
2866 if (!ik->is_linked()) {
2867 return true;
2868 }
2870 // get the java mirror
2871 oop mirror = klass->java_mirror();
2873 // super (only if something more interesting than java.lang.Object)
2874 klassOop java_super = ik->java_super();
2875 if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
2876 oop super = Klass::cast(java_super)->java_mirror();
2877 if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
2878 return false;
2879 }
2880 }
2882 // class loader
2883 oop cl = ik->class_loader();
2884 if (cl != NULL) {
2885 if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) {
2886 return false;
2887 }
2888 }
2890 // protection domain
2891 oop pd = ik->protection_domain();
2892 if (pd != NULL) {
2893 if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) {
2894 return false;
2895 }
2896 }
2898 // signers
2899 oop signers = ik->signers();
2900 if (signers != NULL) {
2901 if (!CallbackInvoker::report_signers_reference(mirror, signers)) {
2902 return false;
2903 }
2904 }
2906 // references from the constant pool
2907 {
2908 const constantPoolOop pool = ik->constants();
2909 for (int i = 1; i < pool->length(); i++) {
2910 constantTag tag = pool->tag_at(i).value();
2911 if (tag.is_string() || tag.is_klass()) {
2912 oop entry;
2913 if (tag.is_string()) {
2914 entry = pool->resolved_string_at(i);
2915 assert(java_lang_String::is_instance(entry), "must be string");
2916 } else {
2917 entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
2918 }
2919 if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
2920 return false;
2921 }
2922 }
2923 }
2924 }
2926 // interfaces
2927 // (These will already have been reported as references from the constant pool
2928 // but are specified by IterateOverReachableObjects and must be reported).
2929 objArrayOop interfaces = ik->local_interfaces();
2930 for (i = 0; i < interfaces->length(); i++) {
2931 oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror();
2932 if (interf == NULL) {
2933 continue;
2934 }
2935 if (!CallbackInvoker::report_interface_reference(mirror, interf)) {
2936 return false;
2937 }
2938 }
2940 // iterate over the static fields
2942 ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
2943 for (i=0; i<field_map->field_count(); i++) {
2944 ClassFieldDescriptor* field = field_map->field_at(i);
2945 char type = field->field_type();
2946 if (!is_primitive_field_type(type)) {
2947 oop fld_o = mirror->obj_field(field->field_offset());
2948 assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
2949 if (fld_o != NULL) {
2950 int slot = field->field_index();
2951 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
2952 delete field_map;
2953 return false;
2954 }
2955 }
2956 } else {
2957 if (is_reporting_primitive_fields()) {
2958 address addr = (address)mirror + field->field_offset();
2959 int slot = field->field_index();
2960 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
2961 delete field_map;
2962 return false;
2963 }
2964 }
2965 }
2966 }
2967 delete field_map;
2969 return true;
2970 }
2972 return true;
2973 }
2975 // an object references a class and its instance fields
2976 // (static fields are ignored here as we report these as
2977 // references from the class).
2978 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2979 // reference to the class
2980 if (!CallbackInvoker::report_class_reference(o, Klass::cast(o->klass())->java_mirror())) {
2981 return false;
2982 }
2984 // iterate over instance fields
2985 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2986 for (int i=0; i<field_map->field_count(); i++) {
2987 ClassFieldDescriptor* field = field_map->field_at(i);
2988 char type = field->field_type();
2989 if (!is_primitive_field_type(type)) {
2990 oop fld_o = o->obj_field(field->field_offset());
2991 if (fld_o != NULL) {
2992 // reflection code may have a reference to a klassOop.
2993 // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
2994 if (fld_o->is_klass()) {
2995 klassOop k = (klassOop)fld_o;
2996 fld_o = Klass::cast(k)->java_mirror();
2997 }
2998 int slot = field->field_index();
2999 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
3000 return false;
3001 }
3002 }
3003 } else {
3004 if (is_reporting_primitive_fields()) {
3005 // primitive instance field
3006 address addr = (address)o + field->field_offset();
3007 int slot = field->field_index();
3008 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
3009 return false;
3010 }
3011 }
3012 }
3013 }
3015 // if the object is a java.lang.String
3016 if (is_reporting_string_values() &&
3017 o->klass() == SystemDictionary::String_klass()) {
3018 if (!CallbackInvoker::report_string_value(o)) {
3019 return false;
3020 }
3021 }
3022 return true;
3023 }
3026 // collects all simple (non-stack) roots.
3027 // if there's a heap root callback provided then the callback is
3028 // invoked for each simple root.
3029 // if an object reference callback is provided then all simple
3030 // roots are pushed onto the marking stack so that they can be
3031 // processed later
3032 //
3033 inline bool VM_HeapWalkOperation::collect_simple_roots() {
3034 SimpleRootsClosure blk;
3036 // JNI globals
3037 blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL);
3038 JNIHandles::oops_do(&blk);
3039 if (blk.stopped()) {
3040 return false;
3041 }
3043 // Preloaded classes and loader from the system dictionary
3044 blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
3045 SystemDictionary::always_strong_oops_do(&blk);
3046 if (blk.stopped()) {
3047 return false;
3048 }
3050 // Inflated monitors
3051 blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR);
3052 ObjectSynchronizer::oops_do(&blk);
3053 if (blk.stopped()) {
3054 return false;
3055 }
3057 // Threads
3058 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
3059 oop threadObj = thread->threadObj();
3060 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3061 bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj);
3062 if (!cont) {
3063 return false;
3064 }
3065 }
3066 }
3068 // Other kinds of roots maintained by HotSpot
3069 // Many of these won't be visible but others (such as instances of important
3070 // exceptions) will be visible.
3071 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
3072 Universe::oops_do(&blk);
3074 // If there are any non-perm roots in the code cache, visit them.
3075 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
3076 CodeBlobToOopClosure look_in_blobs(&blk, false);
3077 CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
3079 return true;
3080 }
3082 // Walk the stack of a given thread and find all references (locals
3083 // and JNI calls) and report these as stack references
3084 inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread,
3085 JNILocalRootsClosure* blk)
3086 {
3087 oop threadObj = java_thread->threadObj();
3088 assert(threadObj != NULL, "sanity check");
3090 // only need to get the thread's tag once per thread
3091 jlong thread_tag = tag_for(_tag_map, threadObj);
3093 // also need the thread id
3094 jlong tid = java_lang_Thread::thread_id(threadObj);
3097 if (java_thread->has_last_Java_frame()) {
3099 // vframes are resource allocated
3100 Thread* current_thread = Thread::current();
3101 ResourceMark rm(current_thread);
3102 HandleMark hm(current_thread);
3104 RegisterMap reg_map(java_thread);
3105 frame f = java_thread->last_frame();
3106 vframe* vf = vframe::new_vframe(&f, ®_map, java_thread);
3108 bool is_top_frame = true;
3109 int depth = 0;
3110 frame* last_entry_frame = NULL;
3112 while (vf != NULL) {
3113 if (vf->is_java_frame()) {
3115 // java frame (interpreted, compiled, ...)
3116 javaVFrame *jvf = javaVFrame::cast(vf);
3118 // the jmethodID
3119 jmethodID method = jvf->method()->jmethod_id();
3121 if (!(jvf->method()->is_native())) {
3122 jlocation bci = (jlocation)jvf->bci();
3123 StackValueCollection* locals = jvf->locals();
3124 for (int slot=0; slot<locals->size(); slot++) {
3125 if (locals->at(slot)->type() == T_OBJECT) {
3126 oop o = locals->obj_at(slot)();
3127 if (o == NULL) {
3128 continue;
3129 }
3131 // stack reference
3132 if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method,
3133 bci, slot, o)) {
3134 return false;
3135 }
3136 }
3137 }
3138 } else {
3139 blk->set_context(thread_tag, tid, depth, method);
3140 if (is_top_frame) {
3141 // JNI locals for the top frame.
3142 java_thread->active_handles()->oops_do(blk);
3143 } else {
3144 if (last_entry_frame != NULL) {
3145 // JNI locals for the entry frame
3146 assert(last_entry_frame->is_entry_frame(), "checking");
3147 last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk);
3148 }
3149 }
3150 }
3151 last_entry_frame = NULL;
3152 depth++;
3153 } else {
3154 // externalVFrame - for an entry frame then we report the JNI locals
3155 // when we find the corresponding javaVFrame
3156 frame* fr = vf->frame_pointer();
3157 assert(fr != NULL, "sanity check");
3158 if (fr->is_entry_frame()) {
3159 last_entry_frame = fr;
3160 }
3161 if (fr->is_ricochet_frame()) {
3162 fr->oops_ricochet_do(blk, vf->register_map());
3163 }
3164 }
3166 vf = vf->sender();
3167 is_top_frame = false;
3168 }
3169 } else {
3170 // no last java frame but there may be JNI locals
3171 blk->set_context(thread_tag, tid, 0, (jmethodID)NULL);
3172 java_thread->active_handles()->oops_do(blk);
3173 }
3174 return true;
3175 }
3178 // collects all stack roots - for each thread it walks the execution
3179 // stack to find all references and local JNI refs.
3180 inline bool VM_HeapWalkOperation::collect_stack_roots() {
3181 JNILocalRootsClosure blk;
3182 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
3183 oop threadObj = thread->threadObj();
3184 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3185 if (!collect_stack_roots(thread, &blk)) {
3186 return false;
3187 }
3188 }
3189 }
3190 return true;
3191 }
3193 // visit an object
3194 // first mark the object as visited
3195 // second get all the outbound references from this object (in other words, all
3196 // the objects referenced by this object).
3197 //
3198 bool VM_HeapWalkOperation::visit(oop o) {
3199 // mark object as visited
3200 assert(!ObjectMarker::visited(o), "can't visit same object more than once");
3201 ObjectMarker::mark(o);
3203 // instance
3204 if (o->is_instance()) {
3205 if (o->klass() == SystemDictionary::Class_klass()) {
3206 o = klassOop_if_java_lang_Class(o);
3207 if (o->is_klass()) {
3208 // a java.lang.Class
3209 return iterate_over_class(klassOop(o));
3210 }
3211 } else {
3212 return iterate_over_object(o);
3213 }
3214 }
3216 // object array
3217 if (o->is_objArray()) {
3218 return iterate_over_array(o);
3219 }
3221 // type array
3222 if (o->is_typeArray()) {
3223 return iterate_over_type_array(o);
3224 }
3226 return true;
3227 }
3229 void VM_HeapWalkOperation::doit() {
3230 ResourceMark rm;
3231 ObjectMarkerController marker;
3232 ClassFieldMapCacheMark cm;
3234 assert(visit_stack()->is_empty(), "visit stack must be empty");
3236 // the heap walk starts with an initial object or the heap roots
3237 if (initial_object().is_null()) {
3238 if (!collect_simple_roots()) return;
3239 if (!collect_stack_roots()) return;
3240 } else {
3241 visit_stack()->push(initial_object()());
3242 }
3244 // object references required
3245 if (is_following_references()) {
3247 // visit each object until all reachable objects have been
3248 // visited or the callback asked to terminate the iteration.
3249 while (!visit_stack()->is_empty()) {
3250 oop o = visit_stack()->pop();
3251 if (!ObjectMarker::visited(o)) {
3252 if (!visit(o)) {
3253 break;
3254 }
3255 }
3256 }
3257 }
3258 }
3260 // iterate over all objects that are reachable from a set of roots
3261 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3262 jvmtiStackReferenceCallback stack_ref_callback,
3263 jvmtiObjectReferenceCallback object_ref_callback,
3264 const void* user_data) {
3265 MutexLocker ml(Heap_lock);
3266 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3267 VM_HeapWalkOperation op(this, Handle(), context, user_data);
3268 VMThread::execute(&op);
3269 }
3271 // iterate over all objects that are reachable from a given object
3272 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3273 jvmtiObjectReferenceCallback object_ref_callback,
3274 const void* user_data) {
3275 oop obj = JNIHandles::resolve(object);
3276 Handle initial_object(Thread::current(), obj);
3278 MutexLocker ml(Heap_lock);
3279 BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3280 VM_HeapWalkOperation op(this, initial_object, context, user_data);
3281 VMThread::execute(&op);
3282 }
3284 // follow references from an initial object or the GC roots
3285 void JvmtiTagMap::follow_references(jint heap_filter,
3286 KlassHandle klass,
3287 jobject object,
3288 const jvmtiHeapCallbacks* callbacks,
3289 const void* user_data)
3290 {
3291 oop obj = JNIHandles::resolve(object);
3292 Handle initial_object(Thread::current(), obj);
3294 MutexLocker ml(Heap_lock);
3295 AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3296 VM_HeapWalkOperation op(this, initial_object, context, user_data);
3297 VMThread::execute(&op);
3298 }
3301 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3302 // No locks during VM bring-up (0 threads) and no safepoints after main
3303 // thread creation and before VMThread creation (1 thread); initial GC
3304 // verification can happen in that window which gets to here.
3305 assert(Threads::number_of_threads() <= 1 ||
3306 SafepointSynchronize::is_at_safepoint(),
3307 "must be executed at a safepoint");
3308 if (JvmtiEnv::environments_might_exist()) {
3309 JvmtiEnvIterator it;
3310 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
3311 JvmtiTagMap* tag_map = env->tag_map();
3312 if (tag_map != NULL && !tag_map->is_empty()) {
3313 tag_map->do_weak_oops(is_alive, f);
3314 }
3315 }
3316 }
3317 }
3319 void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) {
3321 // does this environment have the OBJECT_FREE event enabled
3322 bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE);
3324 // counters used for trace message
3325 int freed = 0;
3326 int moved = 0;
3328 JvmtiTagHashmap* hashmap = this->hashmap();
3330 // reenable sizing (if disabled)
3331 hashmap->set_resizing_enabled(true);
3333 // if the hashmap is empty then we can skip it
3334 if (hashmap->_entry_count == 0) {
3335 return;
3336 }
3338 // now iterate through each entry in the table
3340 JvmtiTagHashmapEntry** table = hashmap->table();
3341 int size = hashmap->size();
3343 JvmtiTagHashmapEntry* delayed_add = NULL;
3345 for (int pos = 0; pos < size; ++pos) {
3346 JvmtiTagHashmapEntry* entry = table[pos];
3347 JvmtiTagHashmapEntry* prev = NULL;
3349 while (entry != NULL) {
3350 JvmtiTagHashmapEntry* next = entry->next();
3352 oop* obj = entry->object_addr();
3354 // has object been GC'ed
3355 if (!is_alive->do_object_b(entry->object())) {
3356 // grab the tag
3357 jlong tag = entry->tag();
3358 guarantee(tag != 0, "checking");
3360 // remove GC'ed entry from hashmap and return the
3361 // entry to the free list
3362 hashmap->remove(prev, pos, entry);
3363 destroy_entry(entry);
3365 // post the event to the profiler
3366 if (post_object_free) {
3367 JvmtiExport::post_object_free(env(), tag);
3368 }
3370 ++freed;
3371 } else {
3372 f->do_oop(entry->object_addr());
3373 oop new_oop = entry->object();
3375 // if the object has moved then re-hash it and move its
3376 // entry to its new location.
3377 unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size);
3378 if (new_pos != (unsigned int)pos) {
3379 if (prev == NULL) {
3380 table[pos] = next;
3381 } else {
3382 prev->set_next(next);
3383 }
3384 if (new_pos < (unsigned int)pos) {
3385 entry->set_next(table[new_pos]);
3386 table[new_pos] = entry;
3387 } else {
3388 // Delay adding this entry to it's new position as we'd end up
3389 // hitting it again during this iteration.
3390 entry->set_next(delayed_add);
3391 delayed_add = entry;
3392 }
3393 moved++;
3394 } else {
3395 // object didn't move
3396 prev = entry;
3397 }
3398 }
3400 entry = next;
3401 }
3402 }
3404 // Re-add all the entries which were kept aside
3405 while (delayed_add != NULL) {
3406 JvmtiTagHashmapEntry* next = delayed_add->next();
3407 unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size);
3408 delayed_add->set_next(table[pos]);
3409 table[pos] = delayed_add;
3410 delayed_add = next;
3411 }
3413 // stats
3414 if (TraceJVMTIObjectTagging) {
3415 int post_total = hashmap->_entry_count;
3416 int pre_total = post_total + freed;
3418 tty->print_cr("(%d->%d, %d freed, %d total moves)",
3419 pre_total, post_total, freed, moved);
3420 }
3421 }