< prev index next >

src/share/vm/prims/jvmtiTagMap.cpp

Print this page




 765   char field_type()  const  { return _field_type; }
 766   int field_offset() const  { return _field_offset; }
 767 };
 768 
 769 class ClassFieldMap: public CHeapObj<mtInternal> {
 770  private:
 771   enum {
 772     initial_field_count = 5
 773   };
 774 
 775   // list of field descriptors
 776   GrowableArray<ClassFieldDescriptor*>* _fields;
 777 
 778   // constructor
 779   ClassFieldMap();
 780 
 781   // add a field
 782   void add(int index, char type, int offset);
 783 
 784   // returns the field count for the given class
 785   static int compute_field_count(instanceKlassHandle ikh);
 786 
 787  public:
 788   ~ClassFieldMap();
 789 
 790   // access
 791   int field_count()                     { return _fields->length(); }
 792   ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
 793 
 794   // functions to create maps of static or instance fields
 795   static ClassFieldMap* create_map_of_static_fields(Klass* k);
 796   static ClassFieldMap* create_map_of_instance_fields(oop obj);
 797 };
 798 
 799 ClassFieldMap::ClassFieldMap() {
 800   _fields = new (ResourceObj::C_HEAP, mtInternal)
 801     GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
 802 }
 803 
 804 ClassFieldMap::~ClassFieldMap() {
 805   for (int i=0; i<_fields->length(); i++) {
 806     delete _fields->at(i);
 807   }
 808   delete _fields;
 809 }
 810 
 811 void ClassFieldMap::add(int index, char type, int offset) {
 812   ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset);
 813   _fields->append(field);
 814 }
 815 
 816 // Returns a heap allocated ClassFieldMap to describe the static fields
 817 // of the given class.
 818 //
 819 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) {
 820   HandleMark hm;
 821   instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
 822 
 823   // create the field map
 824   ClassFieldMap* field_map = new ClassFieldMap();
 825 
 826   FilteredFieldStream f(ikh, false, false);
 827   int max_field_index = f.field_count()-1;
 828 
 829   int index = 0;
 830   for (FilteredFieldStream fld(ikh, true, true); !fld.eos(); fld.next(), index++) {
 831     // ignore instance fields
 832     if (!fld.access_flags().is_static()) {
 833       continue;
 834     }
 835     field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
 836   }
 837   return field_map;
 838 }
 839 
 840 // Returns a heap allocated ClassFieldMap to describe the instance fields
 841 // of the given class. All instance fields are included (this means public
 842 // and private fields declared in superclasses and superinterfaces too).
 843 //
 844 ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) {
 845   HandleMark hm;
 846   instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), obj->klass());
 847 
 848   // create the field map
 849   ClassFieldMap* field_map = new ClassFieldMap();
 850 
 851   FilteredFieldStream f(ikh, false, false);
 852 
 853   int max_field_index = f.field_count()-1;
 854 
 855   int index = 0;
 856   for (FilteredFieldStream fld(ikh, false, false); !fld.eos(); fld.next(), index++) {
 857     // ignore static fields
 858     if (fld.access_flags().is_static()) {
 859       continue;
 860     }
 861     field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
 862   }
 863 
 864   return field_map;
 865 }
 866 
 867 // Helper class used to cache a ClassFileMap for the instance fields of
 868 // a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during
 869 // heap iteration and avoid creating a field map for each object in the heap
 870 // (only need to create the map when the first instance of a class is encountered).
 871 //
 872 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> {
 873  private:
 874    enum {
 875      initial_class_count = 200
 876    };


 990                                               int heap_filter) {
 991   // apply the heap filter
 992   if (obj_tag != 0) {
 993     // filter out tagged objects
 994     if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true;
 995   } else {
 996     // filter out untagged objects
 997     if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true;
 998   }
 999   if (klass_tag != 0) {
1000     // filter out objects with tagged classes
1001     if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true;
1002   } else {
1003     // filter out objects with untagged classes.
1004     if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true;
1005   }
1006   return false;
1007 }
1008 
1009 // helper function to indicate if an object is filtered by a klass filter
1010 static inline bool is_filtered_by_klass_filter(oop obj, KlassHandle klass_filter) {
1011   if (!klass_filter.is_null()) {
1012     if (obj->klass() != klass_filter()) {
1013       return true;
1014     }
1015   }
1016   return false;
1017 }
1018 
1019 // helper function to tell if a field is a primitive field or not
1020 static inline bool is_primitive_field_type(char type) {
1021   return (type != 'L' && type != '[');
1022 }
1023 
1024 // helper function to copy the value from location addr to jvalue.
1025 static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) {
1026   switch (value_type) {
1027     case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; }
1028     case JVMTI_PRIMITIVE_TYPE_BYTE    : { v->b = *(jbyte*)addr;    break; }
1029     case JVMTI_PRIMITIVE_TYPE_CHAR    : { v->c = *(jchar*)addr;    break; }
1030     case JVMTI_PRIMITIVE_TYPE_SHORT   : { v->s = *(jshort*)addr;   break; }
1031     case JVMTI_PRIMITIVE_TYPE_INT     : { v->i = *(jint*)addr;     break; }
1032     case JVMTI_PRIMITIVE_TYPE_LONG    : { v->j = *(jlong*)addr;    break; }


1254     // JVMTI's IterateOverHeap will crash.
1255     if (VerifyBeforeIteration) {
1256       Universe::verify();
1257     }
1258 
1259     // do the iteration
1260     // If this operation encounters a bad object when using CMS,
1261     // consider using safe_object_iterate() which avoids perm gen
1262     // objects that may contain bad references.
1263     Universe::heap()->object_iterate(_blk);
1264   }
1265 
1266 };
1267 
1268 
1269 // An ObjectClosure used to support the deprecated IterateOverHeap and
1270 // IterateOverInstancesOfClass functions
1271 class IterateOverHeapObjectClosure: public ObjectClosure {
1272  private:
1273   JvmtiTagMap* _tag_map;
1274   KlassHandle _klass;
1275   jvmtiHeapObjectFilter _object_filter;
1276   jvmtiHeapObjectCallback _heap_object_callback;
1277   const void* _user_data;
1278 
1279   // accessors
1280   JvmtiTagMap* tag_map() const                    { return _tag_map; }
1281   jvmtiHeapObjectFilter object_filter() const     { return _object_filter; }
1282   jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; }
1283   KlassHandle klass() const                       { return _klass; }
1284   const void* user_data() const                   { return _user_data; }
1285 
1286   // indicates if iteration has been aborted
1287   bool _iteration_aborted;
1288   bool is_iteration_aborted() const               { return _iteration_aborted; }
1289   void set_iteration_aborted(bool aborted)        { _iteration_aborted = aborted; }
1290 
1291  public:
1292   IterateOverHeapObjectClosure(JvmtiTagMap* tag_map,
1293                                KlassHandle klass,
1294                                jvmtiHeapObjectFilter object_filter,
1295                                jvmtiHeapObjectCallback heap_object_callback,
1296                                const void* user_data) :
1297     _tag_map(tag_map),
1298     _klass(klass),
1299     _object_filter(object_filter),
1300     _heap_object_callback(heap_object_callback),
1301     _user_data(user_data),
1302     _iteration_aborted(false)
1303   {
1304   }
1305 
1306   void do_object(oop o);
1307 };
1308 
1309 // invoked for each object in the heap
1310 void IterateOverHeapObjectClosure::do_object(oop o) {
1311   // check if iteration has been halted
1312   if (is_iteration_aborted()) return;
1313 
1314   // ignore any objects that aren't visible to profiler
1315   if (!ServiceUtil::visible_oop(o)) return;
1316 
1317   // instanceof check when filtering by klass
1318   if (!klass().is_null() && !o->is_a(klass()())) {
1319     return;
1320   }
1321   // prepare for the calllback
1322   CallbackWrapper wrapper(tag_map(), o);
1323 
1324   // if the object is tagged and we're only interested in untagged objects
1325   // then don't invoke the callback. Similiarly, if the object is untagged
1326   // and we're only interested in tagged objects we skip the callback.
1327   if (wrapper.obj_tag() != 0) {
1328     if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
1329   } else {
1330     if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
1331   }
1332 
1333   // invoke the agent's callback
1334   jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
1335                                                        wrapper.obj_size(),
1336                                                        wrapper.obj_tag_p(),
1337                                                        (void*)user_data());
1338   if (control == JVMTI_ITERATION_ABORT) {
1339     set_iteration_aborted(true);
1340   }
1341 }
1342 
1343 // An ObjectClosure used to support the IterateThroughHeap function
1344 class IterateThroughHeapObjectClosure: public ObjectClosure {
1345  private:
1346   JvmtiTagMap* _tag_map;
1347   KlassHandle _klass;
1348   int _heap_filter;
1349   const jvmtiHeapCallbacks* _callbacks;
1350   const void* _user_data;
1351 
1352   // accessor functions
1353   JvmtiTagMap* tag_map() const                     { return _tag_map; }
1354   int heap_filter() const                          { return _heap_filter; }
1355   const jvmtiHeapCallbacks* callbacks() const      { return _callbacks; }
1356   KlassHandle klass() const                        { return _klass; }
1357   const void* user_data() const                    { return _user_data; }
1358 
1359   // indicates if the iteration has been aborted
1360   bool _iteration_aborted;
1361   bool is_iteration_aborted() const                { return _iteration_aborted; }
1362 
1363   // used to check the visit control flags. If the abort flag is set
1364   // then we set the iteration aborted flag so that the iteration completes
1365   // without processing any further objects
1366   bool check_flags_for_abort(jint flags) {
1367     bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0;
1368     if (is_abort) {
1369       _iteration_aborted = true;
1370     }
1371     return is_abort;
1372   }
1373 
1374  public:
1375   IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map,
1376                                   KlassHandle klass,
1377                                   int heap_filter,
1378                                   const jvmtiHeapCallbacks* heap_callbacks,
1379                                   const void* user_data) :
1380     _tag_map(tag_map),
1381     _klass(klass),
1382     _heap_filter(heap_filter),
1383     _callbacks(heap_callbacks),
1384     _user_data(user_data),
1385     _iteration_aborted(false)
1386   {
1387   }
1388 
1389   void do_object(oop o);
1390 };
1391 
1392 // invoked for each object in the heap
1393 void IterateThroughHeapObjectClosure::do_object(oop obj) {
1394   // check if iteration has been halted
1395   if (is_iteration_aborted()) return;
1396 


1452                 (void*)user_data() );
1453     if (check_flags_for_abort(res)) return;
1454   }
1455 
1456   // array callback
1457   if (is_array &&
1458       callbacks()->array_primitive_value_callback != NULL &&
1459       obj->is_typeArray()) {
1460     jint res = invoke_array_primitive_value_callback(
1461                callbacks()->array_primitive_value_callback,
1462                &wrapper,
1463                obj,
1464                (void*)user_data() );
1465     if (check_flags_for_abort(res)) return;
1466   }
1467 };
1468 
1469 
1470 // Deprecated function to iterate over all objects in the heap
1471 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
1472                                     KlassHandle klass,
1473                                     jvmtiHeapObjectCallback heap_object_callback,
1474                                     const void* user_data)
1475 {
1476   MutexLocker ml(Heap_lock);
1477   IterateOverHeapObjectClosure blk(this,
1478                                    klass,
1479                                    object_filter,
1480                                    heap_object_callback,
1481                                    user_data);
1482   VM_HeapIterateOperation op(&blk);
1483   VMThread::execute(&op);
1484 }
1485 
1486 
1487 // Iterates over all objects in the heap
1488 void JvmtiTagMap::iterate_through_heap(jint heap_filter,
1489                                        KlassHandle klass,
1490                                        const jvmtiHeapCallbacks* callbacks,
1491                                        const void* user_data)
1492 {
1493   MutexLocker ml(Heap_lock);
1494   IterateThroughHeapObjectClosure blk(this,
1495                                       klass,
1496                                       heap_filter,
1497                                       callbacks,
1498                                       user_data);
1499   VM_HeapIterateOperation op(&blk);
1500   VMThread::execute(&op);
1501 }
1502 
1503 // support class for get_objects_with_tags
1504 
1505 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
1506  private:
1507   JvmtiEnv* _env;
1508   jlong* _tags;
1509   jint _tag_count;


