< prev index next >

src/hotspot/share/prims/jvmtiTagMap.cpp

Print this page

  49 #include "prims/jvmtiImpl.hpp"
  50 #include "prims/jvmtiTagMap.hpp"
  51 #include "prims/jvmtiTagMapTable.hpp"
  52 #include "runtime/biasedLocking.hpp"
  53 #include "runtime/deoptimization.hpp"
  54 #include "runtime/frame.inline.hpp"
  55 #include "runtime/handles.inline.hpp"
  56 #include "runtime/interfaceSupport.inline.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/jniHandles.inline.hpp"
  59 #include "runtime/mutex.hpp"
  60 #include "runtime/mutexLocker.hpp"
  61 #include "runtime/reflectionUtils.hpp"
  62 #include "runtime/safepoint.hpp"
  63 #include "runtime/timerTrace.hpp"
  64 #include "runtime/thread.inline.hpp"
  65 #include "runtime/threadSMR.hpp"
  66 #include "runtime/vframe.hpp"
  67 #include "runtime/vmThread.hpp"
  68 #include "runtime/vmOperations.hpp"

  69 #include "utilities/macros.hpp"
  70 


  71 bool JvmtiTagMap::_has_object_free_events = false;
  72 
  73 // create a JvmtiTagMap
  74 JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) :
  75   _env(env),
  76   _lock(Mutex::nonleaf+1, "JvmtiTagMap_lock", Mutex::_allow_vm_block_flag,
  77         Mutex::_safepoint_check_never),
  78   _needs_rehashing(false),
  79   _needs_cleaning(false),
  80   _posting_events(false) {
  81 
  82   assert(JvmtiThreadState_lock->is_locked(), "sanity check");
  83   assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment");
  84 
  85   _hashmap = new JvmtiTagMapTable();
  86 
  87   // finally add us to the environment
  88   ((JvmtiEnvBase *)env)->release_set_tag_map(this);
  89 }
  90 

