Skip to content

Commit

Permalink
8318626: GetClassFields does not filter out ConstantPool.constantPool…
Browse files Browse the repository at this point in the history
…Oop field

Reviewed-by: sspitsyn, lmesnik
  • Loading branch information
Alex Menkov committed Nov 29, 2023
1 parent ea6e92e commit d1e73b1
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/hotspot/share/runtime/reflectionUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,20 +214,26 @@ class FilteredFieldStream : public FieldStream {
private:
int _filtered_fields_count;
bool has_filtered_field() { return (_filtered_fields_count > 0); }
void skip_filtered_fields() {
if (has_filtered_field()) {
while (_index >= 0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass, offset())) {
_index -= 1;
}
}
}

public:
FilteredFieldStream(InstanceKlass* klass, bool local_only, bool classes_only)
: FieldStream(klass, local_only, classes_only) {
_filtered_fields_count = FilteredFieldsMap::filtered_fields_count(klass, local_only);
// skip filtered fields at the end
skip_filtered_fields();

}
int field_count();
void next() {
_index -= 1;
if (has_filtered_field()) {
while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass, offset())) {
_index -= 1;
}
}
skip_filtered_fields();
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 8318626
* @summary Verifies JVMTI GetClassFields function filters out fields
* the same way Class.getDeclaredFields() does.
*
* @run main/othervm/native -agentlib:FilteredFieldsTest FilteredFieldsTest
*/

import java.lang.reflect.Field;

public class FilteredFieldsTest {

static {
System.loadLibrary("FilteredFieldsTest");
}

private native static int getJVMTIFieldCount(Class cls);

private static int getDeclaredFieldsCount(Class cls) {
Field[] declaredFields = cls.getDeclaredFields();
System.out.println("Class.getDeclaredFields reported " + declaredFields.length + " fields:");
for (int i = 0; i < declaredFields.length; i++) {
System.out.println(" [" + i + "] : " + declaredFields[i]);
}
return declaredFields.length;
}

public static void main(String args[]) throws Exception {
Class cls = Class.forName("jdk.internal.reflect.ConstantPool");
int declaredCount = getDeclaredFieldsCount(cls);
int jvmtiCount = getJVMTIFieldCount(cls);
if (declaredCount != jvmtiCount) {
throw new Exception("declaredCount != jvmtiCount: " + declaredCount + " != " + jvmtiCount);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#include <stdio.h>
#include <string.h>
#include "jvmti.h"
#include "jvmti_common.h"

extern "C" {

static jvmtiEnv *jvmti = NULL;


jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
jint res = jvm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_1);
if (res != JNI_OK || jvmti == NULL) {
printf("Wrong result of a valid call to GetEnv!\n");
fflush(0);
return JNI_ERR;
}
return JNI_OK;
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
return Agent_Initialize(jvm, options, reserved);
}
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
return Agent_Initialize(jvm, options, reserved);
}


JNIEXPORT jint JNICALL
Java_FilteredFieldsTest_getJVMTIFieldCount(JNIEnv *env, jclass cls, jclass clazz) {
if (jvmti == NULL) {
env->FatalError("JVMTI agent was not properly loaded");
}

jint fcount = 0;
jfieldID *fields = nullptr;

check_jvmti_status(env, jvmti->GetClassFields(clazz, &fcount, &fields), "GetClassFields failed");

printf("GetClassFields returned %d fields:\n", (int)fcount);
for (int i = 0; i < fcount; i++) {
char *name;
jvmtiError err = jvmti->GetFieldName(clazz, fields[i], &name, nullptr, nullptr);
if (err != JVMTI_ERROR_NONE) {
printf("GetFieldName(%d) returned error: %s (%d)\n",
i, TranslateError(err), err);
continue;
}
printf(" [%d]: %s\n", i, name);
jvmti->Deallocate((unsigned char *)name);
}
fflush(0);
return fcount;
}

}

1 comment on commit d1e73b1

@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.