11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderDataGraph.hpp"
27 #include "classfile/javaClasses.inline.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "jvmtifiles/jvmtiEnv.hpp"
32 #include "logging/log.hpp"
33 #include "memory/allocation.inline.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "memory/universe.hpp"
36 #include "oops/access.inline.hpp"
37 #include "oops/arrayOop.inline.hpp"
38 #include "oops/constantPool.inline.hpp"
39 #include "oops/instanceMirrorKlass.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/typeArrayOop.inline.hpp"
44 #include "prims/jvmtiEventController.hpp"
45 #include "prims/jvmtiEventController.inline.hpp"
46 #include "prims/jvmtiExport.hpp"
47 #include "prims/jvmtiImpl.hpp"
48 #include "prims/jvmtiTagMap.hpp"
49 #include "runtime/biasedLocking.hpp"
50 #include "runtime/frame.inline.hpp"
51 #include "runtime/handles.inline.hpp"
52 #include "runtime/javaCalls.hpp"
53 #include "runtime/jniHandles.inline.hpp"
54 #include "runtime/mutex.hpp"
55 #include "runtime/mutexLocker.hpp"
56 #include "runtime/reflectionUtils.hpp"
57 #include "runtime/thread.inline.hpp"
58 #include "runtime/threadSMR.hpp"
59 #include "runtime/vframe.hpp"
60 #include "runtime/vmThread.hpp"
61 #include "runtime/vmOperations.hpp"
62 #include "utilities/macros.hpp"
63 #if INCLUDE_ZGC
64 #include "gc/z/zGlobals.hpp"
65 #endif
66
67 // JvmtiTagHashmapEntry
68 //
69 // Each entry encapsulates a reference to the tagged object
1595 }
1596
1597 *count_ptr = count;
1598 return JVMTI_ERROR_NONE;
1599 }
1600 };
1601
1602 // return the list of objects with the specified tags
1603 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
1604 jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1605
1606 TagObjectCollector collector(env(), tags, count);
1607 {
1608 // iterate over all tagged objects
1609 MutexLocker ml(lock());
1610 entry_iterate(&collector);
1611 }
1612 return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
1613 }
1614
1615
1616 // ObjectMarker is used to support the marking objects when walking the
1617 // heap.
1618 //
1619 // This implementation uses the existing mark bits in an object for
1620 // marking. Objects that are marked must later have their headers restored.
1621 // As most objects are unlocked and don't have their identity hash computed
1622 // we don't have to save their headers. Instead we save the headers that
1623 // are "interesting". Later when the headers are restored this implementation
1624 // restores all headers to their initial value and then restores the few
1625 // objects that had interesting headers.
1626 //
1627 // Future work: This implementation currently uses growable arrays to save
1628 // the oop and header of interesting objects. As an optimization we could
1629 // use the same technique as the GC and make use of the unused area
1630 // between top() and end().
1631 //
1632
1633 // An ObjectClosure used to restore the mark bits of an object
1634 class RestoreMarksClosure : public ObjectClosure {
1635 public:
1636 void do_object(oop o) {
1637 if (o != NULL) {
1638 markWord mark = o->mark();
1639 if (mark.is_marked()) {
1640 o->init_mark();
1641 }
1642 }
1643 }
1644 };
1645
1646 // ObjectMarker provides the mark and visited functions
1647 class ObjectMarker : AllStatic {
1648 private:
1649 // saved headers
1650 static GrowableArray<oop>* _saved_oop_stack;
1651 static GrowableArray<markWord>* _saved_mark_stack;
1652 static bool _needs_reset; // do we need to reset mark bits?
1653
1654 public:
1655 static void init(); // initialize
1656 static void done(); // clean-up
1657
1658 static inline void mark(oop o); // mark an object
1659 static inline bool visited(oop o); // check if object has been visited
1660
1661 static inline bool needs_reset() { return _needs_reset; }
1662 static inline void set_needs_reset(bool v) { _needs_reset = v; }
1663 };
1664
1665 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1666 GrowableArray<markWord>* ObjectMarker::_saved_mark_stack = NULL;
1667 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default
1668
1669 // initialize ObjectMarker - prepares for object marking
1670 void ObjectMarker::init() {
1671 assert(Thread::current()->is_VM_thread(), "must be VMThread");
1672
1673 // prepare heap for iteration
1674 Universe::heap()->ensure_parsability(false); // no need to retire TLABs
1675
1676 // create stacks for interesting headers
1677 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markWord>(4000, true);
1678 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
1679
1680 if (UseBiasedLocking) {
1681 BiasedLocking::preserve_marks();
1682 }
1683 }
1684
1685 // Object marking is done so restore object headers
1686 void ObjectMarker::done() {
1687 // iterate over all objects and restore the mark bits to
1688 // their initial value
1689 RestoreMarksClosure blk;
1690 if (needs_reset()) {
1691 Universe::heap()->object_iterate(&blk);
1692 } else {
1693 // We don't need to reset mark bits on this call, but reset the
1694 // flag to the default for the next call.
1695 set_needs_reset(true);
1696 }
1697
1698 // now restore the interesting headers
1699 for (int i = 0; i < _saved_oop_stack->length(); i++) {
1700 oop o = _saved_oop_stack->at(i);
1701 markWord mark = _saved_mark_stack->at(i);
1702 o->set_mark(mark);
1703 }
1704
1705 if (UseBiasedLocking) {
1706 BiasedLocking::restore_marks();
1707 }
1708
1709 // free the stacks
1710 delete _saved_oop_stack;
1711 delete _saved_mark_stack;
1712 }
1713
1714 // mark an object
1715 inline void ObjectMarker::mark(oop o) {
1716 assert(Universe::heap()->is_in(o), "sanity check");
1717 assert(!o->mark().is_marked(), "should only mark an object once");
1718
1719 // object's mark word
1720 markWord mark = o->mark();
1721
1722 if (o->mark_must_be_preserved(mark)) {
1723 _saved_mark_stack->push(mark);
1724 _saved_oop_stack->push(o);
1725 }
1726
1727 // mark the object
1728 o->set_mark(markWord::prototype().set_marked());
1729 }
1730
1731 // return true if object is marked
1732 inline bool ObjectMarker::visited(oop o) {
1733 return o->mark().is_marked();
1734 }
1735
1736 // Stack allocated class to help ensure that ObjectMarker is used
1737 // correctly. Constructor initializes ObjectMarker, destructor calls
1738 // ObjectMarker's done() function to restore object headers.
1739 class ObjectMarkerController : public StackObj {
1740 public:
1741 ObjectMarkerController() {
1742 ObjectMarker::init();
1743 }
1744 ~ObjectMarkerController() {
1745 ObjectMarker::done();
1746 }
1747 };
1748
1749
1750 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1751 // (not performance critical as only used for roots)
1752 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1753 switch (kind) {
1754 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1755 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1756 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
1757 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
1758 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
1759 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
1760 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
1761 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
1762 }
1763 }
1764
1765 // Base class for all heap walk contexts. The base class maintains a flag
1838 const jvmtiHeapReferenceCallback heap_reference_callback() const {
1839 return _heap_callbacks->heap_reference_callback;
1840 };
1841 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1842 return _heap_callbacks->primitive_field_callback;
1843 }
1844 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1845 return _heap_callbacks->array_primitive_value_callback;
1846 }
1847 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1848 return _heap_callbacks->string_primitive_value_callback;
1849 }
1850 };
1851
1852 // The CallbackInvoker is a class with static functions that the heap walk can call
1853 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1854 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1855 // mode is for the newer FollowReferences function which supports a lot of
1856 // additional callbacks.
1857 class CallbackInvoker : AllStatic {
1858 private:
1859 // heap walk styles
1860 enum { basic, advanced };
1861 static int _heap_walk_type;
1862 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
1863 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
1864
1865 // context for basic style heap walk
1866 static BasicHeapWalkContext _basic_context;
1867 static BasicHeapWalkContext* basic_context() {
1868 assert(_basic_context.is_valid(), "invalid");
1869 return &_basic_context;
1870 }
1871
1872 // context for advanced style heap walk
1873 static AdvancedHeapWalkContext _advanced_context;
1874 static AdvancedHeapWalkContext* advanced_context() {
1875 assert(_advanced_context.is_valid(), "invalid");
1876 return &_advanced_context;
1877 }
1878
1879 // context needed for all heap walks
1880 static JvmtiTagMap* _tag_map;
1881 static const void* _user_data;
1882 static GrowableArray<oop>* _visit_stack;
1883
1884 // accessors
1885 static JvmtiTagMap* tag_map() { return _tag_map; }
1886 static const void* user_data() { return _user_data; }
1887 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
1888
1889 // if the object hasn't been visited then push it onto the visit stack
1890 // so that it will be visited later
1891 static inline bool check_for_visit(oop obj) {
1892 if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
1893 return true;
1894 }
1895
1896 // invoke basic style callbacks
1897 static inline bool invoke_basic_heap_root_callback
1898 (jvmtiHeapRootKind root_kind, oop obj);
1899 static inline bool invoke_basic_stack_ref_callback
1900 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1901 int slot, oop obj);
1902 static inline bool invoke_basic_object_reference_callback
1903 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1904
1905 // invoke advanced style callbacks
1906 static inline bool invoke_advanced_heap_root_callback
1907 (jvmtiHeapReferenceKind ref_kind, oop obj);
1908 static inline bool invoke_advanced_stack_ref_callback
1909 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1910 jmethodID method, jlocation bci, jint slot, oop obj);
1911 static inline bool invoke_advanced_object_reference_callback
1912 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1942 static inline bool report_signers_reference(oop referrer, oop referree);
1943 static inline bool report_protection_domain_reference(oop referrer, oop referree);
1944 static inline bool report_superclass_reference(oop referrer, oop referree);
1945 static inline bool report_interface_reference(oop referrer, oop referree);
1946 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1947 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1948 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1949 static inline bool report_primitive_array_values(oop array);
1950 static inline bool report_string_value(oop str);
1951 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1952 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1953 };
1954
1955 // statics
1956 int CallbackInvoker::_heap_walk_type;
1957 BasicHeapWalkContext CallbackInvoker::_basic_context;
1958 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1959 JvmtiTagMap* CallbackInvoker::_tag_map;
1960 const void* CallbackInvoker::_user_data;
1961 GrowableArray<oop>* CallbackInvoker::_visit_stack;
1962
1963 // initialize for basic heap walk (IterateOverReachableObjects et al)
1964 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1965 GrowableArray<oop>* visit_stack,
1966 const void* user_data,
1967 BasicHeapWalkContext context) {
1968 _tag_map = tag_map;
1969 _visit_stack = visit_stack;
1970 _user_data = user_data;
1971 _basic_context = context;
1972 _advanced_context.invalidate(); // will trigger assertion if used
1973 _heap_walk_type = basic;
1974 }
1975
1976 // initialize for advanced heap walk (FollowReferences)
1977 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1978 GrowableArray<oop>* visit_stack,
1979 const void* user_data,
1980 AdvancedHeapWalkContext context) {
1981 _tag_map = tag_map;
2532 }
2533
2534 // report an object referencing an instance field object
2535 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
2536 if (is_basic_heap_walk()) {
2537 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
2538 } else {
2539 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
2540 }
2541 }
2542
2543 // report an array referencing an element object
2544 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
2545 if (is_basic_heap_walk()) {
2546 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2547 } else {
2548 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2549 }
2550 }
2551
2552 // A supporting closure used to process simple roots
2553 class SimpleRootsClosure : public OopClosure {
2554 private:
2555 jvmtiHeapReferenceKind _kind;
2556 bool _continue;
2557
2558 jvmtiHeapReferenceKind root_kind() { return _kind; }
2559
2560 public:
2561 void set_kind(jvmtiHeapReferenceKind kind) {
2562 _kind = kind;
2563 _continue = true;
2564 }
2565
2566 inline bool stopped() {
2567 return !_continue;
2568 }
2569
2570 void do_oop(oop* obj_p) {
2571 // iteration has terminated
3175 // Collect the simple root for this thread before we
3176 // collect its stack roots
3177 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
3178 threadObj)) {
3179 return false;
3180 }
3181 if (!collect_stack_roots(thread, &blk)) {
3182 return false;
3183 }
3184 }
3185 }
3186 return true;
3187 }
3188
3189 // visit an object
3190 // first mark the object as visited
3191 // second get all the outbound references from this object (in other words, all
3192 // the objects referenced by this object).
3193 //
3194 bool VM_HeapWalkOperation::visit(oop o) {
3195 // mark object as visited
3196 assert(!ObjectMarker::visited(o), "can't visit same object more than once");
3197 ObjectMarker::mark(o);
3198
3199 // instance
3200 if (o->is_instance()) {
3201 if (o->klass() == SystemDictionary::Class_klass()) {
3202 if (!java_lang_Class::is_primitive(o)) {
3203 // a java.lang.Class
3204 return iterate_over_class(o);
3205 }
3206 } else {
3207 return iterate_over_object(o);
3208 }
3209 }
3210
3211 // object array
3212 if (o->is_objArray()) {
3213 return iterate_over_array(o);
3214 }
3215
3216 // type array
3217 if (o->is_typeArray()) {
3218 return iterate_over_type_array(o);
3219 }
3220
3221 return true;
3222 }
3223
3224 void VM_HeapWalkOperation::doit() {
3225 ResourceMark rm;
3226 ObjectMarkerController marker;
3227 ClassFieldMapCacheMark cm;
3228
3229 assert(visit_stack()->is_empty(), "visit stack must be empty");
3230
3231 // the heap walk starts with an initial object or the heap roots
3232 if (initial_object().is_null()) {
3233 // If either collect_stack_roots() or collect_simple_roots()
3234 // returns false at this point, then there are no mark bits
3235 // to reset.
3236 ObjectMarker::set_needs_reset(false);
3237
3238 // Calling collect_stack_roots() before collect_simple_roots()
3239 // can result in a big performance boost for an agent that is
3240 // focused on analyzing references in the thread stacks.
3241 if (!collect_stack_roots()) return;
3242
3243 if (!collect_simple_roots()) return;
3244
3245 // no early return so enable heap traversal to reset the mark bits
3246 ObjectMarker::set_needs_reset(true);
3247 } else {
3248 visit_stack()->push(initial_object()());
3249 }
3250
3251 // object references required
3252 if (is_following_references()) {
3253
3254 // visit each object until all reachable objects have been
3255 // visited or the callback asked to terminate the iteration.
3256 while (!visit_stack()->is_empty()) {
3257 oop o = visit_stack()->pop();
3258 if (!ObjectMarker::visited(o)) {
3259 if (!visit(o)) {
3260 break;
3261 }
3262 }
3263 }
3264 }
3265 }
3266
3267 // iterate over all objects that are reachable from a set of roots
3268 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3269 jvmtiStackReferenceCallback stack_ref_callback,
3270 jvmtiObjectReferenceCallback object_ref_callback,
3271 const void* user_data) {
3272 MutexLocker ml(Heap_lock);
3273 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3274 VM_HeapWalkOperation op(this, Handle(), context, user_data);
3275 VMThread::execute(&op);
3276 }
3277
3278 // iterate over all objects that are reachable from a given object
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoaderDataGraph.hpp"
27 #include "classfile/javaClasses.inline.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "classfile/vmSymbols.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "jvmtifiles/jvmtiEnv.hpp"
33 #include "logging/log.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "memory/universe.hpp"
37 #include "oops/access.inline.hpp"
38 #include "oops/arrayOop.inline.hpp"
39 #include "oops/constantPool.inline.hpp"
40 #include "oops/instanceMirrorKlass.hpp"
41 #include "oops/objArrayKlass.hpp"
42 #include "oops/objArrayOop.inline.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "oops/typeArrayOop.inline.hpp"
45 #include "prims/jvmtiEventController.hpp"
46 #include "prims/jvmtiEventController.inline.hpp"
47 #include "prims/jvmtiExport.hpp"
48 #include "prims/jvmtiImpl.hpp"
49 #include "prims/jvmtiTagMap.hpp"
50 #include "runtime/frame.inline.hpp"
51 #include "runtime/handles.inline.hpp"
52 #include "runtime/javaCalls.hpp"
53 #include "runtime/jniHandles.inline.hpp"
54 #include "runtime/mutex.hpp"
55 #include "runtime/mutexLocker.hpp"
56 #include "runtime/reflectionUtils.hpp"
57 #include "runtime/thread.inline.hpp"
58 #include "runtime/threadSMR.hpp"
59 #include "runtime/vframe.hpp"
60 #include "runtime/vmThread.hpp"
61 #include "runtime/vmOperations.hpp"
62 #include "utilities/macros.hpp"
63 #if INCLUDE_ZGC
64 #include "gc/z/zGlobals.hpp"
65 #endif
66
67 // JvmtiTagHashmapEntry
68 //
69 // Each entry encapsulates a reference to the tagged object
1595 }
1596
1597 *count_ptr = count;
1598 return JVMTI_ERROR_NONE;
1599 }
1600 };
1601
1602 // return the list of objects with the specified tags
1603 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
1604 jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1605
1606 TagObjectCollector collector(env(), tags, count);
1607 {
1608 // iterate over all tagged objects
1609 MutexLocker ml(lock());
1610 entry_iterate(&collector);
1611 }
1612 return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
1613 }
1614
1615 // Stack allocated class to help ensure that ObjectMarker is used
1616 // correctly. Constructor initializes ObjectMarker, destructor calls
1617 // ObjectMarker's done() function to restore object headers.
1618 class ObjectMarkerController : public StackObj {
1619 private:
1620 ObjectMarker* _marker;
1621
1622 public:
1623 ObjectMarkerController();
1624 ~ObjectMarkerController();
1625
1626 bool init();
1627
1628 inline ObjectMarker* object_marker() const {
1629 return _marker;
1630 }
1631 };
1632
1633
1634 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1635 // (not performance critical as only used for roots)
1636 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1637 switch (kind) {
1638 case JVMTI_HEAP_REFERENCE_JNI_GLOBAL: return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1639 case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1640 case JVMTI_HEAP_REFERENCE_MONITOR: return JVMTI_HEAP_ROOT_MONITOR;
1641 case JVMTI_HEAP_REFERENCE_STACK_LOCAL: return JVMTI_HEAP_ROOT_STACK_LOCAL;
1642 case JVMTI_HEAP_REFERENCE_JNI_LOCAL: return JVMTI_HEAP_ROOT_JNI_LOCAL;
1643 case JVMTI_HEAP_REFERENCE_THREAD: return JVMTI_HEAP_ROOT_THREAD;
1644 case JVMTI_HEAP_REFERENCE_OTHER: return JVMTI_HEAP_ROOT_OTHER;
1645 default: ShouldNotReachHere(); return JVMTI_HEAP_ROOT_OTHER;
1646 }
1647 }
1648
1649 // Base class for all heap walk contexts. The base class maintains a flag
1722 const jvmtiHeapReferenceCallback heap_reference_callback() const {
1723 return _heap_callbacks->heap_reference_callback;
1724 };
1725 const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1726 return _heap_callbacks->primitive_field_callback;
1727 }
1728 const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1729 return _heap_callbacks->array_primitive_value_callback;
1730 }
1731 const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1732 return _heap_callbacks->string_primitive_value_callback;
1733 }
1734 };
1735
1736 // The CallbackInvoker is a class with static functions that the heap walk can call
1737 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1738 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1739 // mode is for the newer FollowReferences function which supports a lot of
1740 // additional callbacks.
1741 class CallbackInvoker : AllStatic {
1742 friend class ObjectMarkerController;
1743
1744 private:
1745 // heap walk styles
1746 enum { basic, advanced };
1747 static int _heap_walk_type;
1748 static bool is_basic_heap_walk() { return _heap_walk_type == basic; }
1749 static bool is_advanced_heap_walk() { return _heap_walk_type == advanced; }
1750
1751 // context for basic style heap walk
1752 static BasicHeapWalkContext _basic_context;
1753 static BasicHeapWalkContext* basic_context() {
1754 assert(_basic_context.is_valid(), "invalid");
1755 return &_basic_context;
1756 }
1757
1758 // context for advanced style heap walk
1759 static AdvancedHeapWalkContext _advanced_context;
1760 static AdvancedHeapWalkContext* advanced_context() {
1761 assert(_advanced_context.is_valid(), "invalid");
1762 return &_advanced_context;
1763 }
1764
1765 // context needed for all heap walks
1766 static JvmtiTagMap* _tag_map;
1767 static const void* _user_data;
1768 static GrowableArray<oop>* _visit_stack;
1769 static ObjectMarker* _object_marker;
1770
1771 // accessors
1772 static JvmtiTagMap* tag_map() { return _tag_map; }
1773 static const void* user_data() { return _user_data; }
1774 static GrowableArray<oop>* visit_stack() { return _visit_stack; }
1775
1776 // if the object hasn't been visited then push it onto the visit stack
1777 // so that it will be visited later
1778 static inline bool check_for_visit(oop obj) {
1779 if (!_object_marker->marked(obj)) visit_stack()->push(obj);
1780 return true;
1781 }
1782
1783 // invoke basic style callbacks
1784 static inline bool invoke_basic_heap_root_callback
1785 (jvmtiHeapRootKind root_kind, oop obj);
1786 static inline bool invoke_basic_stack_ref_callback
1787 (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1788 int slot, oop obj);
1789 static inline bool invoke_basic_object_reference_callback
1790 (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1791
1792 // invoke advanced style callbacks
1793 static inline bool invoke_advanced_heap_root_callback
1794 (jvmtiHeapReferenceKind ref_kind, oop obj);
1795 static inline bool invoke_advanced_stack_ref_callback
1796 (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1797 jmethodID method, jlocation bci, jint slot, oop obj);
1798 static inline bool invoke_advanced_object_reference_callback
1799 (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1829 static inline bool report_signers_reference(oop referrer, oop referree);
1830 static inline bool report_protection_domain_reference(oop referrer, oop referree);
1831 static inline bool report_superclass_reference(oop referrer, oop referree);
1832 static inline bool report_interface_reference(oop referrer, oop referree);
1833 static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1834 static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1835 static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1836 static inline bool report_primitive_array_values(oop array);
1837 static inline bool report_string_value(oop str);
1838 static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1839 static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1840 };
1841
1842 // statics
1843 int CallbackInvoker::_heap_walk_type;
1844 BasicHeapWalkContext CallbackInvoker::_basic_context;
1845 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1846 JvmtiTagMap* CallbackInvoker::_tag_map;
1847 const void* CallbackInvoker::_user_data;
1848 GrowableArray<oop>* CallbackInvoker::_visit_stack;
1849 ObjectMarker* CallbackInvoker::_object_marker;
1850
1851 // initialize for basic heap walk (IterateOverReachableObjects et al)
1852 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1853 GrowableArray<oop>* visit_stack,
1854 const void* user_data,
1855 BasicHeapWalkContext context) {
1856 _tag_map = tag_map;
1857 _visit_stack = visit_stack;
1858 _user_data = user_data;
1859 _basic_context = context;
1860 _advanced_context.invalidate(); // will trigger assertion if used
1861 _heap_walk_type = basic;
1862 }
1863
1864 // initialize for advanced heap walk (FollowReferences)
1865 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1866 GrowableArray<oop>* visit_stack,
1867 const void* user_data,
1868 AdvancedHeapWalkContext context) {
1869 _tag_map = tag_map;
2420 }
2421
2422 // report an object referencing an instance field object
2423 inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
2424 if (is_basic_heap_walk()) {
2425 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
2426 } else {
2427 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
2428 }
2429 }
2430
2431 // report an array referencing an element object
2432 inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
2433 if (is_basic_heap_walk()) {
2434 return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2435 } else {
2436 return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
2437 }
2438 }
2439
2440
2441 ObjectMarkerController::ObjectMarkerController() {
2442 _marker = Universe::heap()->object_marker();
2443 }
2444
2445 bool ObjectMarkerController::init() {
2446 if (_marker->init()) {
2447 CallbackInvoker::_object_marker = _marker;
2448 return true;
2449 } else {
2450 return false;
2451 }
2452 }
2453
2454 ObjectMarkerController::~ObjectMarkerController() {
2455 CallbackInvoker::_object_marker = NULL;
2456 _marker->done();
2457 }
2458
2459 // A supporting closure used to process simple roots
2460 class SimpleRootsClosure : public OopClosure {
2461 private:
2462 jvmtiHeapReferenceKind _kind;
2463 bool _continue;
2464
2465 jvmtiHeapReferenceKind root_kind() { return _kind; }
2466
2467 public:
2468 void set_kind(jvmtiHeapReferenceKind kind) {
2469 _kind = kind;
2470 _continue = true;
2471 }
2472
2473 inline bool stopped() {
2474 return !_continue;
2475 }
2476
2477 void do_oop(oop* obj_p) {
2478 // iteration has terminated
3082 // Collect the simple root for this thread before we
3083 // collect its stack roots
3084 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
3085 threadObj)) {
3086 return false;
3087 }
3088 if (!collect_stack_roots(thread, &blk)) {
3089 return false;
3090 }
3091 }
3092 }
3093 return true;
3094 }
3095
3096 // visit an object
3097 // first mark the object as visited
3098 // second get all the outbound references from this object (in other words, all
3099 // the objects referenced by this object).
3100 //
3101 bool VM_HeapWalkOperation::visit(oop o) {
3102 // instance
3103 if (o->is_instance()) {
3104 if (o->klass() == SystemDictionary::Class_klass()) {
3105 if (!java_lang_Class::is_primitive(o)) {
3106 // a java.lang.Class
3107 return iterate_over_class(o);
3108 }
3109 } else {
3110 return iterate_over_object(o);
3111 }
3112 }
3113
3114 // object array
3115 if (o->is_objArray()) {
3116 return iterate_over_array(o);
3117 }
3118
3119 // type array
3120 if (o->is_typeArray()) {
3121 return iterate_over_type_array(o);
3122 }
3123
3124 return true;
3125 }
3126
3127 void VM_HeapWalkOperation::doit() {
3128 ResourceMark rm;
3129 ObjectMarkerController marker;
3130 if (!marker.init()) {
3131 return;
3132 }
3133
3134 ClassFieldMapCacheMark cm;
3135 assert(visit_stack()->is_empty(), "visit stack must be empty");
3136 ObjectMarker* const object_marker = marker.object_marker();
3137
3138 // the heap walk starts with an initial object or the heap roots
3139 if (initial_object().is_null()) {
3140 // If either collect_stack_roots() or collect_simple_roots()
3141 // returns false at this point, then there are no mark bits
3142 // to reset.
3143 object_marker->set_needs_reset(false);
3144
3145 // Calling collect_stack_roots() before collect_simple_roots()
3146 // can result in a big performance boost for an agent that is
3147 // focused on analyzing references in the thread stacks.
3148 if (!collect_stack_roots()) return;
3149
3150 if (!collect_simple_roots()) return;
3151
3152 // no early return so enable heap traversal to reset the mark bits
3153 object_marker->set_needs_reset(true);
3154 } else {
3155 visit_stack()->push(initial_object()());
3156 }
3157
3158 // object references required
3159 if (is_following_references()) {
3160
3161 // visit each object until all reachable objects have been
3162 // visited or the callback asked to terminate the iteration.
3163 while (!visit_stack()->is_empty()) {
3164 oop o = visit_stack()->pop();
3165 if (object_marker->mark(o)) {
3166 if (!visit(o)) {
3167 break;
3168 }
3169 }
3170 }
3171 }
3172 }
3173
3174 // iterate over all objects that are reachable from a set of roots
3175 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3176 jvmtiStackReferenceCallback stack_ref_callback,
3177 jvmtiObjectReferenceCallback object_ref_callback,
3178 const void* user_data) {
3179 MutexLocker ml(Heap_lock);
3180 BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3181 VM_HeapWalkOperation op(this, Handle(), context, user_data);
3182 VMThread::execute(&op);
3183 }
3184
3185 // iterate over all objects that are reachable from a given object
|