1780     _last_referrer(NULL),
1781     _last_referrer_tag(0) {
1782   }
1783 
1784   // accessors
1785   jvmtiHeapRootCallback heap_root_callback() const         { return _heap_root_callback; }
1786   jvmtiStackReferenceCallback stack_ref_callback() const   { return _stack_ref_callback; }
1787   jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback;  }
1788 
1789   oop last_referrer() const               { return _last_referrer; }
1790   void set_last_referrer(oop referrer)    { _last_referrer = referrer; }
1791   jlong last_referrer_tag() const         { return _last_referrer_tag; }
1792   void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
1793 };
1794 
1795 // The advanced heap walk context for the FollowReferences functions.
1796 // The context is the callbacks, and the fields used for filtering.
1797 class AdvancedHeapWalkContext: public HeapWalkContext {
1798  private:
1799   jint _heap_filter;
1800   KlassHandle _klass_filter;
1801   const jvmtiHeapCallbacks* _heap_callbacks;
1802 
1803  public:
1804   AdvancedHeapWalkContext() : HeapWalkContext(false) { }
1805 
1806   AdvancedHeapWalkContext(jint heap_filter,
1807                            KlassHandle klass_filter,
1808                            const jvmtiHeapCallbacks* heap_callbacks) :
1809     HeapWalkContext(true),
1810     _heap_filter(heap_filter),
1811     _klass_filter(klass_filter),
1812     _heap_callbacks(heap_callbacks) {
1813   }
1814 
1815   // accessors
1816   jint heap_filter() const         { return _heap_filter; }
1817   KlassHandle klass_filter() const { return _klass_filter; }
1818 
1819   const jvmtiHeapReferenceCallback heap_reference_callback() const {
1820     return _heap_callbacks->heap_reference_callback;
1821   };
1822   const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1823     return _heap_callbacks->primitive_field_callback;
1824   }
1825   const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1826     return _heap_callbacks->array_primitive_value_callback;
1827   }
1828   const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1829     return _heap_callbacks->string_primitive_value_callback;
1830   }
1831 };
1832 
1833 // The CallbackInvoker is a class with static functions that the heap walk can call
1834 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1835 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1836 // mode is for the newer FollowReferences function which supports a lot of
1837 // additional callbacks.


