Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 32 additions & 37 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/stringUtils.hpp"
#include "utilities/pair.hpp"
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
Expand Down Expand Up @@ -1624,57 +1623,43 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAP
}
}


static int compare_fields_by_offset(int* a, int* b) {
return a[0] - b[0];
}

void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
InstanceKlass* super = superklass();
if (super != NULL) {
super->do_nonstatic_fields(cl);
}
fieldDescriptor fd;
int length = java_fields_count();
// In DebugInfo nonstatic fields are sorted by offset.
int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
int j = 0;
for (int i = 0; i < length; i += 1) {
fd.reinitialize(this, i);
if (!fd.is_static()) {
cl->do_field(&fd);
fields_sorted[j + 0] = fd.offset();
fields_sorted[j + 1] = i;
j += 2;
}
}
}

// first in Pair is offset, second is index.
static int compare_fields_by_offset(Pair<int,int>* a, Pair<int,int>* b) {
return a->first - b->first;
}

void InstanceKlass::print_nonstatic_fields(FieldClosure* cl) {
InstanceKlass* super = superklass();
if (super != NULL) {
super->print_nonstatic_fields(cl);
}
ResourceMark rm;
fieldDescriptor fd;
// In DebugInfo nonstatic fields are sorted by offset.
GrowableArray<Pair<int,int> > fields_sorted;
int i = 0;
for (AllFieldStream fs(this); !fs.done(); fs.next()) {
if (!fs.access_flags().is_static()) {
fd = fs.field_descriptor();
Pair<int,int> f(fs.offset(), fs.index());
fields_sorted.push(f);
i++;
}
}
if (i > 0) {
int length = i;
assert(length == fields_sorted.length(), "duh");
if (j > 0) {
length = j;
// _sort_Fn is defined in growableArray.hpp.
fields_sorted.sort(compare_fields_by_offset);
for (int i = 0; i < length; i++) {
fd.reinitialize(this, fields_sorted.at(i).second);
assert(!fd.is_static() && fd.offset() == fields_sorted.at(i).first, "only nonstatic fields");
qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
for (int i = 0; i < length; i += 2) {
fd.reinitialize(this, fields_sorted[i + 1]);
assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
cl->do_field(&fd);
}
}
FREE_C_HEAP_ARRAY(int, fields_sorted);
}


void InstanceKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) {
if (array_klasses() != NULL)
array_klasses()->array_klasses_do(f, THREAD);
Expand Down Expand Up @@ -3452,7 +3437,7 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size());
FieldPrinter print_nonstatic_field(st);
InstanceKlass* ik = const_cast<InstanceKlass*>(this);
ik->print_nonstatic_fields(&print_nonstatic_field);
ik->do_nonstatic_fields(&print_nonstatic_field);

st->print(BULLET"non-static oop maps: ");
OopMapBlock* map = start_of_nonstatic_oop_maps();
Expand Down Expand Up @@ -3494,20 +3479,30 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) {
st->print(BULLET"string: ");
java_lang_String::print(obj, st);
st->cr();
if (!WizardMode) return; // that is enough
}
}

st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj));
FieldPrinter print_field(st, obj);
print_nonstatic_fields(&print_field);
do_nonstatic_fields(&print_field);

if (this == vmClasses::Class_klass()) {
st->print(BULLET"signature: ");
java_lang_Class::print_signature(obj, st);
st->cr();
Klass* mirrored_klass = java_lang_Class::as_Klass(obj);
st->print(BULLET"fake entry for mirror: ");
Metadata::print_value_on_maybe_null(st, mirrored_klass);
st->cr();
Klass* array_klass = java_lang_Class::array_klass_acquire(obj);
st->print(BULLET"fake entry for array: ");
Metadata::print_value_on_maybe_null(st, array_klass);
st->cr();
st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
Klass* real_klass = java_lang_Class::as_Klass(obj);
if (real_klass != NULL && real_klass->is_instance_klass()) {
st->print_cr(BULLET"---- static fields (%d words):", java_lang_Class::static_oop_field_count(obj));
InstanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
}
} else if (this == vmClasses::MethodType_klass()) {
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/oops/instanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,6 @@ class InstanceKlass: public Klass {
void do_local_static_fields(FieldClosure* cl);
void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
void print_nonstatic_fields(FieldClosure* cl); // including inherited and injected fields

void methods_do(void f(Method* method));
void array_klasses_do(void f(Klass* k));
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/runtime/fieldDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
assert(field_holder() == ik, "must be already initialized to this class");
}
FieldInfo* f = ik->field(index);
assert(!f->is_internal(), "regular Java fields only");

_access_flags = accessFlags_from(f->access_flags());
guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor");
_index = index;
Expand All @@ -123,16 +125,14 @@ void fieldDescriptor::verify() const {
assert(_index == badInt, "constructor must be called"); // see constructor
} else {
assert(_index >= 0, "good index");
assert(access_flags().is_internal() ||
_index < field_holder()->java_fields_count(), "oob");
assert(_index < field_holder()->java_fields_count(), "oob");
}
}

#endif /* PRODUCT */

void fieldDescriptor::print_on(outputStream* st) const {
access_flags().print_on(st);
if (access_flags().is_internal()) st->print("internal ");
name()->print_value_on(st);
st->print(" ");
signature()->print_value_on(st);
Expand Down
22 changes: 0 additions & 22 deletions test/hotspot/gtest/oops/test_instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@
*/

#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmClasses.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.inline.hpp"
#include "unittest.hpp"

// Tests for InstanceKlass::is_class_loader_instance_klass() function
Expand All @@ -39,23 +37,3 @@ TEST_VM(InstanceKlass, string_klass) {
InstanceKlass* klass = vmClasses::String_klass();
ASSERT_TRUE(!klass->is_class_loader_instance_klass());
}

TEST_VM(InstanceKlass, class_loader_printer) {
ResourceMark rm;
oop loader = SystemDictionary::java_platform_loader();
stringStream st;
loader->print_on(&st);
// See if injected loader_data field is printed in string
ASSERT_TRUE(strstr(st.as_string(), "internal 'loader_data'") != NULL) << "Must contain internal fields";
st.reset();
// See if mirror injected fields are printed.
oop mirror = vmClasses::ClassLoader_klass()->java_mirror();
mirror->print_on(&st);
ASSERT_TRUE(strstr(st.as_string(), "internal 'protection_domain'") != NULL) << "Must contain internal fields";
// We should test other printing functions too.
st.reset();
Method* method = vmClasses::ClassLoader_klass()->methods()->at(0); // we know there's a method here!
method->print_on(&st);
ASSERT_TRUE(strstr(st.as_string(), "method holder:") != NULL) << "Must contain method_holder field";
ASSERT_TRUE(strstr(st.as_string(), "'java/lang/ClassLoader'") != NULL) << "Must be in ClassLoader";
}