8271221: [BACKOUT] JDK-8271063 Print injected fields for InstanceKlass

Reviewed-by: coleenp
This commit is contained in:
Daniel D. Daugherty 2021-07-23 15:53:49 +00:00
parent f4b3ee5dca
commit ec71e2d891
4 changed files with 35 additions and 63 deletions

View File

@ -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
@ -1624,6 +1623,11 @@ 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) {
@ -1631,50 +1635,31 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* 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);
@ -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();
@ -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()) {

View File

@ -1007,7 +1007,6 @@ public:
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));

View File

@ -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;
@ -123,8 +125,7 @@ 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");
}
}
@ -132,7 +133,6 @@ void fieldDescriptor::verify() const {
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);

View File

@ -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
@ -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";
}