1336   }
1337 };
1338 
1339 // return the list of objects with the specified tags
1340 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
1341   jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1342 
1343   TagObjectCollector collector(env(), tags, count);
1344   {
1345     // iterate over all tagged objects
1346     MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag);
1347     // Can't post ObjectFree events here from a JavaThread, so this
1348     // will race with the gc_notification thread in the tiny
1349     // window where the object is not marked but hasn't been notified that
1350     // it is collected yet.
1351     entry_iterate(&collector);
1352   }
1353   return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
1354 }
1355 
1356 
1357 // ObjectMarker is used to support the marking objects when walking the
1358 // heap.
1359 //
1360 // This implementation uses the existing mark bits in an object for
1361 // marking. Objects that are marked must later have their headers restored.
1362 // As most objects are unlocked and don't have their identity hash computed
1363 // we don't have to save their headers. Instead we save the headers that
1364 // are "interesting". Later when the headers are restored this implementation
1365 // restores all headers to their initial value and then restores the few
1366 // objects that had interesting headers.
1367 //
1368 // Future work: This implementation currently uses growable arrays to save
1369 // the oop and header of interesting objects. As an optimization we could
1370 // use the same technique as the GC and make use of the unused area
1371 // between top() and end().
1372 //
1373 
1374 // An ObjectClosure used to restore the mark bits of an object
1375 class RestoreMarksClosure : public ObjectClosure {
1376  public:
1377   void do_object(oop o) {
1378     if (o != NULL) {
1379       markWord mark = o->mark();
1380       if (mark.is_marked()) {
1381         o->init_mark();
1382       }
1383     }
1384   }
1385 };
1386 
1387 // ObjectMarker provides the mark and visited functions
1388 class ObjectMarker : AllStatic {
1389  private:
1390   // saved headers
1391   static GrowableArray<oop>* _saved_oop_stack;
1392   static GrowableArray<markWord>* _saved_mark_stack;
1393   static bool _needs_reset;                  // do we need to reset mark bits?
1394 
1395  public:
1396   static void init();                       // initialize
1397   static void done();                       // clean-up
1398 
1399   static inline void mark(oop o);           // mark an object
1400   static inline bool visited(oop o);        // check if object has been visited
1401 
1402   static inline bool needs_reset()            { return _needs_reset; }
1403   static inline void set_needs_reset(bool v)  { _needs_reset = v; }
1404 };
1405 
1406 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1407 GrowableArray<markWord>* ObjectMarker::_saved_mark_stack = NULL;
1408 bool ObjectMarker::_needs_reset = true;  // need to reset mark bits by default
1409 
1410 // initialize ObjectMarker - prepares for object marking
1411 void ObjectMarker::init() {
1412   assert(Thread::current()->is_VM_thread(), "must be VMThread");
1413   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
1414 
1415   // prepare heap for iteration
1416   Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
1417 
1418   // create stacks for interesting headers
1419   _saved_mark_stack = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<markWord>(4000, mtServiceability);
1420   _saved_oop_stack = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<oop>(4000, mtServiceability);
1421 
1422   if (UseBiasedLocking) {
1423     BiasedLocking::preserve_marks();
1424   }
1425 }
1426 
1427 // Object marking is done so restore object headers
1428 void ObjectMarker::done() {
1429   // iterate over all objects and restore the mark bits to
1430   // their initial value
1431   RestoreMarksClosure blk;
1432   if (needs_reset()) {
1433     Universe::heap()->object_iterate(&blk);
1434   } else {
1435     // We don't need to reset mark bits on this call, but reset the
1436     // flag to the default for the next call.
1437     set_needs_reset(true);
1438   }
1439 
1440   // now restore the interesting headers
1441   for (int i = 0; i < _saved_oop_stack->length(); i++) {
1442     oop o = _saved_oop_stack->at(i);
1443     markWord mark = _saved_mark_stack->at(i);
1444     o->set_mark(mark);
1445   }
1446 
1447   if (UseBiasedLocking) {
1448     BiasedLocking::restore_marks();
1449   }
1450 
1451   // free the stacks
1452   delete _saved_oop_stack;
1453   delete _saved_mark_stack;
1454 }
1455 
1456 // mark an object
1457 inline void ObjectMarker::mark(oop o) {
1458   assert(Universe::heap()->is_in(o), "sanity check");
1459   assert(!o->mark().is_marked(), "should only mark an object once");
1460 
1461   // object's mark word
1462   markWord mark = o->mark();
1463 
1464   if (o->mark_must_be_preserved(mark)) {
1465     _saved_mark_stack->push(mark);
1466     _saved_oop_stack->push(o);
1467   }
1468 
1469   // mark the object
1470   o->set_mark(markWord::prototype().set_marked());
1471 }
1472 
1473 // return true if object is marked
1474 inline bool ObjectMarker::visited(oop o) {
1475   return o->mark().is_marked();
1476 }
1477 
1478 // Stack allocated class to help ensure that ObjectMarker is used
1479 // correctly. Constructor initializes ObjectMarker, destructor calls
1480 // ObjectMarker's done() function to restore object headers.
1481 class ObjectMarkerController : public StackObj {
1482  public:
1483   ObjectMarkerController() {
1484     ObjectMarker::init();
1485   }
1486   ~ObjectMarkerController() {
1487     ObjectMarker::done();
1488   }
1489 };
1490 
1491 
1492 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1493 // (not performance critical as only used for roots)
1494 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1495   switch (kind) {
1496     case JVMTI_HEAP_REFERENCE_JNI_GLOBAL:   return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1497     case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1498     case JVMTI_HEAP_REFERENCE_STACK_LOCAL:  return JVMTI_HEAP_ROOT_STACK_LOCAL;
1499     case JVMTI_HEAP_REFERENCE_JNI_LOCAL:    return JVMTI_HEAP_ROOT_JNI_LOCAL;
1500     case JVMTI_HEAP_REFERENCE_THREAD:       return JVMTI_HEAP_ROOT_THREAD;
1501     case JVMTI_HEAP_REFERENCE_OTHER:        return JVMTI_HEAP_ROOT_OTHER;
1502     default: ShouldNotReachHere();          return JVMTI_HEAP_ROOT_OTHER;
1503   }
1504 }
1505 
1506 // Base class for all heap walk contexts. The base class maintains a flag
1507 // to indicate if the context is valid or not.
1508 class HeapWalkContext {
1509  private:
1510   bool _valid;
1511  public:

1604   static bool is_advanced_heap_walk()        { return _heap_walk_type == advanced; }
1605 
1606   // context for basic style heap walk
1607   static BasicHeapWalkContext _basic_context;
1608   static BasicHeapWalkContext* basic_context() {
1609     assert(_basic_context.is_valid(), "invalid");
1610     return &_basic_context;
1611   }
1612 
1613   // context for advanced style heap walk
1614   static AdvancedHeapWalkContext _advanced_context;
1615   static AdvancedHeapWalkContext* advanced_context() {
1616     assert(_advanced_context.is_valid(), "invalid");
1617     return &_advanced_context;
1618   }
1619 
1620   // context needed for all heap walks
1621   static JvmtiTagMap* _tag_map;
1622   static const void* _user_data;
1623   static GrowableArray<oop>* _visit_stack;

1624 
1625   // accessors
1626   static JvmtiTagMap* tag_map()                        { return _tag_map; }
1627   static const void* user_data()                       { return _user_data; }
1628   static GrowableArray<oop>* visit_stack()             { return _visit_stack; }
1629 
1630   // if the object hasn't been visited then push it onto the visit stack
1631   // so that it will be visited later
1632   static inline bool check_for_visit(oop obj) {
1633     if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
1634     return true;
1635   }
1636 
1637   // invoke basic style callbacks
1638   static inline bool invoke_basic_heap_root_callback
1639     (jvmtiHeapRootKind root_kind, oop obj);
1640   static inline bool invoke_basic_stack_ref_callback
1641     (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1642      int slot, oop obj);
1643   static inline bool invoke_basic_object_reference_callback
1644     (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1645 
1646   // invoke advanced style callbacks
1647   static inline bool invoke_advanced_heap_root_callback
1648     (jvmtiHeapReferenceKind ref_kind, oop obj);
1649   static inline bool invoke_advanced_stack_ref_callback
1650     (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1651      jmethodID method, jlocation bci, jint slot, oop obj);
1652   static inline bool invoke_advanced_object_reference_callback
1653     (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1654 
1655   // used to report the value of primitive fields
1656   static inline bool report_primitive_field
1657     (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
1658 
1659  public:
1660   // initialize for basic mode
1661   static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1662                                              GrowableArray<oop>* visit_stack,
1663                                              const void* user_data,
1664                                              BasicHeapWalkContext context);

1665 
1666   // initialize for advanced mode
1667   static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1668                                                 GrowableArray<oop>* visit_stack,
1669                                                 const void* user_data,
1670                                                 AdvancedHeapWalkContext context);

1671 
1672    // functions to report roots
1673   static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
1674   static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
1675     jmethodID m, oop o);
1676   static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
1677     jmethodID method, jlocation bci, jint slot, oop o);
1678 
1679   // functions to report references
1680   static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
1681   static inline bool report_class_reference(oop referrer, oop referree);
1682   static inline bool report_class_loader_reference(oop referrer, oop referree);
1683   static inline bool report_signers_reference(oop referrer, oop referree);
1684   static inline bool report_protection_domain_reference(oop referrer, oop referree);
1685   static inline bool report_superclass_reference(oop referrer, oop referree);
1686   static inline bool report_interface_reference(oop referrer, oop referree);
1687   static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1688   static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1689   static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1690   static inline bool report_primitive_array_values(oop array);
1691   static inline bool report_string_value(oop str);
1692   static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1693   static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1694 };
1695 
1696 // statics
1697 int CallbackInvoker::_heap_walk_type;
1698 BasicHeapWalkContext CallbackInvoker::_basic_context;
1699 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1700 JvmtiTagMap* CallbackInvoker::_tag_map;
1701 const void* CallbackInvoker::_user_data;
1702 GrowableArray<oop>* CallbackInvoker::_visit_stack;

