Skip to content

Commit 9b27df6

Browse files
committedJul 23, 2021
8271063: Print injected fields for InstanceKlass
Reviewed-by: fparain, hseigel, yyang
1 parent 0cc4bb7 commit 9b27df6

File tree

4 files changed

+63
-35
lines changed

4 files changed

+63
-35
lines changed
 

‎src/hotspot/share/oops/instanceKlass.cpp

+37-32
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include "utilities/events.hpp"
8989
#include "utilities/macros.hpp"
9090
#include "utilities/stringUtils.hpp"
91+
#include "utilities/pair.hpp"
9192
#ifdef COMPILER1
9293
#include "c1/c1_Compiler.hpp"
9394
#endif
@@ -1623,43 +1624,57 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAP
16231624
}
16241625
}
16251626

1626-
1627-
static int compare_fields_by_offset(int* a, int* b) {
1628-
return a[0] - b[0];
1629-
}
1630-
16311627
void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
16321628
InstanceKlass* super = superklass();
16331629
if (super != NULL) {
16341630
super->do_nonstatic_fields(cl);
16351631
}
16361632
fieldDescriptor fd;
16371633
int length = java_fields_count();
1638-
// In DebugInfo nonstatic fields are sorted by offset.
1639-
int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
1640-
int j = 0;
16411634
for (int i = 0; i < length; i += 1) {
16421635
fd.reinitialize(this, i);
16431636
if (!fd.is_static()) {
1644-
fields_sorted[j + 0] = fd.offset();
1645-
fields_sorted[j + 1] = i;
1646-
j += 2;
1637+
cl->do_field(&fd);
16471638
}
16481639
}
1649-
if (j > 0) {
1650-
length = j;
1640+
}
1641+
1642+
// first in Pair is offset, second is index.
1643+
static int compare_fields_by_offset(Pair<int,int>* a, Pair<int,int>* b) {
1644+
return a->first - b->first;
1645+
}
1646+
1647+
void InstanceKlass::print_nonstatic_fields(FieldClosure* cl) {
1648+
InstanceKlass* super = superklass();
1649+
if (super != NULL) {
1650+
super->print_nonstatic_fields(cl);
1651+
}
1652+
ResourceMark rm;
1653+
fieldDescriptor fd;
1654+
// In DebugInfo nonstatic fields are sorted by offset.
1655+
GrowableArray<Pair<int,int> > fields_sorted;
1656+
int i = 0;
1657+
for (AllFieldStream fs(this); !fs.done(); fs.next()) {
1658+
if (!fs.access_flags().is_static()) {
1659+
fd = fs.field_descriptor();
1660+
Pair<int,int> f(fs.offset(), fs.index());
1661+
fields_sorted.push(f);
1662+
i++;
1663+
}
1664+
}
1665+
if (i > 0) {
1666+
int length = i;
1667+
assert(length == fields_sorted.length(), "duh");
16511668
// _sort_Fn is defined in growableArray.hpp.
1652-
qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
1653-
for (int i = 0; i < length; i += 2) {
1654-
fd.reinitialize(this, fields_sorted[i + 1]);
1655-
assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
1669+
fields_sorted.sort(compare_fields_by_offset);
1670+
for (int i = 0; i < length; i++) {
1671+
fd.reinitialize(this, fields_sorted.at(i).second);
1672+
assert(!fd.is_static() && fd.offset() == fields_sorted.at(i).first, "only nonstatic fields");
16561673
cl->do_field(&fd);
16571674
}
16581675
}
1659-
FREE_C_HEAP_ARRAY(int, fields_sorted);
16601676
}
16611677

1662-
16631678
void InstanceKlass::array_klasses_do(void f(Klass* k, TRAPS), TRAPS) {
16641679
if (array_klasses() != NULL)
16651680
array_klasses()->array_klasses_do(f, THREAD);
@@ -3437,7 +3452,7 @@ void InstanceKlass::print_on(outputStream* st) const {
34373452
st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size());
34383453
FieldPrinter print_nonstatic_field(st);
34393454
InstanceKlass* ik = const_cast<InstanceKlass*>(this);
3440-
ik->do_nonstatic_fields(&print_nonstatic_field);
3455+
ik->print_nonstatic_fields(&print_nonstatic_field);
34413456

34423457
st->print(BULLET"non-static oop maps: ");
34433458
OopMapBlock* map = start_of_nonstatic_oop_maps();
@@ -3479,30 +3494,20 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) {
34793494
st->print(BULLET"string: ");
34803495
java_lang_String::print(obj, st);
34813496
st->cr();
3482-
if (!WizardMode) return; // that is enough
34833497
}
34843498
}
34853499

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

