8318563: GetClassFields should not use random access to field
Reviewed-by: sspitsyn, cjplummer, fparain
This commit is contained in:
parent
9e9c05f0ee
commit
84cf4cb350
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -2896,26 +2896,20 @@ JvmtiEnv::GetClassFields(oop k_mirror, jint* field_count_ptr, jfieldID** fields_
|
|||||||
return JVMTI_ERROR_NONE;
|
return JVMTI_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
InstanceKlass* ik = InstanceKlass::cast(k);
|
||||||
|
|
||||||
int result_count = 0;
|
FilteredJavaFieldStream flds(ik);
|
||||||
// First, count the fields.
|
|
||||||
FilteredFieldStream flds(ik, true, true);
|
|
||||||
result_count = flds.field_count();
|
|
||||||
|
|
||||||
// Allocate the result and fill it in
|
int result_count = flds.field_count();
|
||||||
jfieldID* result_list = (jfieldID*) jvmtiMalloc(result_count * sizeof(jfieldID));
|
|
||||||
// The JVMTI spec requires fields in the order they occur in the class file,
|
|
||||||
// this is the reverse order of what FieldStream hands out.
|
|
||||||
int id_index = (result_count - 1);
|
|
||||||
|
|
||||||
for (FilteredFieldStream src_st(ik, true, true); !src_st.eos(); src_st.next()) {
|
// Allocate the result and fill it in.
|
||||||
result_list[id_index--] = jfieldIDWorkaround::to_jfieldID(
|
jfieldID* result_list = (jfieldID*)jvmtiMalloc(result_count * sizeof(jfieldID));
|
||||||
ik, src_st.offset(),
|
for (int i = 0; i < result_count; i++, flds.next()) {
|
||||||
src_st.access_flags().is_static());
|
result_list[i] = jfieldIDWorkaround::to_jfieldID(ik, flds.offset(),
|
||||||
|
flds.access_flags().is_static());
|
||||||
}
|
}
|
||||||
assert(id_index == -1, "just checking");
|
assert(flds.done(), "just checking");
|
||||||
|
|
||||||
// Fill in the results
|
// Fill in the results
|
||||||
*field_count_ptr = result_count;
|
*field_count_ptr = result_count;
|
||||||
*fields_ptr = result_list;
|
*fields_ptr = result_list;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#define SHARE_RUNTIME_REFLECTIONUTILS_HPP
|
#define SHARE_RUNTIME_REFLECTIONUTILS_HPP
|
||||||
|
|
||||||
#include "memory/allStatic.hpp"
|
#include "memory/allStatic.hpp"
|
||||||
|
#include "oops/fieldStreams.inline.hpp"
|
||||||
#include "oops/instanceKlass.hpp"
|
#include "oops/instanceKlass.hpp"
|
||||||
#include "oops/objArrayOop.hpp"
|
#include "oops/objArrayOop.hpp"
|
||||||
#include "oops/oopsHierarchy.hpp"
|
#include "oops/oopsHierarchy.hpp"
|
||||||
@ -237,4 +238,36 @@ class FilteredFieldStream : public FieldStream {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Iterate over Java fields filtering fields like reflection does.
|
||||||
|
class FilteredJavaFieldStream : public JavaFieldStream {
|
||||||
|
private:
|
||||||
|
InstanceKlass* _klass;
|
||||||
|
int _filtered_fields_count;
|
||||||
|
bool has_filtered_field() const { return (_filtered_fields_count > 0); }
|
||||||
|
void skip_filtered_fields() {
|
||||||
|
if (has_filtered_field()) {
|
||||||
|
while (!done() && FilteredFieldsMap::is_filtered_field((Klass*)_klass, offset())) {
|
||||||
|
JavaFieldStream::next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
FilteredJavaFieldStream(InstanceKlass* klass)
|
||||||
|
: JavaFieldStream(klass),
|
||||||
|
_klass(klass),
|
||||||
|
_filtered_fields_count(FilteredFieldsMap::filtered_fields_count(klass, true))
|
||||||
|
{
|
||||||
|
// skip filtered fields at the beginning
|
||||||
|
skip_filtered_fields();
|
||||||
|
}
|
||||||
|
int field_count() const {
|
||||||
|
return _klass->java_fields_count() - _filtered_fields_count;
|
||||||
|
}
|
||||||
|
void next() {
|
||||||
|
JavaFieldStream::next();
|
||||||
|
skip_filtered_fields();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // SHARE_RUNTIME_REFLECTIONUTILS_HPP
|
#endif // SHARE_RUNTIME_REFLECTIONUTILS_HPP
|
||||||
|
Loading…
Reference in New Issue
Block a user