1703 
1704 // initialize for basic heap walk (IterateOverReachableObjects et al)
1705 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1706                                                      GrowableArray<oop>* visit_stack,
1707                                                      const void* user_data,
1708                                                      BasicHeapWalkContext context) {

1709   _tag_map = tag_map;
1710   _visit_stack = visit_stack;
1711   _user_data = user_data;
1712   _basic_context = context;
1713   _advanced_context.invalidate();       // will trigger assertion if used
1714   _heap_walk_type = basic;

1715 }
1716 
1717 // initialize for advanced heap walk (FollowReferences)
1718 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1719                                                         GrowableArray<oop>* visit_stack,
1720                                                         const void* user_data,
1721                                                         AdvancedHeapWalkContext context) {

1722   _tag_map = tag_map;
1723   _visit_stack = visit_stack;
1724   _user_data = user_data;
1725   _advanced_context = context;
1726   _basic_context.invalidate();      // will trigger assertion if used
1727   _heap_walk_type = advanced;

1728 }
1729 
1730 
1731 // invoke basic style heap root callback
1732 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1733   // if we heap roots should be reported
1734   jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
1735   if (cb == NULL) {
1736     return check_for_visit(obj);
1737   }
1738 
1739   CallbackWrapper wrapper(tag_map(), obj);
1740   jvmtiIterationControl control = (*cb)(root_kind,
1741                                         wrapper.klass_tag(),
1742                                         wrapper.obj_size(),
1743                                         wrapper.obj_tag_p(),
1744                                         (void*)user_data());
1745   // push root to visit stack when following references
1746   if (control == JVMTI_ITERATION_CONTINUE &&
1747       basic_context()->object_ref_callback() != NULL) {

2379 // - All JNI global references
2380 // - All inflated monitors
2381 // - All classes loaded by the boot class loader (or all classes
2382 //     in the event that class unloading is disabled)
2383 // - All java threads
2384 // - For each java thread then all locals and JNI local references
2385 //      on the thread's execution stack
2386 // - All visible/explainable objects from Universes::oops_do
2387 //
2388 class VM_HeapWalkOperation: public VM_Operation {
2389  private:
2390   enum {
2391     initial_visit_stack_size = 4000
2392   };
2393 
2394   bool _is_advanced_heap_walk;                      // indicates FollowReferences
2395   JvmtiTagMap* _tag_map;
2396   Handle _initial_object;
2397   GrowableArray<oop>* _visit_stack;                 // the visit stack
2398 


2399   // Dead object tags in JvmtiTagMap
2400   GrowableArray<jlong>* _dead_objects;
2401 
2402   bool _following_object_refs;                      // are we following object references
2403 
2404   bool _reporting_primitive_fields;                 // optional reporting
2405   bool _reporting_primitive_array_values;
2406   bool _reporting_string_values;
2407 
2408   GrowableArray<oop>* create_visit_stack() {
2409     return new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<oop>(initial_visit_stack_size, mtServiceability);
2410   }
2411 
2412   // accessors
2413   bool is_advanced_heap_walk() const               { return _is_advanced_heap_walk; }
2414   JvmtiTagMap* tag_map() const                     { return _tag_map; }
2415   Handle initial_object() const                    { return _initial_object; }
2416 
2417   bool is_following_references() const             { return _following_object_refs; }
2418 

2455   void doit();
2456 };
2457 
2458 
2459 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2460                                            Handle initial_object,
2461                                            BasicHeapWalkContext callbacks,
2462                                            const void* user_data,
2463                                            GrowableArray<jlong>* objects) {
2464   _is_advanced_heap_walk = false;
2465   _tag_map = tag_map;
2466   _initial_object = initial_object;
2467   _following_object_refs = (callbacks.object_ref_callback() != NULL);
2468   _reporting_primitive_fields = false;
2469   _reporting_primitive_array_values = false;
2470   _reporting_string_values = false;
2471   _visit_stack = create_visit_stack();
2472   _dead_objects = objects;
2473 
2474 
2475   CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2476 }
2477 
2478 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2479                                            Handle initial_object,
2480                                            AdvancedHeapWalkContext callbacks,
2481                                            const void* user_data,
2482                                            GrowableArray<jlong>* objects) {
2483   _is_advanced_heap_walk = true;
2484   _tag_map = tag_map;
2485   _initial_object = initial_object;
2486   _following_object_refs = true;
2487   _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
2488   _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
2489   _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
2490   _visit_stack = create_visit_stack();
2491   _dead_objects = objects;
2492 
2493   CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
2494 }
2495 
2496 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
2497   if (_following_object_refs) {
2498     assert(_visit_stack != NULL, "checking");
2499     delete _visit_stack;
2500     _visit_stack = NULL;
2501   }
2502 }
2503 
2504 // an array references its class and has a reference to
2505 // each element in the array
2506 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
2507   objArrayOop array = objArrayOop(o);
2508 
2509   // array reference to its class
2510   oop mirror = ObjArrayKlass::cast(array->klass())->java_mirror();
2511   if (!CallbackInvoker::report_class_reference(o, mirror)) {
2512     return false;
2513   }

