diff -r 36d1d483d5d6 -r da91efe96a93 src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/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* _class_list; - static void add_to_class_list(instanceKlass* ik); + static GrowableArray* _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* JvmtiCachedClassFieldMap::_class_list; +GrowableArray* 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(initial_class_count, true); + GrowableArray(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; ifield_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* 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; ifield_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);