hotspot/src/share/vm/prims/jvmtiTagMap.cpp
changeset 13728 882756847a04
parent 13391 30245956af37
child 13738 d67be49a5beb
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Fri Aug 31 16:39:35 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp	Sat Sep 01 13:25:18 2012 -0400
@@ -533,17 +533,6 @@
   }
 }
 
-// If the object is a java.lang.Class then return the klassOop,
-// otherwise return the original object
-static inline oop klassOop_if_java_lang_Class(oop o) {
-  if (o->klass() == SystemDictionary::Class_klass()) {
-    if (!java_lang_Class::is_primitive(o)) {
-      o = (oop)java_lang_Class::as_klassOop(o);
-      assert(o != NULL, "class for non-primitive mirror must exist");
-    }
-  }
-  return o;
-}
 
 // A CallbackWrapper is a support class for querying and tagging an object
 // around a callback to a profiler. The constructor does pre-callback
@@ -567,7 +556,6 @@
   oop _o;
   jlong _obj_size;
   jlong _obj_tag;
-  klassOop _klass;         // the object's class
   jlong _klass_tag;
 
  protected:
@@ -581,8 +569,8 @@
     assert(Thread::current()->is_VM_thread() || tag_map->is_locked(),
            "MT unsafe or must be VM thread");
 
-    // for Classes the klassOop is tagged
-    _o = klassOop_if_java_lang_Class(o);
+    // object to tag
+    _o = o;
 
     // object size
     _obj_size = (jlong)_o->size() * wordSize;
@@ -596,14 +584,9 @@
     _obj_tag = (_entry == NULL) ? 0 : _entry->tag();
 
     // get the class and the class's tag value
-    if (_o == o) {
-      _klass = _o->klass();
-    } else {
-      // if the object represents a runtime class then use the
-      // tag for java.lang.Class
-      _klass = SystemDictionary::Class_klass();
-    }
-    _klass_tag = tag_for(tag_map, _klass);
+    assert(SystemDictionary::Class_klass()->oop_is_instanceMirror(), "Is not?");
+
+    _klass_tag = tag_for(tag_map, _o->klass()->java_mirror());
   }
 
   ~CallbackWrapper() {
@@ -613,7 +596,6 @@
   inline jlong* obj_tag_p()                     { return &_obj_tag; }
   inline jlong obj_size() const                 { return _obj_size; }
   inline jlong obj_tag() const                  { return _obj_tag; }
-  inline klassOop klass() const                 { return _klass; }
   inline jlong klass_tag() const                { return _klass_tag; }
 };
 
@@ -686,8 +668,7 @@
       _referrer_klass_tag = klass_tag();
       _referrer_tag_p = obj_tag_p();
     } else {
-      // for Classes the klassOop is tagged
-      _referrer = klassOop_if_java_lang_Class(referrer);
+      _referrer = referrer;
       // record the context
       _referrer_hashmap = tag_map->hashmap();
       _referrer_entry = _referrer_hashmap->find(_referrer);
@@ -697,10 +678,7 @@
       _referrer_tag_p = &_referrer_obj_tag;
 
       // get referrer class tag.
-      klassOop k = (_referrer == referrer) ?  // Check if referrer is a class...
-          _referrer->klass()                  // No, just get its class
-         : SystemDictionary::Class_klass();   // Yes, its class is Class
-      _referrer_klass_tag = tag_for(tag_map, k);
+      _referrer_klass_tag = tag_for(tag_map, _referrer->klass()->java_mirror());
     }
   }
 
@@ -732,9 +710,6 @@
   // resolve the object
   oop o = JNIHandles::resolve_non_null(object);
 
-  // for Classes we tag the klassOop
-  o = klassOop_if_java_lang_Class(o);
-
   // see if the object is already tagged
   JvmtiTagHashmap* hashmap = _hashmap;
   JvmtiTagHashmapEntry* entry = hashmap->find(o);
@@ -767,8 +742,7 @@
   // resolve the object
   oop o = JNIHandles::resolve_non_null(object);
 
-  // for Classes get the tag from the klassOop
-  return tag_for(this, klassOop_if_java_lang_Class(o));
+  return tag_for(this, o);
 }
 
 