2909       // collect its stack roots
2910       if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
2911                                                threadObj)) {
2912         return false;
2913       }
2914       if (!collect_stack_roots(thread, &blk)) {
2915         return false;
2916       }
2917     }
2918   }
2919   return true;
2920 }
2921 
2922 // visit an object
2923 // first mark the object as visited
2924 // second get all the outbound references from this object (in other words, all
2925 // the objects referenced by this object).
2926 //
2927 bool VM_HeapWalkOperation::visit(oop o) {
2928   // mark object as visited
2929   assert(!ObjectMarker::visited(o), "can't visit same object more than once");
2930   ObjectMarker::mark(o);
2931 
2932   // instance
2933   if (o->is_instance()) {
2934     if (o->klass() == vmClasses::Class_klass()) {
2935       if (!java_lang_Class::is_primitive(o)) {
2936         // a java.lang.Class
2937         return iterate_over_class(o);
2938       }
2939     } else {
2940       return iterate_over_object(o);
2941     }
2942   }
2943 
2944   // object array
2945   if (o->is_objArray()) {
2946     return iterate_over_array(o);
2947   }
2948 
2949   // type array
2950   if (o->is_typeArray()) {
2951     return iterate_over_type_array(o);
2952   }
2953 
2954   return true;
2955 }
2956 
2957 void VM_HeapWalkOperation::doit() {
2958   ResourceMark rm;
2959   ObjectMarkerController marker;
2960   ClassFieldMapCacheMark cm;
2961 
2962   JvmtiTagMap::check_hashmaps_for_heapwalk(_dead_objects);
2963 
2964   assert(visit_stack()->is_empty(), "visit stack must be empty");
2965 
2966   // the heap walk starts with an initial object or the heap roots
2967   if (initial_object().is_null()) {
2968     // If either collect_stack_roots() or collect_simple_roots()
2969     // returns false at this point, then there are no mark bits
2970     // to reset.
2971     ObjectMarker::set_needs_reset(false);
2972 
2973     // Calling collect_stack_roots() before collect_simple_roots()
2974     // can result in a big performance boost for an agent that is
2975     // focused on analyzing references in the thread stacks.
2976     if (!collect_stack_roots()) return;
2977 
2978     if (!collect_simple_roots()) return;
2979 
2980     // no early return so enable heap traversal to reset the mark bits
2981     ObjectMarker::set_needs_reset(true);
2982   } else {
2983     visit_stack()->push(initial_object()());
2984   }
2985 
2986   // object references required
2987   if (is_following_references()) {
2988 
2989     // visit each object until all reachable objects have been
2990     // visited or the callback asked to terminate the iteration.
2991     while (!visit_stack()->is_empty()) {
2992       oop o = visit_stack()->pop();
2993       if (!ObjectMarker::visited(o)) {
2994         if (!visit(o)) {
2995           break;
2996         }
2997       }
2998     }
2999   }
3000 }
3001 
3002 // iterate over all objects that are reachable from a set of roots
3003 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3004                                                  jvmtiStackReferenceCallback stack_ref_callback,
3005                                                  jvmtiObjectReferenceCallback object_ref_callback,
3006                                                  const void* user_data) {
3007   JavaThread* jt = JavaThread::current();
3008   EscapeBarrier eb(true, jt);
3009   eb.deoptimize_objects_all_threads();
3010   Arena dead_object_arena(mtServiceability);
3011   GrowableArray<jlong> dead_objects(&dead_object_arena, 10, 0, 0);
3012   {
3013     MutexLocker ml(Heap_lock);

  49 #include "prims/jvmtiImpl.hpp"
  50 #include "prims/jvmtiTagMap.hpp"
  51 #include "prims/jvmtiTagMapTable.hpp"
  52 #include "runtime/biasedLocking.hpp"
  53 #include "runtime/deoptimization.hpp"
  54 #include "runtime/frame.inline.hpp"
  55 #include "runtime/handles.inline.hpp"
  56 #include "runtime/interfaceSupport.inline.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/jniHandles.inline.hpp"
  59 #include "runtime/mutex.hpp"
  60 #include "runtime/mutexLocker.hpp"
  61 #include "runtime/reflectionUtils.hpp"
  62 #include "runtime/safepoint.hpp"
  63 #include "runtime/timerTrace.hpp"
  64 #include "runtime/thread.inline.hpp"
  65 #include "runtime/threadSMR.hpp"
  66 #include "runtime/vframe.hpp"
  67 #include "runtime/vmThread.hpp"
  68 #include "runtime/vmOperations.hpp"
  69 #include "utilities/objectBitSet.inline.hpp"
  70 #include "utilities/macros.hpp"
  71 
  72 typedef ObjectBitSet<mtServiceability> JVMTIBitSet;
  73 
  74 bool JvmtiTagMap::_has_object_free_events = false;
  75 
  76 // create a JvmtiTagMap
  77 JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) :
  78   _env(env),
  79   _lock(Mutex::nonleaf+1, "JvmtiTagMap_lock", Mutex::_allow_vm_block_flag,
  80         Mutex::_safepoint_check_never),
  81   _needs_rehashing(false),
  82   _needs_cleaning(false),
  83   _posting_events(false) {
  84 
  85   assert(JvmtiThreadState_lock->is_locked(), "sanity check");
  86   assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment");
  87 
  88   _hashmap = new JvmtiTagMapTable();
  89 
  90   // finally add us to the environment
  91   ((JvmtiEnvBase *)env)->release_set_tag_map(this);
  92 }
  93 

1339   }
1340 };
1341 
1342 // return the list of objects with the specified tags
1343 jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
1344   jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1345 
1346   TagObjectCollector collector(env(), tags, count);
1347   {
1348     // iterate over all tagged objects
1349     MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag);
1350     // Can't post ObjectFree events here from a JavaThread, so this
1351     // will race with the gc_notification thread in the tiny
1352     // window where the object is not marked but hasn't been notified that
1353     // it is collected yet.
1354     entry_iterate(&collector);
1355   }
1356   return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
1357 }
1358 








































































































































