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