< prev index next >

src/hotspot/share/prims/jvmtiTagMap.cpp

Print this page




  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


< prev index next >