@@ -816,7 +790,7 @@
   ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
 
   // functions to create maps of static or instance fields
-  static ClassFieldMap* create_map_of_static_fields(klassOop k);
+  static ClassFieldMap* create_map_of_static_fields(Klass* k);
   static ClassFieldMap* create_map_of_instance_fields(oop obj);
 };
 
@@ -840,7 +814,7 @@
 // Returns a heap allocated ClassFieldMap to describe the static fields
 // of the given class.
 //
-ClassFieldMap* ClassFieldMap::create_map_of_static_fields(klassOop k) {
+ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) {
   HandleMark hm;
   instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
 
@@ -889,7 +863,7 @@
 }
 
 // Helper class used to cache a ClassFileMap for the instance fields of
-// a cache. A JvmtiCachedClassFieldMap can be cached by an instanceKlass during
+// a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during
 // heap iteration and avoid creating a field map for each object in the heap
 // (only need to create the map when the first instance of a class is encountered).
 //
@@ -905,12 +879,12 @@
   JvmtiCachedClassFieldMap(ClassFieldMap* field_map);
   ~JvmtiCachedClassFieldMap();
 
-  static GrowableArray<instanceKlass*>* _class_list;
-  static void add_to_class_list(instanceKlass* ik);
+  static GrowableArray<InstanceKlass*>* _class_list;
+  static void add_to_class_list(InstanceKlass* ik);
 
  public:
   // returns the field map for a given object (returning map cached
-  // by instanceKlass if possible
+  // by InstanceKlass if possible
   static ClassFieldMap* get_map_of_instance_fields(oop obj);
 
   // removes the field map from all instanceKlasses - should be
@@ -921,7 +895,7 @@
   static int cached_field_map_count();
 };
 