3270   BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3271   VM_HeapWalkOperation op(this, Handle(), context, user_data);
3272   VMThread::execute(&op);
3273 }
3274 
3275 // iterate over all objects that are reachable from a given object
3276 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3277                                                              jvmtiObjectReferenceCallback object_ref_callback,
3278                                                              const void* user_data) {
3279   oop obj = JNIHandles::resolve(object);
3280   Handle initial_object(Thread::current(), obj);
3281 
3282   MutexLocker ml(Heap_lock);
3283   BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3284   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3285   VMThread::execute(&op);
3286 }
3287 
3288 // follow references from an initial object or the GC roots
3289 void JvmtiTagMap::follow_references(jint heap_filter,
3290                                     KlassHandle klass,
3291                                     jobject object,
3292                                     const jvmtiHeapCallbacks* callbacks,
3293                                     const void* user_data)
3294 {
3295   oop obj = JNIHandles::resolve(object);
3296   Handle initial_object(Thread::current(), obj);
3297 
3298   MutexLocker ml(Heap_lock);
3299   AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3300   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3301   VMThread::execute(&op);
3302 }
3303 
3304 
3305 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3306   // No locks during VM bring-up (0 threads) and no safepoints after main
3307   // thread creation and before VMThread creation (1 thread); initial GC
3308   // verification can happen in that window which gets to here.
3309   assert(Threads::number_of_threads() <= 1 ||
3310          SafepointSynchronize::is_at_safepoint(),




 765   char field_type()  const  { return _field_type; }
 766   int field_offset() const  { return _field_offset; }
 767 };
 768 
 769 class ClassFieldMap: public CHeapObj<mtInternal> {
 770  private:
 771   enum {
 772     initial_field_count = 5
 773   };
 774 
 775   // list of field descriptors
 776   GrowableArray<ClassFieldDescriptor*>* _fields;
 777 
 778   // constructor
 779   ClassFieldMap();
 780 
 781   // add a field
 782   void add(int index, char type, int offset);
 783 
 784   // returns the field count for the given class
 785   static int compute_field_count(InstanceKlass* ik);
 786 
 787  public:
 788   ~ClassFieldMap();
 789 
 790   // access
 791   int field_count()                     { return _fields->length(); }
 792   ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
 793 
 794   // functions to create maps of static or instance fields
 795   static ClassFieldMap* create_map_of_static_fields(Klass* k);
 796   static ClassFieldMap* create_map_of_instance_fields(oop obj);
 797 };
 798 
 799 ClassFieldMap::ClassFieldMap() {
 800   _fields = new (ResourceObj::C_HEAP, mtInternal)
 801     GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
 802 }
 803 
 804 ClassFieldMap::~ClassFieldMap() {
 805   for (int i=0; i<_fields->length(); i++) {
 806     delete _fields->at(i);
 807   }
 808   delete _fields;
 809 }
 810 
 811 void ClassFieldMap::add(int index, char type, int offset) {
 812   ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset);
 813   _fields->append(field);
 814 }
 815 
 816 // Returns a heap allocated ClassFieldMap to describe the static fields
 817 // of the given class.
 818 //
 819 ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) {
 820   HandleMark hm;
 821   InstanceKlass* ik = InstanceKlass::cast(k);
 822 
 823   // create the field map
 824   ClassFieldMap* field_map = new ClassFieldMap();
 825 
 826   FilteredFieldStream f(ik, false, false);
 827   int max_field_index = f.field_count()-1;
 828 
 829   int index = 0;
 830   for (FilteredFieldStream fld(ik, true, true); !fld.eos(); fld.next(), index++) {
 831     // ignore instance fields
 832     if (!fld.access_flags().is_static()) {
 833       continue;
 834     }
 835     field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
 836   }
 837   return field_map;
 838 }
 839 
 840 // Returns a heap allocated ClassFieldMap to describe the instance fields
 841 // of the given class. All instance fields are included (this means public
 842 // and private fields declared in superclasses and superinterfaces too).
 843 //
 844 ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) {
 845   HandleMark hm;
 846   InstanceKlass* ik = InstanceKlass::cast(obj->klass());
 847 
 848   // create the field map
 849   ClassFieldMap* field_map = new ClassFieldMap();
 850 
 851   FilteredFieldStream f(ik, false, false);
 852 
 853   int max_field_index = f.field_count()-1;
 854 
 855   int index = 0;
 856   for (FilteredFieldStream fld(ik, false, false); !fld.eos(); fld.next(), index++) {
 857     // ignore static fields
 858     if (fld.access_flags().is_static()) {
 859       continue;
 860     }
 861     field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
 862   }
 863 
 864   return field_map;
 865 }
 866 
 867 // Helper class used to cache a ClassFileMap for the instance fields of
 868 // a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during
 869 // heap iteration and avoid creating a field map for each object in the heap
 870 // (only need to create the map when the first instance of a class is encountered).
 871 //
 872 class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> {
 873  private:
 874    enum {
 875      initial_class_count = 200
 876    };


 990                                               int heap_filter) {
 991   // apply the heap filter
 992   if (obj_tag != 0) {
 993     // filter out tagged objects
 994     if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true;
 995   } else {
 996     // filter out untagged objects
 997     if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true;
 998   }
 999   if (klass_tag != 0) {
1000     // filter out objects with tagged classes
1001     if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true;
1002   } else {
1003     // filter out objects with untagged classes.
1004     if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true;
1005   }
1006   return false;
1007 }
1008 
1009 // helper function to indicate if an object is filtered by a klass filter
1010 static inline bool is_filtered_by_klass_filter(oop obj, Klass* klass_filter) {
1011   if (klass_filter != NULL) {
1012     if (obj->klass() != klass_filter) {
1013       return true;
1014     }
1015   }
1016   return false;
1017 }
1018 
1019 // helper function to tell if a field is a primitive field or not
1020 static inline bool is_primitive_field_type(char type) {
1021   return (type != 'L' && type != '[');
1022 }
1023 
1024 // helper function to copy the value from location addr to jvalue.
1025 static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) {
1026   switch (value_type) {
1027     case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; }
1028     case JVMTI_PRIMITIVE_TYPE_BYTE    : { v->b = *(jbyte*)addr;    break; }
1029     case JVMTI_PRIMITIVE_TYPE_CHAR    : { v->c = *(jchar*)addr;    break; }
1030     case JVMTI_PRIMITIVE_TYPE_SHORT   : { v->s = *(jshort*)addr;   break; }
1031     case JVMTI_PRIMITIVE_TYPE_INT     : { v->i = *(jint*)addr;     break; }
1032     case JVMTI_PRIMITIVE_TYPE_LONG    : { v->j = *(jlong*)addr;    break; }


1254     // JVMTI's IterateOverHeap will crash.
1255     if (VerifyBeforeIteration) {
1256       Universe::verify();
1257     }
1258 
1259     // do the iteration
1260     // If this operation encounters a bad object when using CMS,
1261     // consider using safe_object_iterate() which avoids perm gen
1262     // objects that may contain bad references.
1263     Universe::heap()->object_iterate(_blk);
1264   }
1265 
1266 };
1267 
1268 
1269 // An ObjectClosure used to support the deprecated IterateOverHeap and
1270 // IterateOverInstancesOfClass functions
1271 class IterateOverHeapObjectClosure: public ObjectClosure {
1272  private:
1273   JvmtiTagMap* _tag_map;
1274   Klass* _klass;
1275   jvmtiHeapObjectFilter _object_filter;
1276   jvmtiHeapObjectCallback _heap_object_callback;
1277   const void* _user_data;
1278 
1279   // accessors
1280   JvmtiTagMap* tag_map() const                    { return _tag_map; }
1281   jvmtiHeapObjectFilter object_filter() const     { return _object_filter; }
1282   jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; }
1283   Klass* klass() const                            { return _klass; }
1284   const void* user_data() const                   { return _user_data; }
1285 
1286   // indicates if iteration has been aborted
1287   bool _iteration_aborted;
1288   bool is_iteration_aborted() const               { return _iteration_aborted; }
1289   void set_iteration_aborted(bool aborted)        { _iteration_aborted = aborted; }
1290 
1291  public:
1292   IterateOverHeapObjectClosure(JvmtiTagMap* tag_map,
1293                                Klass* klass,
1294                                jvmtiHeapObjectFilter object_filter,
1295                                jvmtiHeapObjectCallback heap_object_callback,
1296                                const void* user_data) :
1297     _tag_map(tag_map),
1298     _klass(klass),
1299     _object_filter(object_filter),
1300     _heap_object_callback(heap_object_callback),
1301     _user_data(user_data),
1302     _iteration_aborted(false)
1303   {
1304   }
1305 
1306   void do_object(oop o);
1307 };
1308 
1309 // invoked for each object in the heap
1310 void IterateOverHeapObjectClosure::do_object(oop o) {
1311   // check if iteration has been halted
1312   if (is_iteration_aborted()) return;
1313 
1314   // ignore any objects that aren't visible to profiler
1315   if (!ServiceUtil::visible_oop(o)) return;
1316 
1317   // instanceof check when filtering by klass
1318   if (klass() != NULL && !o->is_a(klass())) {
1319     return;
1320   }
1321   // prepare for the calllback
1322   CallbackWrapper wrapper(tag_map(), o);
1323 
1324   // if the object is tagged and we're only interested in untagged objects
1325   // then don't invoke the callback. Similiarly, if the object is untagged
1326   // and we're only interested in tagged objects we skip the callback.
1327   if (wrapper.obj_tag() != 0) {
1328     if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
1329   } else {
1330     if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
1331   }
1332 
1333   // invoke the agent's callback
1334   jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
1335                                                        wrapper.obj_size(),
1336                                                        wrapper.obj_tag_p(),
1337                                                        (void*)user_data());
1338   if (control == JVMTI_ITERATION_ABORT) {
1339     set_iteration_aborted(true);
1340   }
1341 }
1342 
1343 // An ObjectClosure used to support the IterateThroughHeap function
1344 class IterateThroughHeapObjectClosure: public ObjectClosure {
1345  private:
1346   JvmtiTagMap* _tag_map;
1347   Klass* _klass;
1348   int _heap_filter;
1349   const jvmtiHeapCallbacks* _callbacks;
1350   const void* _user_data;
1351 
1352   // accessor functions
1353   JvmtiTagMap* tag_map() const                     { return _tag_map; }
1354   int heap_filter() const                          { return _heap_filter; }
1355   const jvmtiHeapCallbacks* callbacks() const      { return _callbacks; }
1356   Klass* klass() const                             { return _klass; }
1357   const void* user_data() const                    { return _user_data; }
1358 
1359   // indicates if the iteration has been aborted
1360   bool _iteration_aborted;
1361   bool is_iteration_aborted() const                { return _iteration_aborted; }
1362 
1363   // used to check the visit control flags. If the abort flag is set
1364   // then we set the iteration aborted flag so that the iteration completes
1365   // without processing any further objects
1366   bool check_flags_for_abort(jint flags) {
1367     bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0;
1368     if (is_abort) {
1369       _iteration_aborted = true;
1370     }
1371     return is_abort;
1372   }
1373 
1374  public:
1375   IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map,
1376                                   Klass* klass,
1377                                   int heap_filter,
1378                                   const jvmtiHeapCallbacks* heap_callbacks,
1379                                   const void* user_data) :
1380     _tag_map(tag_map),
1381     _klass(klass),
1382     _heap_filter(heap_filter),
1383     _callbacks(heap_callbacks),
1384     _user_data(user_data),
1385     _iteration_aborted(false)
1386   {
1387   }
1388 
1389   void do_object(oop o);
1390 };
1391 
1392 // invoked for each object in the heap
1393 void IterateThroughHeapObjectClosure::do_object(oop obj) {
1394   // check if iteration has been halted
1395   if (is_iteration_aborted()) return;
1396 


1452                 (void*)user_data() );
1453     if (check_flags_for_abort(res)) return;
1454   }
1455 
1456   // array callback
1457   if (is_array &&
1458       callbacks()->array_primitive_value_callback != NULL &&
1459       obj->is_typeArray()) {
1460     jint res = invoke_array_primitive_value_callback(
1461                callbacks()->array_primitive_value_callback,
1462                &wrapper,
1463                obj,
1464                (void*)user_data() );
1465     if (check_flags_for_abort(res)) return;
1466   }
1467 };
1468 
1469 
1470 // Deprecated function to iterate over all objects in the heap
1471 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
1472                                     Klass* klass,
1473                                     jvmtiHeapObjectCallback heap_object_callback,
1474                                     const void* user_data)
1475 {
1476   MutexLocker ml(Heap_lock);
1477   IterateOverHeapObjectClosure blk(this,
1478                                    klass,
1479                                    object_filter,
1480                                    heap_object_callback,
1481                                    user_data);
1482   VM_HeapIterateOperation op(&blk);
1483   VMThread::execute(&op);
1484 }
1485 
1486 
1487 // Iterates over all objects in the heap
1488 void JvmtiTagMap::iterate_through_heap(jint heap_filter,
1489                                        Klass* klass,
1490                                        const jvmtiHeapCallbacks* callbacks,
1491                                        const void* user_data)
1492 {
1493   MutexLocker ml(Heap_lock);
1494   IterateThroughHeapObjectClosure blk(this,
1495                                       klass,
1496                                       heap_filter,
1497                                       callbacks,
1498                                       user_data);
1499   VM_HeapIterateOperation op(&blk);
1500   VMThread::execute(&op);
1501 }
1502 
1503 // support class for get_objects_with_tags
1504 
1505 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
1506  private:
1507   JvmtiEnv* _env;
1508   jlong* _tags;
1509   jint _tag_count;


