< prev index next >

src/share/vm/prims/jvmtiTagMap.cpp

Print this page
rev 12310 : [mq]: gcinterface.patch


1231     }
1232   }
1233   return 0;
1234 }
1235 
1236 
1237 // VM operation to iterate over all objects in the heap (both reachable
1238 // and unreachable)
1239 class VM_HeapIterateOperation: public VM_Operation {
1240  private:
1241   ObjectClosure* _blk;
1242  public:
1243   VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; }
1244 
1245   VMOp_Type type() const { return VMOp_HeapIterateOperation; }
1246   void doit() {
1247     // allows class files maps to be cached during iteration
1248     ClassFieldMapCacheMark cm;
1249 
1250     // make sure that heap is parsable (fills TLABs with filler objects)
1251     Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
1252 
1253     // Verify heap before iteration - if the heap gets corrupted then
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; }


1516     _env = env;
1517     _tags = (jlong*)tags;
1518     _tag_count = tag_count;
1519     _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true);
1520     _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true);
1521   }
1522 
1523   ~TagObjectCollector() {
1524     delete _object_results;
1525     delete _tag_results;
1526   }
1527 
1528   // for each tagged object check if the tag value matches
1529   // - if it matches then we create a JNI local reference to the object
1530   // and record the reference and tag value.
1531   //
1532   void do_entry(JvmtiTagHashmapEntry* entry) {
1533     for (int i=0; i<_tag_count; i++) {
1534       if (_tags[i] == entry->tag()) {
1535         oop o = entry->object();
1536         assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check");
1537         jobject ref = JNIHandles::make_local(JavaThread::current(), o);
1538         _object_results->append(ref);
1539         _tag_results->append((uint64_t)entry->tag());
1540       }
1541     }
1542   }
1543 
1544   // return the results from the collection
1545   //
1546   jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1547     jvmtiError error;
1548     int count = _object_results->length();
1549     assert(count >= 0, "sanity check");
1550 
1551     // if object_result_ptr is not NULL then allocate the result and copy
1552     // in the object references.
1553     if (object_result_ptr != NULL) {
1554       error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr);
1555       if (error != JVMTI_ERROR_NONE) {
1556         return error;


1635  public:
1636   static void init();                       // initialize
1637   static void done();                       // clean-up
1638 
1639   static inline void mark(oop o);           // mark an object
1640   static inline bool visited(oop o);        // check if object has been visited
1641 
1642   static inline bool needs_reset()            { return _needs_reset; }
1643   static inline void set_needs_reset(bool v)  { _needs_reset = v; }
1644 };
1645 
1646 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1647 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
1648 bool ObjectMarker::_needs_reset = true;  // need to reset mark bits by default
1649 
1650 // initialize ObjectMarker - prepares for object marking
1651 void ObjectMarker::init() {
1652   assert(Thread::current()->is_VM_thread(), "must be VMThread");
1653 
1654   // prepare heap for iteration
1655   Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
1656 
1657   // create stacks for interesting headers
1658   _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true);
1659   _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
1660 
1661   if (UseBiasedLocking) {
1662     BiasedLocking::preserve_marks();
1663   }
1664 }
1665 
1666 // Object marking is done so restore object headers
1667 void ObjectMarker::done() {
1668   // iterate over all objects and restore the mark bits to
1669   // their initial value
1670   RestoreMarksClosure blk;
1671   if (needs_reset()) {
1672     Universe::heap()->object_iterate(&blk);
1673   } else {
1674     // We don't need to reset mark bits on this call, but reset the
1675     // flag to the default for the next call.
1676     set_needs_reset(true);
1677   }
1678 
1679   // now restore the interesting headers
1680   for (int i = 0; i < _saved_oop_stack->length(); i++) {
1681     oop o = _saved_oop_stack->at(i);
1682     markOop mark = _saved_mark_stack->at(i);
1683     o->set_mark(mark);
1684   }
1685 
1686   if (UseBiasedLocking) {
1687     BiasedLocking::restore_marks();
1688   }
1689 
1690   // free the stacks
1691   delete _saved_oop_stack;
1692   delete _saved_mark_stack;
1693 }
1694 
1695 // mark an object
1696 inline void ObjectMarker::mark(oop o) {
1697   assert(Universe::heap()->is_in(o), "sanity check");
1698   assert(!o->mark()->is_marked(), "should only mark an object once");
1699 
1700   // object's mark word
1701   markOop mark = o->mark();
1702 
1703   if (mark->must_be_preserved(o)) {
1704     _saved_mark_stack->push(mark);
1705     _saved_oop_stack->push(o);
1706   }
1707 
1708   // mark the object
1709   o->set_mark(markOopDesc::prototype()->set_marked());
1710 }
1711 
1712 // return true if object is marked
1713 inline bool ObjectMarker::visited(oop o) {
1714   return o->mark()->is_marked();
1715 }
1716 
1717 // Stack allocated class to help ensure that ObjectMarker is used


