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