1359 // helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
1360 // (not performance critical as only used for roots)
1361 static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
1362   switch (kind) {
1363     case JVMTI_HEAP_REFERENCE_JNI_GLOBAL:   return JVMTI_HEAP_ROOT_JNI_GLOBAL;
1364     case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
1365     case JVMTI_HEAP_REFERENCE_STACK_LOCAL:  return JVMTI_HEAP_ROOT_STACK_LOCAL;
1366     case JVMTI_HEAP_REFERENCE_JNI_LOCAL:    return JVMTI_HEAP_ROOT_JNI_LOCAL;
1367     case JVMTI_HEAP_REFERENCE_THREAD:       return JVMTI_HEAP_ROOT_THREAD;
1368     case JVMTI_HEAP_REFERENCE_OTHER:        return JVMTI_HEAP_ROOT_OTHER;
1369     default: ShouldNotReachHere();          return JVMTI_HEAP_ROOT_OTHER;
1370   }
1371 }
1372 
1373 // Base class for all heap walk contexts. The base class maintains a flag
1374 // to indicate if the context is valid or not.
1375 class HeapWalkContext {
1376  private:
1377   bool _valid;
1378  public:

1471   static bool is_advanced_heap_walk()        { return _heap_walk_type == advanced; }
1472 
1473   // context for basic style heap walk
1474   static BasicHeapWalkContext _basic_context;
1475   static BasicHeapWalkContext* basic_context() {
1476     assert(_basic_context.is_valid(), "invalid");
1477     return &_basic_context;
1478   }
1479 
1480   // context for advanced style heap walk
1481   static AdvancedHeapWalkContext _advanced_context;
1482   static AdvancedHeapWalkContext* advanced_context() {
1483     assert(_advanced_context.is_valid(), "invalid");
1484     return &_advanced_context;
1485   }
1486 
1487   // context needed for all heap walks
1488   static JvmtiTagMap* _tag_map;
1489   static const void* _user_data;
1490   static GrowableArray<oop>* _visit_stack;
1491   static JVMTIBitSet* _bitset;
1492 
1493   // accessors
1494   static JvmtiTagMap* tag_map()                        { return _tag_map; }
1495   static const void* user_data()                       { return _user_data; }
1496   static GrowableArray<oop>* visit_stack()             { return _visit_stack; }
1497 
1498   // if the object hasn't been visited then push it onto the visit stack
1499   // so that it will be visited later
1500   static inline bool check_for_visit(oop obj) {
1501     if (!_bitset->is_marked(obj)) visit_stack()->push(obj);
1502     return true;
1503   }
1504 
1505   // invoke basic style callbacks
1506   static inline bool invoke_basic_heap_root_callback
1507     (jvmtiHeapRootKind root_kind, oop obj);
1508   static inline bool invoke_basic_stack_ref_callback
1509     (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
1510      int slot, oop obj);
1511   static inline bool invoke_basic_object_reference_callback
1512     (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
1513 
1514   // invoke advanced style callbacks
1515   static inline bool invoke_advanced_heap_root_callback
1516     (jvmtiHeapReferenceKind ref_kind, oop obj);
1517   static inline bool invoke_advanced_stack_ref_callback
1518     (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
1519      jmethodID method, jlocation bci, jint slot, oop obj);
1520   static inline bool invoke_advanced_object_reference_callback
1521     (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
1522 
1523   // used to report the value of primitive fields
1524   static inline bool report_primitive_field
1525     (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
1526 
1527  public:
1528   // initialize for basic mode
1529   static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1530                                              GrowableArray<oop>* visit_stack,
1531                                              const void* user_data,
1532                                              BasicHeapWalkContext context,
1533                                              JVMTIBitSet* bitset);
1534 
1535   // initialize for advanced mode
1536   static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1537                                                 GrowableArray<oop>* visit_stack,
1538                                                 const void* user_data,
1539                                                 AdvancedHeapWalkContext context,
1540                                                 JVMTIBitSet* bitset);
1541 
1542    // functions to report roots
1543   static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
1544   static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
1545     jmethodID m, oop o);
1546   static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
1547     jmethodID method, jlocation bci, jint slot, oop o);
1548 
1549   // functions to report references
1550   static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
1551   static inline bool report_class_reference(oop referrer, oop referree);
1552   static inline bool report_class_loader_reference(oop referrer, oop referree);
1553   static inline bool report_signers_reference(oop referrer, oop referree);
1554   static inline bool report_protection_domain_reference(oop referrer, oop referree);
1555   static inline bool report_superclass_reference(oop referrer, oop referree);
1556   static inline bool report_interface_reference(oop referrer, oop referree);
1557   static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
1558   static inline bool report_field_reference(oop referrer, oop referree, jint slot);
1559   static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
1560   static inline bool report_primitive_array_values(oop array);
1561   static inline bool report_string_value(oop str);
1562   static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
1563   static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
1564 };
1565 
1566 // statics
1567 int CallbackInvoker::_heap_walk_type;
1568 BasicHeapWalkContext CallbackInvoker::_basic_context;
1569 AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
1570 JvmtiTagMap* CallbackInvoker::_tag_map;
1571 const void* CallbackInvoker::_user_data;
1572 GrowableArray<oop>* CallbackInvoker::_visit_stack;
1573 JVMTIBitSet* CallbackInvoker::_bitset;
1574 
1575 // initialize for basic heap walk (IterateOverReachableObjects et al)
1576 void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
1577                                                      GrowableArray<oop>* visit_stack,
1578                                                      const void* user_data,
1579                                                      BasicHeapWalkContext context,
1580                                                      JVMTIBitSet* bitset) {
1581   _tag_map = tag_map;
1582   _visit_stack = visit_stack;
1583   _user_data = user_data;
1584   _basic_context = context;
1585   _advanced_context.invalidate();       // will trigger assertion if used
1586   _heap_walk_type = basic;
1587   _bitset = bitset;
1588 }
1589 
1590 // initialize for advanced heap walk (FollowReferences)
1591 void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
1592                                                         GrowableArray<oop>* visit_stack,
1593                                                         const void* user_data,
1594                                                         AdvancedHeapWalkContext context,
1595                                                         JVMTIBitSet* bitset) {
1596   _tag_map = tag_map;
1597   _visit_stack = visit_stack;
1598   _user_data = user_data;
1599   _advanced_context = context;
1600   _basic_context.invalidate();      // will trigger assertion if used
1601   _heap_walk_type = advanced;
1602   _bitset = bitset;
1603 }
1604 
1605 
1606 // invoke basic style heap root callback
1607 inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
1608   // if we heap roots should be reported
1609   jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
1610   if (cb == NULL) {
1611     return check_for_visit(obj);
1612   }
1613 
1614   CallbackWrapper wrapper(tag_map(), obj);
1615   jvmtiIterationControl control = (*cb)(root_kind,
1616                                         wrapper.klass_tag(),
1617                                         wrapper.obj_size(),
1618                                         wrapper.obj_tag_p(),
1619                                         (void*)user_data());
1620   // push root to visit stack when following references
1621   if (control == JVMTI_ITERATION_CONTINUE &&
1622       basic_context()->object_ref_callback() != NULL) {

2254 // - All JNI global references
2255 // - All inflated monitors
2256 // - All classes loaded by the boot class loader (or all classes
2257 //     in the event that class unloading is disabled)
2258 // - All java threads
2259 // - For each java thread then all locals and JNI local references
2260 //      on the thread's execution stack
2261 // - All visible/explainable objects from Universes::oops_do
2262 //
2263 class VM_HeapWalkOperation: public VM_Operation {
2264  private:
2265   enum {
2266     initial_visit_stack_size = 4000
2267   };
2268 
2269   bool _is_advanced_heap_walk;                      // indicates FollowReferences
2270   JvmtiTagMap* _tag_map;
2271   Handle _initial_object;
2272   GrowableArray<oop>* _visit_stack;                 // the visit stack
2273 
2274   JVMTIBitSet _bitset;
2275 
2276   // Dead object tags in JvmtiTagMap
2277   GrowableArray<jlong>* _dead_objects;
2278 
2279   bool _following_object_refs;                      // are we following object references
2280 
2281   bool _reporting_primitive_fields;                 // optional reporting
2282   bool _reporting_primitive_array_values;
2283   bool _reporting_string_values;
2284 
2285   GrowableArray<oop>* create_visit_stack() {
2286     return new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<oop>(initial_visit_stack_size, mtServiceability);
2287   }
2288 
2289   // accessors
2290   bool is_advanced_heap_walk() const               { return _is_advanced_heap_walk; }
2291   JvmtiTagMap* tag_map() const                     { return _tag_map; }
2292   Handle initial_object() const                    { return _initial_object; }
2293 
2294   bool is_following_references() const             { return _following_object_refs; }
2295 

2332   void doit();
2333 };
2334 
2335 
2336 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2337                                            Handle initial_object,
2338                                            BasicHeapWalkContext callbacks,
2339                                            const void* user_data,
2340                                            GrowableArray<jlong>* objects) {
2341   _is_advanced_heap_walk = false;
2342   _tag_map = tag_map;
2343   _initial_object = initial_object;
2344   _following_object_refs = (callbacks.object_ref_callback() != NULL);
2345   _reporting_primitive_fields = false;
2346   _reporting_primitive_array_values = false;
2347   _reporting_string_values = false;
2348   _visit_stack = create_visit_stack();
2349   _dead_objects = objects;
2350 
2351 
2352   CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks, &_bitset);
2353 }
2354 
2355 VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
2356                                            Handle initial_object,
2357                                            AdvancedHeapWalkContext callbacks,
2358                                            const void* user_data,
2359                                            GrowableArray<jlong>* objects) {
2360   _is_advanced_heap_walk = true;
2361   _tag_map = tag_map;
2362   _initial_object = initial_object;
2363   _following_object_refs = true;
2364   _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
2365   _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
2366   _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
2367   _visit_stack = create_visit_stack();
2368   _dead_objects = objects;
2369 
2370   CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks, &_bitset);
2371 }
2372 
2373 VM_HeapWalkOperation::~VM_HeapWalkOperation() {
2374   if (_following_object_refs) {
2375     assert(_visit_stack != NULL, "checking");
2376     delete _visit_stack;
2377     _visit_stack = NULL;
2378   }
2379 }
2380 
2381 // an array references its class and has a reference to
2382 // each element in the array
2383 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
2384   objArrayOop array = objArrayOop(o);
2385 
2386   // array reference to its class
2387   oop mirror = ObjArrayKlass::cast(array->klass())->java_mirror();
2388   if (!CallbackInvoker::report_class_reference(o, mirror)) {
2389     return false;
2390   }

