--- 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);