mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8372002: VarHandle for receiver's superclass instance fields fails describeConstable
Reviewed-by: psandoz, jvernee
This commit is contained in:
parent
b6d83eda6b
commit
1f99cf9424
@ -166,12 +166,15 @@ final class VarHandles {
|
||||
static Field getFieldFromReceiverAndOffset(Class<?> receiverType,
|
||||
long offset,
|
||||
Class<?> fieldType) {
|
||||
for (Field f : receiverType.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) continue;
|
||||
// The receiver may be a referenced class different from the declaring class
|
||||
for (var declaringClass = receiverType; declaringClass != null; declaringClass = declaringClass.getSuperclass()) {
|
||||
for (Field f : declaringClass.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) continue;
|
||||
|
||||
if (offset == UNSAFE.objectFieldOffset(f)) {
|
||||
assert f.getType() == fieldType;
|
||||
return f;
|
||||
if (offset == UNSAFE.objectFieldOffset(f)) {
|
||||
assert f.getType() == fieldType;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new InternalError("Field not found at offset");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, 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
|
||||
@ -21,18 +21,16 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
/*
|
||||
* @test
|
||||
* @bug 8302260
|
||||
* @bug 8302260 8372002
|
||||
* @build p.C p.D p.I p.q.Q
|
||||
* @run junit DescribeConstableTest
|
||||
* @summary Test VarHandle::describeConstable on static fields
|
||||
*/
|
||||
|
||||
import java.lang.constant.ClassDesc;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.invoke.VarHandle.VarHandleDesc;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -43,7 +41,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class DescribeConstableTest {
|
||||
private static final Lookup LOOKUP = MethodHandles.lookup();
|
||||
private static Stream<Arguments> testCases() {
|
||||
private static Stream<Arguments> staticTestCases() {
|
||||
return Stream.of(
|
||||
// static field defined in p.C only
|
||||
Arguments.of(p.C.class, "cString", String.class, p.C.class, "CClass"),
|
||||
@ -68,8 +66,8 @@ public class DescribeConstableTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("testCases")
|
||||
void test(Class<?> refc, String name, Class<?> type, Class<?> declaringClass, Object value) throws Throwable {
|
||||
@MethodSource("staticTestCases")
|
||||
void testStatic(Class<?> refc, String name, Class<?> type, Class<?> declaringClass, Object value) throws Throwable {
|
||||
var vh = LOOKUP.findStaticVarHandle(refc, name, type);
|
||||
assertEquals(value, vh.get());
|
||||
|
||||
@ -84,6 +82,37 @@ public class DescribeConstableTest {
|
||||
assertEquals(vhd.toString(), varHandleDescString(declaringClass, name, type, true));
|
||||
}
|
||||
|
||||
private static Arguments[] instanceTestCases() {
|
||||
return new Arguments[] {
|
||||
// Basic instance field in p.q.Q
|
||||
Arguments.of(p.q.Q.class, "instanceIntField", int.class, new p.q.Q(), 42),
|
||||
// p.C.instanceIntField hides the superclass instanceIntField, but it still exists
|
||||
Arguments.of(p.C.class, "instanceIntField", int.class, new p.C(), 76),
|
||||
Arguments.of(p.q.Q.class, "instanceIntField", int.class, new p.C(), 42),
|
||||
// p.D.instanceIntField points to that of p.q.Q
|
||||
Arguments.of(p.D.class, "instanceIntField", int.class, new p.D(), 42),
|
||||
};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("instanceTestCases")
|
||||
void testInstance(Class<?> refc, String name, Class<?> type, Object instance, Object value) throws Throwable {
|
||||
var vh = LOOKUP.findVarHandle(refc, name, type).withInvokeBehavior();
|
||||
assertEquals(value, vh.get(instance));
|
||||
|
||||
var refcDesc = refc.describeConstable().orElseThrow();
|
||||
var typeDesc = type.describeConstable().orElseThrow();
|
||||
var vhd = vh.describeConstable().orElseThrow();
|
||||
var vhd2 = VarHandleDesc.ofField(refcDesc, name, typeDesc);
|
||||
|
||||
assertEquals(value, vhd.resolveConstantDesc(LOOKUP).get(instance));
|
||||
assertEquals(value, vhd2.resolveConstantDesc(LOOKUP).get(instance));
|
||||
|
||||
// The string does not use the declaring class because
|
||||
// receiver is restricted on the handle
|
||||
assertEquals(vhd.toString(), varHandleDescString(refc, name, type, false));
|
||||
}
|
||||
|
||||
static String varHandleDescString(Class<?> declaringClass, String name, Class<?> type, boolean staticField) {
|
||||
return String.format("VarHandleDesc[%s%s.%s:%s]",
|
||||
staticField ? "static " : "",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, 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
|
||||
@ -25,4 +25,6 @@ package p;
|
||||
|
||||
public class C extends p.q.Q implements I {
|
||||
public static String cString = "CClass";
|
||||
|
||||
public int instanceIntField = 76; // Hides the field from Q
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, 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
|
||||
@ -29,4 +29,6 @@ public class Q {
|
||||
|
||||
public static String stringField2 = "QClass2";
|
||||
public static long longField2 = 102L;
|
||||
|
||||
public int instanceIntField = 42;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user