2558     _kind = kind;
2559     _continue = true;
2560   }
2561 
2562   inline bool stopped() {
2563     return !_continue;
2564   }
2565 
2566   void do_oop(oop* obj_p) {
2567     // iteration has terminated
2568     if (stopped()) {
2569       return;
2570     }
2571 
2572     // ignore null or deleted handles
2573     oop o = *obj_p;
2574     if (o == NULL || o == JNIHandles::deleted_handle()) {
2575       return;
2576     }
2577 
2578     assert(Universe::heap()->is_in_reserved(o), "should be impossible");
2579 
2580     jvmtiHeapReferenceKind kind = root_kind();
2581     if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2582       // SystemDictionary::always_strong_oops_do reports the application
2583       // class loader as a root. We want this root to be reported as
2584       // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2585       if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
2586         kind = JVMTI_HEAP_REFERENCE_OTHER;
2587       }
2588     }
2589 
2590     // some objects are ignored - in the case of simple
2591     // roots it's mostly Symbol*s that we are skipping
2592     // here.
2593     if (!ServiceUtil::visible_oop(o)) {
2594       return;
2595     }
2596 
2597     // invoke the callback
2598     _continue = CallbackInvoker::report_simple_root(kind, o);


2949 }
2950 
2951 // an object references a class and its instance fields
2952 // (static fields are ignored here as we report these as
2953 // references from the class).
2954 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2955   // reference to the class
2956   if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
2957     return false;
2958   }
2959 
2960   // iterate over instance fields
2961   ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2962   for (int i=0; i<field_map->field_count(); i++) {
2963     ClassFieldDescriptor* field = field_map->field_at(i);
2964     char type = field->field_type();
2965     if (!is_primitive_field_type(type)) {
2966       oop fld_o = o->obj_field(field->field_offset());
2967       // ignore any objects that aren't visible to profiler
2968       if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
2969         assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
2970                "have references to Klass* anymore");
2971         int slot = field->field_index();
2972         if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
2973           return false;
2974         }
2975       }
2976     } else {
2977       if (is_reporting_primitive_fields()) {
2978         // primitive instance field
2979         address addr = (address)o + field->field_offset();
2980         int slot = field->field_index();
2981         if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
2982           return false;
2983         }
2984       }
2985     }
2986   }
2987 
2988   // if the object is a java.lang.String
2989   if (is_reporting_string_values() &&




1231     }
1232   }
1233   return 0;
1234 }
1235 
1236 
1237 // VM operation to iterate over all objects in the heap (both reachable
1238 // and unreachable)
1239 class VM_HeapIterateOperation: public VM_Operation {
1240  private:
1241   ObjectClosure* _blk;
1242  public:
1243   VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; }
1244 
1245   VMOp_Type type() const { return VMOp_HeapIterateOperation; }
1246   void doit() {
1247     // allows class files maps to be cached during iteration
1248     ClassFieldMapCacheMark cm;
1249 
1250     // make sure that heap is parsable (fills TLABs with filler objects)
1251     GC::gc()->heap()->ensure_parsability(false);  // no need to retire TLABs
1252 
1253     // Verify heap before iteration - if the heap gets corrupted then
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     GC::gc()->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; }