2786       // collect its stack roots
2787       if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
2788                                                threadObj)) {
2789         return false;
2790       }
2791       if (!collect_stack_roots(thread, &blk)) {
2792         return false;
2793       }
2794     }
2795   }
2796   return true;
2797 }
2798 
2799 // visit an object
2800 // first mark the object as visited
2801 // second get all the outbound references from this object (in other words, all
2802 // the objects referenced by this object).
2803 //
2804 bool VM_HeapWalkOperation::visit(oop o) {
2805   // mark object as visited
2806   assert(!_bitset.is_marked(o), "can't visit same object more than once");
2807   _bitset.mark_obj(o);
2808 
2809   // instance
2810   if (o->is_instance()) {
2811     if (o->klass() == vmClasses::Class_klass()) {
2812       if (!java_lang_Class::is_primitive(o)) {
2813         // a java.lang.Class
2814         return iterate_over_class(o);
2815       }
2816     } else {
2817       return iterate_over_object(o);
2818     }
2819   }
2820 
2821   // object array
2822   if (o->is_objArray()) {
2823     return iterate_over_array(o);
2824   }
2825 
2826   // type array
2827   if (o->is_typeArray()) {
2828     return iterate_over_type_array(o);
2829   }
2830 
2831   return true;
2832 }
2833 
2834 void VM_HeapWalkOperation::doit() {
2835   ResourceMark rm;

2836   ClassFieldMapCacheMark cm;
2837 
2838   JvmtiTagMap::check_hashmaps_for_heapwalk(_dead_objects);
2839 
2840   assert(visit_stack()->is_empty(), "visit stack must be empty");
2841 
2842   // the heap walk starts with an initial object or the heap roots
2843   if (initial_object().is_null()) {






2844     // can result in a big performance boost for an agent that is
2845     // focused on analyzing references in the thread stacks.
2846     if (!collect_stack_roots()) return;
2847 
2848     if (!collect_simple_roots()) return;



2849   } else {
2850     visit_stack()->push(initial_object()());
2851   }
2852 
2853   // object references required
2854   if (is_following_references()) {
2855 
2856     // visit each object until all reachable objects have been
2857     // visited or the callback asked to terminate the iteration.
2858     while (!visit_stack()->is_empty()) {
2859       oop o = visit_stack()->pop();
2860       if (!_bitset.is_marked(o)) {
2861         if (!visit(o)) {
2862           break;
2863         }
2864       }
2865     }
2866   }
2867 }
2868 
2869 // iterate over all objects that are reachable from a set of roots
2870 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
2871                                                  jvmtiStackReferenceCallback stack_ref_callback,
2872                                                  jvmtiObjectReferenceCallback object_ref_callback,
2873                                                  const void* user_data) {
2874   JavaThread* jt = JavaThread::current();
2875   EscapeBarrier eb(true, jt);
2876   eb.deoptimize_objects_all_threads();
2877   Arena dead_object_arena(mtServiceability);
2878   GrowableArray<jlong> dead_objects(&dead_object_arena, 10, 0, 0);
2879   {
2880     MutexLocker ml(Heap_lock);
< prev index next >