-GrowableArray<instanceKlass*>* JvmtiCachedClassFieldMap::_class_list;
+GrowableArray<InstanceKlass*>* JvmtiCachedClassFieldMap::_class_list;
 
 JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) {
   _field_map = field_map;
@@ -955,23 +929,23 @@
 bool ClassFieldMapCacheMark::_is_active;
 
 
-// record that the given instanceKlass is caching a field map
-void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) {
+// record that the given InstanceKlass is caching a field map
+void JvmtiCachedClassFieldMap::add_to_class_list(InstanceKlass* ik) {
   if (_class_list == NULL) {
     _class_list = new (ResourceObj::C_HEAP, mtInternal)
-      GrowableArray<instanceKlass*>(initial_class_count, true);
+      GrowableArray<InstanceKlass*>(initial_class_count, true);
   }
   _class_list->push(ik);
 }
 
 // returns the instance field map for the given object
-// (returns field map cached by the instanceKlass if possible)
+// (returns field map cached by the InstanceKlass if possible)
 ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) {
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
   assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active");
 
-  klassOop k = obj->klass();
-  instanceKlass* ik = instanceKlass::cast(k);
+  Klass* k = obj->klass();
+  InstanceKlass* ik = InstanceKlass::cast(k);
 
   // return cached map if possible
   JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
@@ -992,7 +966,7 @@
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
   if (_class_list != NULL) {
     for (int i = 0; i < _class_list->length(); i++) {
-      instanceKlass* ik = _class_list->at(i);
+      InstanceKlass* ik = _class_list->at(i);
       JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
       assert(cached_map != NULL, "should not be NULL");
       ik->set_jvmti_cached_class_field_map(NULL);
@@ -1131,8 +1105,7 @@
   if (java_lang_Class::is_primitive(obj)) {
     return 0;
   }
-  klassOop k = java_lang_Class::as_klassOop(obj);
-  Klass* klass = k->klass_part();
+  Klass* klass = java_lang_Class::as_Klass(obj);
 
   // ignore classes for object and type arrays
   if (!klass->oop_is_instance()) {
@@ -1140,13 +1113,13 @@
   }
 
   // ignore classes which aren't linked yet
-  instanceKlass* ik = instanceKlass::cast(k);
+  InstanceKlass* ik = InstanceKlass::cast(klass);
   if (!ik->is_linked()) {
     return 0;
   }
 
   // get the field map
-  ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
+  ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
 
   // invoke the callback for each static primitive field
   for (int i=0; i<field_map->field_count(); i++) {
@@ -1162,7 +1135,7 @@
 
     // get offset and field value
     int offset = field->field_offset();
-    address addr = (address)k + offset;
+    address addr = (address)klass + offset;
     jvalue value;
     copy_to_jvalue(&value, addr, value_type);
 
@@ -1265,14 +1238,6 @@
     // consider using safe_object_iterate() which avoids perm gen
     // objects that may contain bad references.
     Universe::heap()->object_iterate(_blk);
-
-    // when sharing is enabled we must iterate over the shared spaces
-    if (UseSharedSpaces) {
-      GenCollectedHeap* gch = GenCollectedHeap::heap();
-      CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen();
-      gen->ro_space()->object_iterate(_blk);
-      gen->rw_space()->object_iterate(_blk);
-    }
   }
 
 };
@@ -1545,14 +1510,7 @@
     for (int i=0; i<_tag_count; i++) {
       if (_tags[i] == entry->tag()) {
         oop o = entry->object();
-        assert(o != NULL, "sanity check");
-
-        // the mirror is tagged
-        if (o->is_klass()) {
-          klassOop k = (klassOop)o;
-          o = Klass::cast(k)->java_mirror();
-        }
-
+        assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check");
         jobject ref = JNIHandles::make_local(JavaThread::current(), o);
         _object_results->append(ref);
         _tag_results->append((uint64_t)entry->tag());
@@ -1695,14 +1653,6 @@
     set_needs_reset(true);
   }
 
-  // When sharing is enabled we need to restore the headers of the objects
-  // in the readwrite space too.
-  if (UseSharedSpaces) {
-    GenCollectedHeap* gch = GenCollectedHeap::heap();
-    CompactingPermGenGen* gen = (CompactingPermGenGen*)gch->perm_gen();
-    gen->rw_space()->object_iterate(&blk);
-  }
-
   // now restore the interesting headers
   for (int i = 0; i < _saved_oop_stack->length(); i++) {
     oop o = _saved_oop_stack->at(i);
@@ -2069,7 +2019,7 @@
   if (referrer == context->last_referrer()) {
     referrer_tag = context->last_referrer_tag();
   } else {
-    referrer_tag = tag_for(tag_map(), klassOop_if_java_lang_Class(referrer));
+    referrer_tag = tag_for(tag_map(), referrer);
   }
 
   // do the callback
@@ -2604,24 +2554,13 @@
 
     jvmtiHeapReferenceKind kind = root_kind();
 
-    // many roots are Klasses so we use the java mirror
-    if (o->is_klass()) {
-      klassOop k = (klassOop)o;
-      o = Klass::cast(k)->java_mirror();
-      if (o == NULL) {
-        // Classes without mirrors don't correspond to real Java
-        // classes so just ignore them.
-        return;
-      }
-    } else {
-
+    assert(Universe::heap()->is_in_reserved(o), "should be impossible");
       // SystemDictionary::always_strong_oops_do reports the application
       // class loader as a root. We want this root to be reported as
       // a root kind of "OTHER" rather than "SYSTEM_CLASS".
       if (o->is_instance() && root_kind() == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
         kind = JVMTI_HEAP_REFERENCE_OTHER;
       }
-    }
 
     // some objects are ignored - in the case of simple
     // roots it's mostly Symbol*s that we are skipping
@@ -2733,7 +2672,7 @@
   // iterate over the various object types
   inline bool iterate_over_array(oop o);
   inline bool iterate_over_type_array(oop o);
-  inline bool iterate_over_class(klassOop o);
+  inline bool iterate_over_class(oop o);
   inline bool iterate_over_object(oop o);
 
   // root collection
@@ -2807,10 +2746,6 @@
 // each element in the array
 inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
   objArrayOop array = objArrayOop(o);
-  if (array->klass() == Universe::systemObjArrayKlassObj()) {
-    // filtered out
-    return true;
-  }
 
   // array reference to its class
   oop mirror = objArrayKlass::cast(array->klass())->java_mirror();
@@ -2836,7 +2771,7 @@
 
 // a type array references its class
 inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
-  klassOop k = o->klass();
+  Klass* k = o->klass();
   oop mirror = Klass::cast(k)->java_mirror();
   if (!CallbackInvoker::report_class_reference(o, mirror)) {
     return false;
@@ -2852,7 +2787,7 @@
 }
 
 // verify that a static oop field is in range
-static inline bool verify_static_oop(instanceKlass* ik,
+static inline bool verify_static_oop(InstanceKlass* ik,
                                      oop mirror, int offset) {
   address obj_p = (address)mirror + offset;
   address start = (address)instanceMirrorKlass::start_of_static_fields(mirror);
@@ -2868,12 +2803,12 @@
 
 // a class references its super class, interfaces, class loader, ...
 // and finally its static fields
-inline bool VM_HeapWalkOperation::iterate_over_class(klassOop k) {
+inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) {
   int i;
-  Klass* klass = klassOop(k)->klass_part();
+  Klass* klass = java_lang_Class::as_Klass(java_class);
 
   if (klass->oop_is_instance()) {
-    instanceKlass* ik = instanceKlass::cast(k);
+    InstanceKlass* ik = InstanceKlass::cast(klass);
 
     // ignore the class if it's has been initialized yet
     if (!ik->is_linked()) {
@@ -2884,7 +2819,7 @@
     oop mirror = klass->java_mirror();
 
     // super (only if something more interesting than java.lang.Object)
-    klassOop java_super = ik->java_super();
+    Klass* java_super = ik->java_super();
     if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
       oop super = Klass::cast(java_super)->java_mirror();
       if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
@@ -2918,13 +2853,15 @@
 
     // references from the constant pool
     {
-      const constantPoolOop pool = ik->constants();
+      ConstantPool* const pool = ik->constants();
       for (int i = 1; i < pool->length(); i++) {
         constantTag tag = pool->tag_at(i).value();
         if (tag.is_string() || tag.is_klass()) {
           oop entry;
           if (tag.is_string()) {
             entry = pool->resolved_string_at(i);
+            // If the entry is non-null it it resolved.
+            if (entry == NULL) continue;
             assert(java_lang_String::is_instance(entry), "must be string");
           } else {
             entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
@@ -2939,9 +2876,9 @@
     // interfaces
     // (These will already have been reported as references from the constant pool
     //  but are specified by IterateOverReachableObjects and must be reported).
-    objArrayOop interfaces = ik->local_interfaces();
+    Array<Klass*>* interfaces = ik->local_interfaces();
     for (i = 0; i < interfaces->length(); i++) {
-      oop interf = Klass::cast((klassOop)interfaces->obj_at(i))->java_mirror();
+      oop interf = Klass::cast((Klass*)interfaces->at(i))->java_mirror();
       if (interf == NULL) {
         continue;
       }
@@ -2952,7 +2889,7 @@
 
     // iterate over the static fields
 
-    ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(k);
+    ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
     for (i=0; i<field_map->field_count(); i++) {
       ClassFieldDescriptor* field = field_map->field_at(i);
       char type = field->field_type();
@@ -3003,12 +2940,8 @@
       oop fld_o = o->obj_field(field->field_offset());
       // ignore any objects that aren't visible to profiler
       if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
-        // reflection code may have a reference to a klassOop.
-        // - see sun.reflect.UnsafeStaticFieldAccessorImpl and sun.misc.Unsafe
-        if (fld_o->is_klass()) {
-          klassOop k = (klassOop)fld_o;
-          fld_o = Klass::cast(k)->java_mirror();
-        }
+        assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
+               "have references to Klass* anymore");
         int slot = field->field_index();
         if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
           return false;
@@ -3058,6 +2991,7 @@
   // Preloaded classes and loader from the system dictionary
   blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
   SystemDictionary::always_strong_oops_do(&blk);
+  ClassLoaderDataGraph::always_strong_oops_do(&blk, NULL, false);
   if (blk.stopped()) {
     return false;
   }
@@ -3213,10 +3147,9 @@
   // instance
   if (o->is_instance()) {
     if (o->klass() == SystemDictionary::Class_klass()) {
-      o = klassOop_if_java_lang_Class(o);
-      if (o->is_klass()) {
+      if (!java_lang_Class::is_primitive(o)) {
         // a java.lang.Class
-        return iterate_over_class(klassOop(o));
+        return iterate_over_class(o);
       }
     } else {
       return iterate_over_object(o);