8353175: Eliminate double iteration of stream in FieldDescriptor reinitialization

Reviewed-by: jsjolen, shade, fparain
This commit is contained in:
Radim Vansa 2025-04-14 08:18:59 +00:00 committed by Johan Sjölen
parent cf27a42d92
commit f169fc5a99
5 changed files with 20 additions and 30 deletions

View File

@ -120,7 +120,7 @@ class FieldStreamBase : public StackObj {
// Convenient methods
FieldInfo to_FieldInfo() {
const FieldInfo& to_FieldInfo() const {
return _fi_buf;
}
@ -131,7 +131,7 @@ class FieldStreamBase : public StackObj {
// bridge to a heavier API:
fieldDescriptor& field_descriptor() const {
fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
field.reinitialize(field_holder(), _index);
field.reinitialize(field_holder(), to_FieldInfo());
return field;
}
};

View File

@ -97,7 +97,6 @@
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
#include "utilities/nativeStackPrinter.hpp"
#include "utilities/pair.hpp"
#include "utilities/stringUtils.hpp"
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
@ -1785,7 +1784,7 @@ bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor*
Symbol* f_name = fs.name();
Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) {
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.to_FieldInfo());
return true;
}
}
@ -1854,7 +1853,7 @@ Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fiel
bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.offset() == offset) {
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.to_FieldInfo());
if (fd->is_static() == is_static) return true;
}
}
@ -1915,19 +1914,16 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
if (super != nullptr) {
super->do_nonstatic_fields(cl);
}
fieldDescriptor fd;
int length = java_fields_count();
for (int i = 0; i < length; i += 1) {
fd.reinitialize(this, i);
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
fieldDescriptor& fd = fs.field_descriptor();
if (!fd.is_static()) {
cl->do_field(&fd);
}
}
}
// 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;
static int compare_fields_by_offset(FieldInfo* a, FieldInfo* b) {
return a->offset() - b->offset();
}
void InstanceKlass::print_nonstatic_fields(FieldClosure* cl) {
@ -1936,25 +1932,20 @@ void InstanceKlass::print_nonstatic_fields(FieldClosure* cl) {
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;
GrowableArray<FieldInfo> fields_sorted;
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++;
fields_sorted.push(fs.to_FieldInfo());
}
}
if (i > 0) {
int length = i;
assert(length == fields_sorted.length(), "duh");
int length = fields_sorted.length();
if (length > 0) {
fields_sorted.sort(compare_fields_by_offset);
fieldDescriptor fd;
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");
fd.reinitialize(this, fields_sorted.at(i));
assert(!fd.is_static() && fd.offset() == checked_cast<int>(fields_sorted.at(i).offset()), "only nonstatic fields");
cl->do_field(&fd);
}
}

View File

@ -1588,7 +1588,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
fieldDescriptor fd;
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (!publicOnly || fs.access_flags().is_public()) {
fd.reinitialize(k, fs.index());
fd.reinitialize(k, fs.to_FieldInfo());
oop field = Reflection::new_field(&fd, CHECK_NULL);
result->obj_at_put(out_idx, field);
++out_idx;

View File

@ -86,7 +86,7 @@ oop fieldDescriptor::string_initial_value(TRAPS) const {
return constants()->uncached_string_at(initial_value_index(), THREAD);
}
void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
void fieldDescriptor::reinitialize(InstanceKlass* ik, const FieldInfo& fieldinfo) {
if (_cp.is_null() || field_holder() != ik) {
_cp = constantPoolHandle(Thread::current(), ik->constants());
// _cp should now reference ik's constant pool; i.e., ik is now field_holder.
@ -94,8 +94,7 @@ void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) {
// but that's ok because of constant pool merging.
assert(field_holder() == ik || ik->is_scratch_class(), "must be already initialized to this class");
}
_fieldinfo= ik->field(index);
assert((int)_fieldinfo.index() == index, "just checking");
_fieldinfo = fieldinfo;
guarantee(_fieldinfo.name_index() != 0 && _fieldinfo.signature_index() != 0, "bad constant pool index for fieldDescriptor");
}

View File

@ -46,7 +46,7 @@ class fieldDescriptor {
public:
fieldDescriptor() {}
fieldDescriptor(InstanceKlass* ik, int index) {
reinitialize(ik, index);
reinitialize(ik, ik->field(index));
}
inline Symbol* name() const;
inline Symbol* signature() const;
@ -102,7 +102,7 @@ class fieldDescriptor {
inline void set_has_initialized_final_update(const bool value);
// Initialization
void reinitialize(InstanceKlass* ik, int index);
void reinitialize(InstanceKlass* ik, const FieldInfo& fieldinfo);
// Print
void print() const;