34903504
if (this == vmClasses::Class_klass()) {
34913505
st->print(BULLET"signature: ");
34923506
java_lang_Class::print_signature(obj, st);
34933507
st->cr();
3494-
Klass* mirrored_klass = java_lang_Class::as_Klass(obj);
3495-
st->print(BULLET"fake entry for mirror: ");
3496-
Metadata::print_value_on_maybe_null(st, mirrored_klass);
3497-
st->cr();
3498-
Klass* array_klass = java_lang_Class::array_klass_acquire(obj);
3499-
st->print(BULLET"fake entry for array: ");
3500-
Metadata::print_value_on_maybe_null(st, array_klass);
3501-
st->cr();
3502-
st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
3503-
st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
35043508
Klass* real_klass = java_lang_Class::as_Klass(obj);
35053509
if (real_klass != NULL && real_klass->is_instance_klass()) {
3510+
st->print_cr(BULLET"---- static fields (%d words):", java_lang_Class::static_oop_field_count(obj));
35063511
InstanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
35073512
}
35083513
} else if (this == vmClasses::MethodType_klass()) {

‎src/hotspot/share/oops/instanceKlass.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,7 @@ class InstanceKlass: public Klass {
10071007
void do_local_static_fields(FieldClosure* cl);
10081008
void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
10091009
void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
1010+
void print_nonstatic_fields(FieldClosure* cl); // including inherited and injected fields
10101011

10111012
void methods_do(void f(Method* method));
10121013
void array_klasses_do(void f(Klass* k));

‎src/hotspot/share/runtime/fieldDescriptor.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
110110
assert(field_holder() == ik, "must be already initialized to this class");
111111
}
112112
FieldInfo* f = ik->field(index);
113-
assert(!f->is_internal(), "regular Java fields only");
114-
115113
_access_flags = accessFlags_from(f->access_flags());
116114
guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor");
117115
_index = index;
@@ -125,14 +123,16 @@ void fieldDescriptor::verify() const {
125123
assert(_index == badInt, "constructor must be called"); // see constructor
126124
} else {
127125
assert(_index >= 0, "good index");
128-
assert(_index < field_holder()->java_fields_count(), "oob");
126+
assert(access_flags().is_internal() ||
127+
_index < field_holder()->java_fields_count(), "oob");
129128
}
130129
}
131130

132131
#endif /* PRODUCT */
133132

134133
void fieldDescriptor::print_on(outputStream* st) const {
135134
access_flags().print_on(st);
135+
if (access_flags().is_internal()) st->print("internal ");
136136
name()->print_value_on(st);
137137
st->print(" ");
138138
signature()->print_value_on(st);

‎test/hotspot/gtest/oops/test_instanceKlass.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
*/
2323

2424
#include "precompiled.hpp"
25+
#include "classfile/systemDictionary.hpp"
2526
#include "classfile/vmClasses.hpp"
2627
#include "memory/resourceArea.hpp"
2728
#include "oops/instanceKlass.hpp"
29+
#include "oops/klass.inline.hpp"
2830
#include "unittest.hpp"
2931

3032
// Tests for InstanceKlass::is_class_loader_instance_klass() function
@@ -37,3 +39,23 @@ TEST_VM(InstanceKlass, string_klass) {
3739
InstanceKlass* klass = vmClasses::String_klass();
3840
ASSERT_TRUE(!klass->is_class_loader_instance_klass());
3941
}
42+
43+
TEST_VM(InstanceKlass, class_loader_printer) {
44+
ResourceMark rm;
45+
oop loader = SystemDictionary::java_platform_loader();
46+
stringStream st;
47+
loader->print_on(&st);
48+
// See if injected loader_data field is printed in string
49+
ASSERT_TRUE(strstr(st.as_string(), "internal 'loader_data'") != NULL) << "Must contain internal fields";
50+
st.reset();
51+
// See if mirror injected fields are printed.
52+
oop mirror = vmClasses::ClassLoader_klass()->java_mirror();
53+
mirror->print_on(&st);
54+
ASSERT_TRUE(strstr(st.as_string(), "internal 'protection_domain'") != NULL) << "Must contain internal fields";
55+
// We should test other printing functions too.
56+
st.reset();
57+
Method* method = vmClasses::ClassLoader_klass()->methods()->at(0); // we know there's a method here!
58+
method->print_on(&st);
59+
ASSERT_TRUE(strstr(st.as_string(), "method holder:") != NULL) << "Must contain method_holder field";
60+
ASSERT_TRUE(strstr(st.as_string(), "'java/lang/ClassLoader'") != NULL) << "Must be in ClassLoader";
61+
}

0 commit comments

Comments
 (0)
Please sign in to comment.