Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8271063: Print injected fields for InstanceKlass
Reviewed-by: fparain, hseigel, yyang
  • Loading branch information
coleenp committed Jul 23, 2021
1 parent 0cc4bb7 commit 9b27df6
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 35 deletions.
69 changes: 37 additions & 32 deletions src/hotspot/share/oops/instanceKlass.cpp
Expand Up @@ -88,6 +88,7 @@
#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 @@ -1623,43 +1624,57 @@ 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()) {
fields_sorted[j + 0] = fd.offset();
fields_sorted[j + 1] = i;
j += 2;
cl->do_field(&fd);
}
}
if (j > 0) {
length = j;
}

// 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");
// _sort_Fn is defined in growableArray.hpp.
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");
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");
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 @@ -3437,7 +3452,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->do_nonstatic_fields(&print_nonstatic_field);
ik->print_nonstatic_fields(&print_nonstatic_field);

st->print(BULLET"non-static oop maps: ");
OopMapBlock* map = start_of_nonstatic_oop_maps();
Expand Down Expand Up @@ -3479,30 +3494,20 @@ 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);
do_nonstatic_fields(&print_field);
print_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: 1 addition & 0 deletions src/hotspot/share/oops/instanceKlass.hpp
Expand Up @@ -1007,6 +1007,7 @@ 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
Expand Up @@ -110,8 +110,6 @@ 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 @@ -125,14 +123,16 @@ void fieldDescriptor::verify() const {
assert(_index == badInt, "constructor must be called"); // see constructor
} else {
assert(_index >= 0, "good index");
assert(_index < field_holder()->java_fields_count(), "oob");
assert(access_flags().is_internal() ||
_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: 22 additions & 0 deletions test/hotspot/gtest/oops/test_instanceKlass.cpp
Expand Up @@ -22,9 +22,11 @@
*/

#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 @@ -37,3 +39,23 @@ 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";
}

1 comment on commit 9b27df6

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.