1780     _last_referrer(NULL),
1781     _last_referrer_tag(0) {
1782   }
1783 
1784   // accessors
1785   jvmtiHeapRootCallback heap_root_callback() const         { return _heap_root_callback; }
1786   jvmtiStackReferenceCallback stack_ref_callback() const   { return _stack_ref_callback; }
1787   jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback;  }
1788 
1789   oop last_referrer() const               { return _last_referrer; }
1790   void set_last_referrer(oop referrer)    { _last_referrer = referrer; }
1791   jlong last_referrer_tag() const         { return _last_referrer_tag; }
1792   void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
1793 };
1794 
1795 // The advanced heap walk context for the FollowReferences functions.
1796 // The context is the callbacks, and the fields used for filtering.
1797 class AdvancedHeapWalkContext: public HeapWalkContext {
1798  private:
1799   jint _heap_filter;
1800   Klass* _klass_filter;
1801   const jvmtiHeapCallbacks* _heap_callbacks;
1802 
1803  public:
1804   AdvancedHeapWalkContext() : HeapWalkContext(false) { }
1805 
1806   AdvancedHeapWalkContext(jint heap_filter,
1807                            Klass* klass_filter,
1808                            const jvmtiHeapCallbacks* heap_callbacks) :
1809     HeapWalkContext(true),
1810     _heap_filter(heap_filter),
1811     _klass_filter(klass_filter),
1812     _heap_callbacks(heap_callbacks) {
1813   }
1814 
1815   // accessors
1816   jint heap_filter() const         { return _heap_filter; }
1817   Klass* klass_filter() const      { return _klass_filter; }
1818 
1819   const jvmtiHeapReferenceCallback heap_reference_callback() const {
1820     return _heap_callbacks->heap_reference_callback;
1821   };
1822   const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
1823     return _heap_callbacks->primitive_field_callback;
1824   }
1825   const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
1826     return _heap_callbacks->array_primitive_value_callback;
1827   }
1828   const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
1829     return _heap_callbacks->string_primitive_value_callback;
1830   }
1831 };
1832 
1833 // The CallbackInvoker is a class with static functions that the heap walk can call
1834 // into to invoke callbacks. It works in one of two modes. The "basic" mode is
1835 // used for the deprecated IterateOverReachableObjects functions. The "advanced"
1836 // mode is for the newer FollowReferences function which supports a lot of
1837 // additional callbacks.


