< prev index next >

src/hotspot/share/prims/jvmtiTagMap.cpp

Print this page
rev 58143 : 8238633: JVMTI heap walk should consult GC for marking oops


  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


< prev index next >