38 #include "oops/objArrayKlass.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/typeArrayOop.inline.hpp"
42 #include "prims/jvmtiEventController.hpp"
43 #include "prims/jvmtiEventController.inline.hpp"
44 #include "prims/jvmtiExport.hpp"
45 #include "prims/jvmtiImpl.hpp"
46 #include "prims/jvmtiTagMap.hpp"
47 #include "runtime/biasedLocking.hpp"
48 #include "runtime/javaCalls.hpp"
49 #include "runtime/jniHandles.inline.hpp"
50 #include "runtime/mutex.hpp"
51 #include "runtime/mutexLocker.hpp"
52 #include "runtime/reflectionUtils.hpp"
53 #include "runtime/thread.inline.hpp"
54 #include "runtime/threadSMR.hpp"
55 #include "runtime/vframe.hpp"
56 #include "runtime/vmThread.hpp"
57 #include "runtime/vm_operations.hpp"
58 #include "services/serviceUtil.hpp"
59 #include "utilities/macros.hpp"
60
61 // JvmtiTagHashmapEntry
62 //
63 // Each entry encapsulates a reference to the tagged object
64 // and the tag value. In addition an entry includes a next pointer which
65 // is used to chain entries together.
66
67 class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> {
68 private:
69 friend class JvmtiTagMap;
70
71 oop _object; // tagged object
72 jlong _tag; // the tag
73 JvmtiTagHashmapEntry* _next; // next on the list
74
75 inline void init(oop object, jlong tag) {
76 _object = object;
77 _tag = tag;
78 _next = NULL;
1307 jvmtiHeapObjectFilter object_filter,
1308 jvmtiHeapObjectCallback heap_object_callback,
1309 const void* user_data) :
1310 _tag_map(tag_map),
1311 _klass(klass),
1312 _object_filter(object_filter),
1313 _heap_object_callback(heap_object_callback),
1314 _user_data(user_data),
1315 _iteration_aborted(false)
1316 {
1317 }
1318
1319 void do_object(oop o);
1320 };
1321
1322 // invoked for each object in the heap
1323 void IterateOverHeapObjectClosure::do_object(oop o) {
1324 // check if iteration has been halted
1325 if (is_iteration_aborted()) return;
1326
1327 // ignore any objects that aren't visible to profiler
1328 if (!ServiceUtil::visible_oop(o)) return;
1329
1330 // instanceof check when filtering by klass
1331 if (klass() != NULL && !o->is_a(klass())) {
1332 return;
1333 }
1334 // prepare for the calllback
1335 CallbackWrapper wrapper(tag_map(), o);
1336
1337 // if the object is tagged and we're only interested in untagged objects
1338 // then don't invoke the callback. Similiarly, if the object is untagged
1339 // and we're only interested in tagged objects we skip the callback.
1340 if (wrapper.obj_tag() != 0) {
1341 if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
1342 } else {
1343 if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
1344 }
1345
1346 // invoke the agent's callback
1347 jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
1348 wrapper.obj_size(),
1349 wrapper.obj_tag_p(),
1390 int heap_filter,
1391 const jvmtiHeapCallbacks* heap_callbacks,
1392 const void* user_data) :
1393 _tag_map(tag_map),
1394 _klass(klass),
1395 _heap_filter(heap_filter),
1396 _callbacks(heap_callbacks),
1397 _user_data(user_data),
1398 _iteration_aborted(false)
1399 {
1400 }
1401
1402 void do_object(oop o);
1403 };
1404
1405 // invoked for each object in the heap
1406 void IterateThroughHeapObjectClosure::do_object(oop obj) {
1407 // check if iteration has been halted
1408 if (is_iteration_aborted()) return;
1409
1410 // ignore any objects that aren't visible to profiler
1411 if (!ServiceUtil::visible_oop(obj)) return;
1412
1413 // apply class filter
1414 if (is_filtered_by_klass_filter(obj, klass())) return;
1415
1416 // prepare for callback
1417 CallbackWrapper wrapper(tag_map(), obj);
1418
1419 // check if filtered by the heap filter
1420 if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) {
1421 return;
1422 }
1423
1424 // for arrays we need the length, otherwise -1
1425 bool is_array = obj->is_array();
1426 int len = is_array ? arrayOop(obj)->length() : -1;
1427
1428 // invoke the object callback (if callback is provided)
1429 if (callbacks()->heap_iteration_callback != NULL) {
1430 jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback;
1431 jint res = (*cb)(wrapper.klass_tag(),
1432 wrapper.obj_size(),
1970 _advanced_context.invalidate(); // will trigger assertion if used
1971 _heap_walk_type = basic;
1972 }
1973
1974 // initialize for advanced heap walk (FollowReferences)
1975 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1976 GrowableArray<oop>* visit_stack,
1977 const void* user_data,
1978 AdvancedHeapWalkContext context) {
1979 _tag_map = tag_map;
1980 _visit_stack = visit_stack;
1981 _user_data = user_data;
1982 _advanced_context = context;
1983 _basic_context.invalidate(); // will trigger assertion if used
1984 _heap_walk_type = advanced;
1985 }
1986
1987
1988 // invoke basic style heap root callback
1989 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1990 assert(ServiceUtil::visible_oop(obj), "checking");
1991
1992 // if we heap roots should be reported
1993 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
1994 if (cb == NULL) {
1995 return check_for_visit(obj);
1996 }
1997
1998 CallbackWrapper wrapper(tag_map(), obj);
1999 jvmtiIterationControl control = (*cb)(root_kind,
2000 wrapper.klass_tag(),
2001 wrapper.obj_size(),
2002 wrapper.obj_tag_p(),
2003 (void*)user_data());
2004 // push root to visit stack when following references
2005 if (control == JVMTI_ITERATION_CONTINUE &&
2006 basic_context()->object_ref_callback() != NULL) {
2007 visit_stack()->push(obj);
2008 }
2009 return control != JVMTI_ITERATION_ABORT;
2010 }
2011
2012 // invoke basic style stack ref callback
2013 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
2014 jlong thread_tag,
2015 jint depth,
2016 jmethodID method,
2017 int slot,
2018 oop obj) {
2019 assert(ServiceUtil::visible_oop(obj), "checking");
2020
2021 // if we stack refs should be reported
2022 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
2023 if (cb == NULL) {
2024 return check_for_visit(obj);
2025 }
2026
2027 CallbackWrapper wrapper(tag_map(), obj);
2028 jvmtiIterationControl control = (*cb)(root_kind,
2029 wrapper.klass_tag(),
2030 wrapper.obj_size(),
2031 wrapper.obj_tag_p(),
2032 thread_tag,
2033 depth,
2034 method,
2035 slot,
2036 (void*)user_data());
2037 // push root to visit stack when following references
2038 if (control == JVMTI_ITERATION_CONTINUE &&
2039 basic_context()->object_ref_callback() != NULL) {
2040 visit_stack()->push(obj);
2041 }
2042 return control != JVMTI_ITERATION_ABORT;
2043 }
2044
2045 // invoke basic style object reference callback
2046 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
2047 oop referrer,
2048 oop referree,
2049 jint index) {
2050
2051 assert(ServiceUtil::visible_oop(referrer), "checking");
2052 assert(ServiceUtil::visible_oop(referree), "checking");
2053
2054 BasicHeapWalkContext* context = basic_context();
2055
2056 // callback requires the referrer's tag. If it's the same referrer
2057 // as the last call then we use the cached value.
2058 jlong referrer_tag;
2059 if (referrer == context->last_referrer()) {
2060 referrer_tag = context->last_referrer_tag();
2061 } else {
2062 referrer_tag = tag_for(tag_map(), referrer);
2063 }
2064
2065 // do the callback
2066 CallbackWrapper wrapper(tag_map(), referree);
2067 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
2068 jvmtiIterationControl control = (*cb)(ref_kind,
2069 wrapper.klass_tag(),
2070 wrapper.obj_size(),
2071 wrapper.obj_tag_p(),
2072 referrer_tag,
2073 index,
2075
2076 // record referrer and referrer tag. For self-references record the
2077 // tag value from the callback as this might differ from referrer_tag.
2078 context->set_last_referrer(referrer);
2079 if (referrer == referree) {
2080 context->set_last_referrer_tag(*wrapper.obj_tag_p());
2081 } else {
2082 context->set_last_referrer_tag(referrer_tag);
2083 }
2084
2085 if (control == JVMTI_ITERATION_CONTINUE) {
2086 return check_for_visit(referree);
2087 } else {
2088 return control != JVMTI_ITERATION_ABORT;
2089 }
2090 }
2091
2092 // invoke advanced style heap root callback
2093 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
2094 oop obj) {
2095 assert(ServiceUtil::visible_oop(obj), "checking");
2096
2097 AdvancedHeapWalkContext* context = advanced_context();
2098
2099 // check that callback is provided
2100 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2101 if (cb == NULL) {
2102 return check_for_visit(obj);
2103 }
2104
2105 // apply class filter
2106 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2107 return check_for_visit(obj);
2108 }
2109
2110 // setup the callback wrapper
2111 CallbackWrapper wrapper(tag_map(), obj);
2112
2113 // apply tag filter
2114 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2115 wrapper.klass_tag(),
2116 context->heap_filter())) {
2131 len,
2132 (void*)user_data());
2133 if (res & JVMTI_VISIT_ABORT) {
2134 return false;// referrer class tag
2135 }
2136 if (res & JVMTI_VISIT_OBJECTS) {
2137 check_for_visit(obj);
2138 }
2139 return true;
2140 }
2141
2142 // report a reference from a thread stack to an object
2143 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
2144 jlong thread_tag,
2145 jlong tid,
2146 int depth,
2147 jmethodID method,
2148 jlocation bci,
2149 jint slot,
2150 oop obj) {
2151 assert(ServiceUtil::visible_oop(obj), "checking");
2152
2153 AdvancedHeapWalkContext* context = advanced_context();
2154
2155 // check that callback is provider
2156 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2157 if (cb == NULL) {
2158 return check_for_visit(obj);
2159 }
2160
2161 // apply class filter
2162 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2163 return check_for_visit(obj);
2164 }
2165
2166 // setup the callback wrapper
2167 CallbackWrapper wrapper(tag_map(), obj);
2168
2169 // apply tag filter
2170 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2171 wrapper.klass_tag(),
2172 context->heap_filter())) {
2206 }
2207
2208 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
2209 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
2210 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
2211 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
2212 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
2213 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
2214 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
2215 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
2216
2217 // invoke the object reference callback to report a reference
2218 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
2219 oop referrer,
2220 oop obj,
2221 jint index)
2222 {
2223 // field index is only valid field in reference_info
2224 static jvmtiHeapReferenceInfo reference_info = { 0 };
2225
2226 assert(ServiceUtil::visible_oop(referrer), "checking");
2227 assert(ServiceUtil::visible_oop(obj), "checking");
2228
2229 AdvancedHeapWalkContext* context = advanced_context();
2230
2231 // check that callback is provider
2232 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2233 if (cb == NULL) {
2234 return check_for_visit(obj);
2235 }
2236
2237 // apply class filter
2238 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2239 return check_for_visit(obj);
2240 }
2241
2242 // setup the callback wrapper
2243 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
2244
2245 // apply tag filter
2246 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2247 wrapper.klass_tag(),
2248 context->heap_filter())) {
2262 wrapper.referrer_klass_tag(),
2263 wrapper.obj_size(),
2264 wrapper.obj_tag_p(),
2265 wrapper.referrer_tag_p(),
2266 len,
2267 (void*)user_data());
2268
2269 if (res & JVMTI_VISIT_ABORT) {
2270 return false;
2271 }
2272 if (res & JVMTI_VISIT_OBJECTS) {
2273 check_for_visit(obj);
2274 }
2275 return true;
2276 }
2277
2278 // report a "simple root"
2279 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
2280 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
2281 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
2282 assert(ServiceUtil::visible_oop(obj), "checking");
2283
2284 if (is_basic_heap_walk()) {
2285 // map to old style root kind
2286 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
2287 return invoke_basic_heap_root_callback(root_kind, obj);
2288 } else {
2289 assert(is_advanced_heap_walk(), "wrong heap walk type");
2290 return invoke_advanced_heap_root_callback(kind, obj);
2291 }
2292 }
2293
2294
2295 // invoke the primitive array values
2296 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
2297 assert(obj->is_typeArray(), "not a primitive array");
2298
2299 AdvancedHeapWalkContext* context = advanced_context();
2300 assert(context->array_primitive_value_callback() != NULL, "no callback");
2301
2302 // apply class filter
2587 }
2588
2589 oop o = *obj_p;
2590 // ignore null
2591 if (o == NULL) {
2592 return;
2593 }
2594
2595 assert(Universe::heap()->is_in_reserved(o), "should be impossible");
2596
2597 jvmtiHeapReferenceKind kind = root_kind();
2598 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2599 // SystemDictionary::always_strong_oops_do reports the application
2600 // class loader as a root. We want this root to be reported as
2601 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2602 if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
2603 kind = JVMTI_HEAP_REFERENCE_OTHER;
2604 }
2605 }
2606
2607 // some objects are ignored - in the case of simple
2608 // roots it's mostly Symbol*s that we are skipping
2609 // here.
2610 if (!ServiceUtil::visible_oop(o)) {
2611 return;
2612 }
2613
2614 // invoke the callback
2615 _continue = CallbackInvoker::report_simple_root(kind, o);
2616
2617 }
2618 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2619 };
2620
2621 // A supporting closure used to process JNI locals
2622 class JNILocalRootsClosure : public OopClosure {
2623 private:
2624 jlong _thread_tag;
2625 jlong _tid;
2626 jint _depth;
2627 jmethodID _method;
2628 bool _continue;
2629 public:
2630 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
2631 _thread_tag = thread_tag;
2632 _tid = tid;
2633 _depth = depth;
2634 _method = method;
2635 _continue = true;
2636 }
2637
2638 inline bool stopped() {
2639 return !_continue;
2640 }
2641
2642 void do_oop(oop* obj_p) {
2643 // iteration has terminated
2644 if (stopped()) {
2645 return;
2646 }
2647
2648 oop o = *obj_p;
2649 // ignore null
2650 if (o == NULL) {
2651 return;
2652 }
2653
2654 if (!ServiceUtil::visible_oop(o)) {
2655 return;
2656 }
2657
2658 // invoke the callback
2659 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
2660 }
2661 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2662 };
2663
2664
2665 // A VM operation to iterate over objects that are reachable from
2666 // a set of roots or an initial object.
2667 //
2668 // For VM_HeapWalkOperation the set of roots used is :-
2669 //
2670 // - All JNI global references
2671 // - All inflated monitors
2672 // - All classes loaded by the boot class loader (or all classes
2673 // in the event that class unloading is disabled)
2674 // - All java threads
2675 // - For each java thread then all locals and JNI local references
2676 // on the thread's execution stack
2677 // - All visible/explainable objects from Universes::oops_do
2965 return true;
2966 }
2967
2968 // an object references a class and its instance fields
2969 // (static fields are ignored here as we report these as
2970 // references from the class).
2971 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2972 // reference to the class
2973 if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
2974 return false;
2975 }
2976
2977 // iterate over instance fields
2978 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2979 for (int i=0; i<field_map->field_count(); i++) {
2980 ClassFieldDescriptor* field = field_map->field_at(i);
2981 char type = field->field_type();
2982 if (!is_primitive_field_type(type)) {
2983 oop fld_o = o->obj_field(field->field_offset());
2984 // ignore any objects that aren't visible to profiler
2985 if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
2986 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
2987 "have references to Klass* anymore");
2988 int slot = field->field_index();
2989 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
2990 return false;
2991 }
2992 }
2993 } else {
2994 if (is_reporting_primitive_fields()) {
2995 // primitive instance field
2996 address addr = (address)o + field->field_offset();
2997 int slot = field->field_index();
2998 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
2999 return false;
3000 }
3001 }
3002 }
3003 }
3004
3005 // if the object is a java.lang.String
|
38 #include "oops/objArrayKlass.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/typeArrayOop.inline.hpp"
42 #include "prims/jvmtiEventController.hpp"
43 #include "prims/jvmtiEventController.inline.hpp"
44 #include "prims/jvmtiExport.hpp"
45 #include "prims/jvmtiImpl.hpp"
46 #include "prims/jvmtiTagMap.hpp"
47 #include "runtime/biasedLocking.hpp"
48 #include "runtime/javaCalls.hpp"
49 #include "runtime/jniHandles.inline.hpp"
50 #include "runtime/mutex.hpp"
51 #include "runtime/mutexLocker.hpp"
52 #include "runtime/reflectionUtils.hpp"
53 #include "runtime/thread.inline.hpp"
54 #include "runtime/threadSMR.hpp"
55 #include "runtime/vframe.hpp"
56 #include "runtime/vmThread.hpp"
57 #include "runtime/vm_operations.hpp"
58 #include "utilities/macros.hpp"
59
60 // JvmtiTagHashmapEntry
61 //
62 // Each entry encapsulates a reference to the tagged object
63 // and the tag value. In addition an entry includes a next pointer which
64 // is used to chain entries together.
65
66 class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> {
67 private:
68 friend class JvmtiTagMap;
69
70 oop _object; // tagged object
71 jlong _tag; // the tag
72 JvmtiTagHashmapEntry* _next; // next on the list
73
74 inline void init(oop object, jlong tag) {
75 _object = object;
76 _tag = tag;
77 _next = NULL;
1306 jvmtiHeapObjectFilter object_filter,
1307 jvmtiHeapObjectCallback heap_object_callback,
1308 const void* user_data) :
1309 _tag_map(tag_map),
1310 _klass(klass),
1311 _object_filter(object_filter),
1312 _heap_object_callback(heap_object_callback),
1313 _user_data(user_data),
1314 _iteration_aborted(false)
1315 {
1316 }
1317
1318 void do_object(oop o);
1319 };
1320
1321 // invoked for each object in the heap
1322 void IterateOverHeapObjectClosure::do_object(oop o) {
1323 // check if iteration has been halted
1324 if (is_iteration_aborted()) return;
1325
1326 // instanceof check when filtering by klass
1327 if (klass() != NULL && !o->is_a(klass())) {
1328 return;
1329 }
1330 // prepare for the calllback
1331 CallbackWrapper wrapper(tag_map(), o);
1332
1333 // if the object is tagged and we're only interested in untagged objects
1334 // then don't invoke the callback. Similiarly, if the object is untagged
1335 // and we're only interested in tagged objects we skip the callback.
1336 if (wrapper.obj_tag() != 0) {
1337 if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
1338 } else {
1339 if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
1340 }
1341
1342 // invoke the agent's callback
1343 jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
1344 wrapper.obj_size(),
1345 wrapper.obj_tag_p(),
1386 int heap_filter,
1387 const jvmtiHeapCallbacks* heap_callbacks,
1388 const void* user_data) :
1389 _tag_map(tag_map),
1390 _klass(klass),
1391 _heap_filter(heap_filter),
1392 _callbacks(heap_callbacks),
1393 _user_data(user_data),
1394 _iteration_aborted(false)
1395 {
1396 }
1397
1398 void do_object(oop o);
1399 };
1400
1401 // invoked for each object in the heap
1402 void IterateThroughHeapObjectClosure::do_object(oop obj) {
1403 // check if iteration has been halted
1404 if (is_iteration_aborted()) return;
1405
1406 // apply class filter
1407 if (is_filtered_by_klass_filter(obj, klass())) return;
1408
1409 // prepare for callback
1410 CallbackWrapper wrapper(tag_map(), obj);
1411
1412 // check if filtered by the heap filter
1413 if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) {
1414 return;
1415 }
1416
1417 // for arrays we need the length, otherwise -1
1418 bool is_array = obj->is_array();
1419 int len = is_array ? arrayOop(obj)->length() : -1;
1420
1421 // invoke the object callback (if callback is provided)
1422 if (callbacks()->heap_iteration_callback != NULL) {
1423 jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback;
1424 jint res = (*cb)(wrapper.klass_tag(),
1425 wrapper.obj_size(),
1963 _advanced_context.invalidate(); // will trigger assertion if used
1964 _heap_walk_type = basic;
1965 }
1966
1967 // initialize for advanced heap walk (FollowReferences)
1968 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1969 GrowableArray<oop>* visit_stack,
1970 const void* user_data,
1971 AdvancedHeapWalkContext context) {
1972 _tag_map = tag_map;
1973 _visit_stack = visit_stack;
1974 _user_data = user_data;
1975 _advanced_context = context;
1976 _basic_context.invalidate(); // will trigger assertion if used
1977 _heap_walk_type = advanced;
1978 }
1979
1980
1981 // invoke basic style heap root callback
1982 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1983 // if we heap roots should be reported
1984 jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
1985 if (cb == NULL) {
1986 return check_for_visit(obj);
1987 }
1988
1989 CallbackWrapper wrapper(tag_map(), obj);
1990 jvmtiIterationControl control = (*cb)(root_kind,
1991 wrapper.klass_tag(),
1992 wrapper.obj_size(),
1993 wrapper.obj_tag_p(),
1994 (void*)user_data());
1995 // push root to visit stack when following references
1996 if (control == JVMTI_ITERATION_CONTINUE &&
1997 basic_context()->object_ref_callback() != NULL) {
1998 visit_stack()->push(obj);
1999 }
2000 return control != JVMTI_ITERATION_ABORT;
2001 }
2002
2003 // invoke basic style stack ref callback
2004 inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
2005 jlong thread_tag,
2006 jint depth,
2007 jmethodID method,
2008 int slot,
2009 oop obj) {
2010 // if we stack refs should be reported
2011 jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
2012 if (cb == NULL) {
2013 return check_for_visit(obj);
2014 }
2015
2016 CallbackWrapper wrapper(tag_map(), obj);
2017 jvmtiIterationControl control = (*cb)(root_kind,
2018 wrapper.klass_tag(),
2019 wrapper.obj_size(),
2020 wrapper.obj_tag_p(),
2021 thread_tag,
2022 depth,
2023 method,
2024 slot,
2025 (void*)user_data());
2026 // push root to visit stack when following references
2027 if (control == JVMTI_ITERATION_CONTINUE &&
2028 basic_context()->object_ref_callback() != NULL) {
2029 visit_stack()->push(obj);
2030 }
2031 return control != JVMTI_ITERATION_ABORT;
2032 }
2033
2034 // invoke basic style object reference callback
2035 inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
2036 oop referrer,
2037 oop referree,
2038 jint index) {
2039
2040 BasicHeapWalkContext* context = basic_context();
2041
2042 // callback requires the referrer's tag. If it's the same referrer
2043 // as the last call then we use the cached value.
2044 jlong referrer_tag;
2045 if (referrer == context->last_referrer()) {
2046 referrer_tag = context->last_referrer_tag();
2047 } else {
2048 referrer_tag = tag_for(tag_map(), referrer);
2049 }
2050
2051 // do the callback
2052 CallbackWrapper wrapper(tag_map(), referree);
2053 jvmtiObjectReferenceCallback cb = context->object_ref_callback();
2054 jvmtiIterationControl control = (*cb)(ref_kind,
2055 wrapper.klass_tag(),
2056 wrapper.obj_size(),
2057 wrapper.obj_tag_p(),
2058 referrer_tag,
2059 index,
2061
2062 // record referrer and referrer tag. For self-references record the
2063 // tag value from the callback as this might differ from referrer_tag.
2064 context->set_last_referrer(referrer);
2065 if (referrer == referree) {
2066 context->set_last_referrer_tag(*wrapper.obj_tag_p());
2067 } else {
2068 context->set_last_referrer_tag(referrer_tag);
2069 }
2070
2071 if (control == JVMTI_ITERATION_CONTINUE) {
2072 return check_for_visit(referree);
2073 } else {
2074 return control != JVMTI_ITERATION_ABORT;
2075 }
2076 }
2077
2078 // invoke advanced style heap root callback
2079 inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
2080 oop obj) {
2081 AdvancedHeapWalkContext* context = advanced_context();
2082
2083 // check that callback is provided
2084 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2085 if (cb == NULL) {
2086 return check_for_visit(obj);
2087 }
2088
2089 // apply class filter
2090 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2091 return check_for_visit(obj);
2092 }
2093
2094 // setup the callback wrapper
2095 CallbackWrapper wrapper(tag_map(), obj);
2096
2097 // apply tag filter
2098 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2099 wrapper.klass_tag(),
2100 context->heap_filter())) {
2115 len,
2116 (void*)user_data());
2117 if (res & JVMTI_VISIT_ABORT) {
2118 return false;// referrer class tag
2119 }
2120 if (res & JVMTI_VISIT_OBJECTS) {
2121 check_for_visit(obj);
2122 }
2123 return true;
2124 }
2125
2126 // report a reference from a thread stack to an object
2127 inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
2128 jlong thread_tag,
2129 jlong tid,
2130 int depth,
2131 jmethodID method,
2132 jlocation bci,
2133 jint slot,
2134 oop obj) {
2135 AdvancedHeapWalkContext* context = advanced_context();
2136
2137 // check that callback is provider
2138 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2139 if (cb == NULL) {
2140 return check_for_visit(obj);
2141 }
2142
2143 // apply class filter
2144 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2145 return check_for_visit(obj);
2146 }
2147
2148 // setup the callback wrapper
2149 CallbackWrapper wrapper(tag_map(), obj);
2150
2151 // apply tag filter
2152 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2153 wrapper.klass_tag(),
2154 context->heap_filter())) {
2188 }
2189
2190 // This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
2191 // only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
2192 #define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \
2193 | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \
2194 | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
2195 | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
2196 | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \
2197 | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
2198
2199 // invoke the object reference callback to report a reference
2200 inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
2201 oop referrer,
2202 oop obj,
2203 jint index)
2204 {
2205 // field index is only valid field in reference_info
2206 static jvmtiHeapReferenceInfo reference_info = { 0 };
2207
2208 AdvancedHeapWalkContext* context = advanced_context();
2209
2210 // check that callback is provider
2211 jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
2212 if (cb == NULL) {
2213 return check_for_visit(obj);
2214 }
2215
2216 // apply class filter
2217 if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
2218 return check_for_visit(obj);
2219 }
2220
2221 // setup the callback wrapper
2222 TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
2223
2224 // apply tag filter
2225 if (is_filtered_by_heap_filter(wrapper.obj_tag(),
2226 wrapper.klass_tag(),
2227 context->heap_filter())) {
2241 wrapper.referrer_klass_tag(),
2242 wrapper.obj_size(),
2243 wrapper.obj_tag_p(),
2244 wrapper.referrer_tag_p(),
2245 len,
2246 (void*)user_data());
2247
2248 if (res & JVMTI_VISIT_ABORT) {
2249 return false;
2250 }
2251 if (res & JVMTI_VISIT_OBJECTS) {
2252 check_for_visit(obj);
2253 }
2254 return true;
2255 }
2256
2257 // report a "simple root"
2258 inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
2259 assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
2260 kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
2261
2262 if (is_basic_heap_walk()) {
2263 // map to old style root kind
2264 jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
2265 return invoke_basic_heap_root_callback(root_kind, obj);
2266 } else {
2267 assert(is_advanced_heap_walk(), "wrong heap walk type");
2268 return invoke_advanced_heap_root_callback(kind, obj);
2269 }
2270 }
2271
2272
2273 // invoke the primitive array values
2274 inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
2275 assert(obj->is_typeArray(), "not a primitive array");
2276
2277 AdvancedHeapWalkContext* context = advanced_context();
2278 assert(context->array_primitive_value_callback() != NULL, "no callback");
2279
2280 // apply class filter
2565 }
2566
2567 oop o = *obj_p;
2568 // ignore null
2569 if (o == NULL) {
2570 return;
2571 }
2572
2573 assert(Universe::heap()->is_in_reserved(o), "should be impossible");
2574
2575 jvmtiHeapReferenceKind kind = root_kind();
2576 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2577 // SystemDictionary::always_strong_oops_do reports the application
2578 // class loader as a root. We want this root to be reported as
2579 // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2580 if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
2581 kind = JVMTI_HEAP_REFERENCE_OTHER;
2582 }
2583 }
2584
2585 // invoke the callback
2586 _continue = CallbackInvoker::report_simple_root(kind, o);
2587
2588 }
2589 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2590 };
2591
2592 // A supporting closure used to process JNI locals
2593 class JNILocalRootsClosure : public OopClosure {
2594 private:
2595 jlong _thread_tag;
2596 jlong _tid;
2597 jint _depth;
2598 jmethodID _method;
2599 bool _continue;
2600 public:
2601 void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
2602 _thread_tag = thread_tag;
2603 _tid = tid;
2604 _depth = depth;
2605 _method = method;
2606 _continue = true;
2607 }
2608
2609 inline bool stopped() {
2610 return !_continue;
2611 }
2612
2613 void do_oop(oop* obj_p) {
2614 // iteration has terminated
2615 if (stopped()) {
2616 return;
2617 }
2618
2619 oop o = *obj_p;
2620 // ignore null
2621 if (o == NULL) {
2622 return;
2623 }
2624
2625 // invoke the callback
2626 _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
2627 }
2628 virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
2629 };
2630
2631
2632 // A VM operation to iterate over objects that are reachable from
2633 // a set of roots or an initial object.
2634 //
2635 // For VM_HeapWalkOperation the set of roots used is :-
2636 //
2637 // - All JNI global references
2638 // - All inflated monitors
2639 // - All classes loaded by the boot class loader (or all classes
2640 // in the event that class unloading is disabled)
2641 // - All java threads
2642 // - For each java thread then all locals and JNI local references
2643 // on the thread's execution stack
2644 // - All visible/explainable objects from Universes::oops_do
2932 return true;
2933 }
2934
2935 // an object references a class and its instance fields
2936 // (static fields are ignored here as we report these as
2937 // references from the class).
2938 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2939 // reference to the class
2940 if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
2941 return false;
2942 }
2943
2944 // iterate over instance fields
2945 ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2946 for (int i=0; i<field_map->field_count(); i++) {
2947 ClassFieldDescriptor* field = field_map->field_at(i);
2948 char type = field->field_type();
2949 if (!is_primitive_field_type(type)) {
2950 oop fld_o = o->obj_field(field->field_offset());
2951 // ignore any objects that aren't visible to profiler
2952 if (fld_o != NULL) {
2953 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
2954 "have references to Klass* anymore");
2955 int slot = field->field_index();
2956 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
2957 return false;
2958 }
2959 }
2960 } else {
2961 if (is_reporting_primitive_fields()) {
2962 // primitive instance field
2963 address addr = (address)o + field->field_offset();
2964 int slot = field->field_index();
2965 if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
2966 return false;
2967 }
2968 }
2969 }
2970 }
2971
2972 // if the object is a java.lang.String
|