1516     _env = env;
1517     _tags = (jlong*)tags;
1518     _tag_count = tag_count;
1519     _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true);
1520     _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true);
1521   }
1522 
1523   ~TagObjectCollector() {
1524     delete _object_results;
1525     delete _tag_results;
1526   }
1527 
1528   // for each tagged object check if the tag value matches
1529   // - if it matches then we create a JNI local reference to the object
1530   // and record the reference and tag value.
1531   //
1532   void do_entry(JvmtiTagHashmapEntry* entry) {
1533     for (int i=0; i<_tag_count; i++) {
1534       if (_tags[i] == entry->tag()) {
1535         oop o = entry->object();
1536         assert(o != NULL && GC::gc()->heap()->is_in_reserved(o), "sanity check");
1537         jobject ref = JNIHandles::make_local(JavaThread::current(), o);
1538         _object_results->append(ref);
1539         _tag_results->append((uint64_t)entry->tag());
1540       }
1541     }
1542   }
1543 
1544   // return the results from the collection
1545   //
1546   jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
1547     jvmtiError error;
1548     int count = _object_results->length();
1549     assert(count >= 0, "sanity check");
1550 
1551     // if object_result_ptr is not NULL then allocate the result and copy
1552     // in the object references.
1553     if (object_result_ptr != NULL) {
1554       error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr);
1555       if (error != JVMTI_ERROR_NONE) {
1556         return error;


1635  public:
1636   static void init();                       // initialize
1637   static void done();                       // clean-up
1638 
1639   static inline void mark(oop o);           // mark an object
1640   static inline bool visited(oop o);        // check if object has been visited
1641 
1642   static inline bool needs_reset()            { return _needs_reset; }
1643   static inline void set_needs_reset(bool v)  { _needs_reset = v; }
1644 };
1645 
1646 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
1647 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
1648 bool ObjectMarker::_needs_reset = true;  // need to reset mark bits by default
1649 
1650 // initialize ObjectMarker - prepares for object marking
1651 void ObjectMarker::init() {
1652   assert(Thread::current()->is_VM_thread(), "must be VMThread");
1653 
1654   // prepare heap for iteration
1655   GC::gc()->heap()->ensure_parsability(false);  // no need to retire TLABs
1656 
1657   // create stacks for interesting headers
1658   _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true);
1659   _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
1660 
1661   if (UseBiasedLocking) {
1662     BiasedLocking::preserve_marks();
1663   }
1664 }
1665 
1666 // Object marking is done so restore object headers
1667 void ObjectMarker::done() {
1668   // iterate over all objects and restore the mark bits to
1669   // their initial value
1670   RestoreMarksClosure blk;
1671   if (needs_reset()) {
1672     GC::gc()->heap()->object_iterate(&blk);
1673   } else {
1674     // We don't need to reset mark bits on this call, but reset the
1675     // flag to the default for the next call.
1676     set_needs_reset(true);
1677   }
1678 
1679   // now restore the interesting headers
1680   for (int i = 0; i < _saved_oop_stack->length(); i++) {
1681     oop o = _saved_oop_stack->at(i);
1682     markOop mark = _saved_mark_stack->at(i);
1683     o->set_mark(mark);
1684   }
1685 
1686   if (UseBiasedLocking) {
1687     BiasedLocking::restore_marks();
1688   }
1689 
1690   // free the stacks
1691   delete _saved_oop_stack;
1692   delete _saved_mark_stack;
1693 }
1694 
1695 // mark an object
1696 inline void ObjectMarker::mark(oop o) {
1697   assert(GC::gc()->heap()->is_in(o), "sanity check");
1698   assert(!o->mark()->is_marked(), "should only mark an object once");
1699 
1700   // object's mark word
1701   markOop mark = o->mark();
1702 
1703   if (mark->must_be_preserved(o)) {
1704     _saved_mark_stack->push(mark);
1705     _saved_oop_stack->push(o);
1706   }
1707 
1708   // mark the object
1709   o->set_mark(markOopDesc::prototype()->set_marked());
1710 }
1711 
1712 // return true if object is marked
1713 inline bool ObjectMarker::visited(oop o) {
1714   return o->mark()->is_marked();
1715 }
1716 
1717 // Stack allocated class to help ensure that ObjectMarker is used


2558     _kind = kind;
2559     _continue = true;
2560   }
2561 
2562   inline bool stopped() {
2563     return !_continue;
2564   }
2565 
2566   void do_oop(oop* obj_p) {
2567     // iteration has terminated
2568     if (stopped()) {
2569       return;
2570     }
2571 
2572     // ignore null or deleted handles
2573     oop o = *obj_p;
2574     if (o == NULL || o == JNIHandles::deleted_handle()) {
2575       return;
2576     }
2577 
2578     assert(GC::gc()->heap()->is_in_reserved(o), "should be impossible");
2579 
2580     jvmtiHeapReferenceKind kind = root_kind();
2581     if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
2582       // SystemDictionary::always_strong_oops_do reports the application
2583       // class loader as a root. We want this root to be reported as
2584       // a root kind of "OTHER" rather than "SYSTEM_CLASS".
2585       if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
2586         kind = JVMTI_HEAP_REFERENCE_OTHER;
2587       }
2588     }
2589 
2590     // some objects are ignored - in the case of simple
2591     // roots it's mostly Symbol*s that we are skipping
2592     // here.
2593     if (!ServiceUtil::visible_oop(o)) {
2594       return;
2595     }
2596 
2597     // invoke the callback
2598     _continue = CallbackInvoker::report_simple_root(kind, o);


2949 }
2950 
2951 // an object references a class and its instance fields
2952 // (static fields are ignored here as we report these as
2953 // references from the class).
2954 inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
2955   // reference to the class
2956   if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
2957     return false;
2958   }
2959 
2960   // iterate over instance fields
2961   ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
2962   for (int i=0; i<field_map->field_count(); i++) {
2963     ClassFieldDescriptor* field = field_map->field_at(i);
2964     char type = field->field_type();
2965     if (!is_primitive_field_type(type)) {
2966       oop fld_o = o->obj_field(field->field_offset());
2967       // ignore any objects that aren't visible to profiler
2968       if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
2969         assert(GC::gc()->heap()->is_in_reserved(fld_o), "unsafe code should not "
2970                "have references to Klass* anymore");
2971         int slot = field->field_index();
2972         if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
2973           return false;
2974         }
2975       }
2976     } else {
2977       if (is_reporting_primitive_fields()) {
2978         // primitive instance field
2979         address addr = (address)o + field->field_offset();
2980         int slot = field->field_index();
2981         if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
2982           return false;
2983         }
2984       }
2985     }
2986   }
2987 
2988   // if the object is a java.lang.String
2989   if (is_reporting_string_values() &&


< prev index next >