mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8302260: VarHandle.describeConstable() fails to return a nominal descriptor for static public fields
Reviewed-by: alanb, psandoz
This commit is contained in:
parent
ca73f7e80f
commit
9c202a5a8f
7 changed files with 254 additions and 39 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
|
@ -114,52 +114,53 @@ final class VarHandles {
|
|||
if (UNSAFE.shouldBeInitialized(refc))
|
||||
UNSAFE.ensureClassInitialized(refc);
|
||||
|
||||
Class<?> decl = f.getDeclaringClass();
|
||||
Object base = MethodHandleNatives.staticFieldBase(f);
|
||||
long foffset = MethodHandleNatives.staticFieldOffset(f);
|
||||
if (!type.isPrimitive()) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleReferences.FieldStaticReadOnly(refc, base, foffset, type)
|
||||
: new VarHandleReferences.FieldStaticReadWrite(refc, base, foffset, type));
|
||||
? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type)
|
||||
: new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type));
|
||||
}
|
||||
else if (type == boolean.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleBooleans.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleBooleans.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == byte.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleBytes.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleBytes.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == short.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleShorts.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleShorts.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == char.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleChars.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleChars.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == int.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleInts.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleInts.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleInts.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleInts.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == long.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleLongs.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleLongs.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleLongs.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleLongs.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == float.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleFloats.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleFloats.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleFloats.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleFloats.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else if (type == double.class) {
|
||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||
? new VarHandleDoubles.FieldStaticReadOnly(refc, base, foffset)
|
||||
: new VarHandleDoubles.FieldStaticReadWrite(refc, base, foffset));
|
||||
? new VarHandleDoubles.FieldStaticReadOnly(decl, base, foffset)
|
||||
: new VarHandleDoubles.FieldStaticReadWrite(decl, base, foffset));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
|
@ -183,10 +184,10 @@ final class VarHandles {
|
|||
}
|
||||
|
||||
// Required by instance static field handles
|
||||
static Field getStaticFieldFromBaseAndOffset(Class<?> receiverType,
|
||||
static Field getStaticFieldFromBaseAndOffset(Class<?> declaringClass,
|
||||
long offset,
|
||||
Class<?> fieldType) {
|
||||
for (Field f : receiverType.getDeclaredFields()) {
|
||||
for (Field f : declaringClass.getDeclaredFields()) {
|
||||
if (!Modifier.isStatic(f.getModifiers())) continue;
|
||||
|
||||
if (offset == UNSAFE.staticFieldOffset(f)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -382,21 +382,21 @@ final class VarHandle$Type$s {
|
|||
|
||||
|
||||
static sealed class FieldStaticReadOnly extends VarHandle {
|
||||
final Class<?> receiverType;
|
||||
final Class<?> declaringClass;
|
||||
final Object base;
|
||||
final long fieldOffset;
|
||||
#if[Object]
|
||||
final Class<?> fieldType;
|
||||
#end[Object]
|
||||
|
||||
FieldStaticReadOnly(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||
this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
|
||||
FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||
this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
|
||||
}
|
||||
|
||||
protected FieldStaticReadOnly(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||
protected FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||
VarForm form, boolean exact) {
|
||||
super(form, exact);
|
||||
this.receiverType = receiverType;
|
||||
this.declaringClass = declaringClass;
|
||||
this.base = base;
|
||||
this.fieldOffset = fieldOffset;
|
||||
#if[Object]
|
||||
|
@ -408,14 +408,14 @@ final class VarHandle$Type$s {
|
|||
public FieldStaticReadOnly withInvokeExactBehavior() {
|
||||
return hasInvokeExactBehavior()
|
||||
? this
|
||||
: new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, true);
|
||||
: new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldStaticReadOnly withInvokeBehavior() {
|
||||
return !hasInvokeExactBehavior()
|
||||
? this
|
||||
: new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, false);
|
||||
: new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -426,11 +426,11 @@ final class VarHandle$Type$s {
|
|||
|
||||
// Reflect on this VarHandle to extract the field name
|
||||
var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
|
||||
receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class});
|
||||
var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
|
||||
if (!receiverTypeRef.isPresent())
|
||||
declaringClass, fieldOffset, {#if[Object]?fieldType:$type$.class});
|
||||
var declaringTypeRef = declaringClass.describeConstable();
|
||||
if (!declaringTypeRef.isPresent())
|
||||
return Optional.empty();
|
||||
return Optional.of(VarHandleDesc.ofStaticField(receiverTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
|
||||
return Optional.of(VarHandleDesc.ofStaticField(declaringTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -471,27 +471,27 @@ final class VarHandle$Type$s {
|
|||
|
||||
static final class FieldStaticReadWrite extends FieldStaticReadOnly {
|
||||
|
||||
FieldStaticReadWrite(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||
this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||
FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||
this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||
}
|
||||
|
||||
private FieldStaticReadWrite(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||
private FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||
boolean exact) {
|
||||
super(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
|
||||
super(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldStaticReadWrite withInvokeExactBehavior() {
|
||||
return hasInvokeExactBehavior()
|
||||
? this
|
||||
: new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, true);
|
||||
: new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldStaticReadWrite withInvokeBehavior() {
|
||||
return !hasInvokeExactBehavior()
|
||||
? this
|
||||
: new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||
: new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue