From facd41511b972e940ecab3bc57f5f23efca43343 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Fri, 20 Jan 2023 17:25:18 +0000 Subject: [PATCH] 8297757: VarHandles.getStaticFieldFromBaseAndOffset should get the receiver type from VarHandle Reviewed-by: psandoz, alanb --- .../classes/java/lang/invoke/VarHandles.java | 40 +++++++++---------- .../lang/invoke/X-VarHandle.java.template | 26 ++++++------ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandles.java b/src/java.base/share/classes/java/lang/invoke/VarHandles.java index 7d1c150c12a..c15136ced44 100644 --- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java @@ -118,48 +118,48 @@ final class VarHandles { long foffset = MethodHandleNatives.staticFieldOffset(f); if (!type.isPrimitive()) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type) - : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type)); + ? new VarHandleReferences.FieldStaticReadOnly(refc, base, foffset, type) + : new VarHandleReferences.FieldStaticReadWrite(refc, base, foffset, type)); } else if (type == boolean.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset) - : new VarHandleBooleans.FieldStaticReadWrite(base, foffset)); + ? new VarHandleBooleans.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleBooleans.FieldStaticReadWrite(refc, base, foffset)); } else if (type == byte.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleBytes.FieldStaticReadOnly(base, foffset) - : new VarHandleBytes.FieldStaticReadWrite(base, foffset)); + ? new VarHandleBytes.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleBytes.FieldStaticReadWrite(refc, base, foffset)); } else if (type == short.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleShorts.FieldStaticReadOnly(base, foffset) - : new VarHandleShorts.FieldStaticReadWrite(base, foffset)); + ? new VarHandleShorts.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleShorts.FieldStaticReadWrite(refc, base, foffset)); } else if (type == char.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleChars.FieldStaticReadOnly(base, foffset) - : new VarHandleChars.FieldStaticReadWrite(base, foffset)); + ? new VarHandleChars.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleChars.FieldStaticReadWrite(refc, base, foffset)); } else if (type == int.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleInts.FieldStaticReadOnly(base, foffset) - : new VarHandleInts.FieldStaticReadWrite(base, foffset)); + ? new VarHandleInts.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleInts.FieldStaticReadWrite(refc, base, foffset)); } else if (type == long.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleLongs.FieldStaticReadOnly(base, foffset) - : new VarHandleLongs.FieldStaticReadWrite(base, foffset)); + ? new VarHandleLongs.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleLongs.FieldStaticReadWrite(refc, base, foffset)); } else if (type == float.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleFloats.FieldStaticReadOnly(base, foffset) - : new VarHandleFloats.FieldStaticReadWrite(base, foffset)); + ? new VarHandleFloats.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleFloats.FieldStaticReadWrite(refc, base, foffset)); } else if (type == double.class) { return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields - ? new VarHandleDoubles.FieldStaticReadOnly(base, foffset) - : new VarHandleDoubles.FieldStaticReadWrite(base, foffset)); + ? new VarHandleDoubles.FieldStaticReadOnly(refc, base, foffset) + : new VarHandleDoubles.FieldStaticReadWrite(refc, base, foffset)); } else { throw new UnsupportedOperationException(); @@ -183,11 +183,9 @@ final class VarHandles { } // Required by instance static field handles - static Field getStaticFieldFromBaseAndOffset(Object base, + static Field getStaticFieldFromBaseAndOffset(Class receiverType, long offset, Class fieldType) { - // @@@ This is a little fragile assuming the base is the class - Class receiverType = (Class) base; for (Field f : receiverType.getDeclaredFields()) { if (!Modifier.isStatic(f.getModifiers())) continue; diff --git a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template index d182056f4eb..fdde3aef663 100644 --- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template +++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template @@ -382,19 +382,21 @@ final class VarHandle$Type$s { static sealed class FieldStaticReadOnly extends VarHandle { + final Class receiverType; final Object base; final long fieldOffset; #if[Object] final Class fieldType; #end[Object] - FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { - this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false); + FieldStaticReadOnly(Class receiverType, Object base, long fieldOffset{#if[Object]?, Class fieldType}) { + this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false); } - protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class fieldType}, + protected FieldStaticReadOnly(Class receiverType, Object base, long fieldOffset{#if[Object]?, Class fieldType}, VarForm form, boolean exact) { super(form, exact); + this.receiverType = receiverType; this.base = base; this.fieldOffset = fieldOffset; #if[Object] @@ -406,14 +408,14 @@ final class VarHandle$Type$s { public FieldStaticReadOnly withInvokeExactBehavior() { return hasInvokeExactBehavior() ? this - : new FieldStaticReadOnly(base, fieldOffset{#if[Object]?, fieldType}, vform, true); + : new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, true); } @Override public FieldStaticReadOnly withInvokeBehavior() { return !hasInvokeExactBehavior() ? this - : new FieldStaticReadOnly(base, fieldOffset{#if[Object]?, fieldType}, vform, false); + : new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, false); } @Override @@ -424,7 +426,7 @@ final class VarHandle$Type$s { // Reflect on this VarHandle to extract the field name var staticField = VarHandles.getStaticFieldFromBaseAndOffset( - base, fieldOffset, {#if[Object]?fieldType:$type$.class}); + receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class}); var receiverTypeRef = staticField.getDeclaringClass().describeConstable(); if (!receiverTypeRef.isPresent()) return Optional.empty(); @@ -469,27 +471,27 @@ final class VarHandle$Type$s { static final class FieldStaticReadWrite extends FieldStaticReadOnly { - FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class fieldType}) { - this(base, fieldOffset{#if[Object]?, fieldType}, false); + FieldStaticReadWrite(Class receiverType, Object base, long fieldOffset{#if[Object]?, Class fieldType}) { + this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false); } - private FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class fieldType}, + private FieldStaticReadWrite(Class receiverType, Object base, long fieldOffset{#if[Object]?, Class fieldType}, boolean exact) { - super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact); + super(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact); } @Override public FieldStaticReadWrite withInvokeExactBehavior() { return hasInvokeExactBehavior() ? this - : new FieldStaticReadWrite(base, fieldOffset{#if[Object]?, fieldType}, true); + : new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, true); } @Override public FieldStaticReadWrite withInvokeBehavior() { return !hasInvokeExactBehavior() ? this - : new FieldStaticReadWrite(base, fieldOffset{#if[Object]?, fieldType}, false); + : new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false); } @ForceInline