3270   BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3271   VM_HeapWalkOperation op(this, Handle(), context, user_data);
3272   VMThread::execute(&op);
3273 }
3274 
3275 // iterate over all objects that are reachable from a given object
3276 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3277                                                              jvmtiObjectReferenceCallback object_ref_callback,
3278                                                              const void* user_data) {
3279   oop obj = JNIHandles::resolve(object);
3280   Handle initial_object(Thread::current(), obj);
3281 
3282   MutexLocker ml(Heap_lock);
3283   BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3284   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3285   VMThread::execute(&op);
3286 }
3287 
3288 // follow references from an initial object or the GC roots
3289 void JvmtiTagMap::follow_references(jint heap_filter,
3290                                     Klass* klass,
3291                                     jobject object,
3292                                     const jvmtiHeapCallbacks* callbacks,
3293                                     const void* user_data)
3294 {
3295   oop obj = JNIHandles::resolve(object);
3296   Handle initial_object(Thread::current(), obj);
3297 
3298   MutexLocker ml(Heap_lock);
3299   AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3300   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3301   VMThread::execute(&op);
3302 }
3303 
3304 
3305 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3306   // No locks during VM bring-up (0 threads) and no safepoints after main
3307   // thread creation and before VMThread creation (1 thread); initial GC
3308   // verification can happen in that window which gets to here.
3309   assert(Threads::number_of_threads() <= 1 ||
3310          SafepointSynchronize::is_at_safepoint(),


< prev index next >