Skip to content

Commit 8f171d2

Browse files
committed
[GR-41268] Add automatic computation for Unsafe.staticFieldOffset() and Unsafe.staticFieldBase().
PullRequest: graal/13384
2 parents 1cfe289 + 4c6b9a9 commit 8f171d2

File tree

4 files changed

+102
-60
lines changed

4 files changed

+102
-60
lines changed

sdk/src/com.oracle.svm.core.annotate/src/com/oracle/svm/core/annotate/RecomputeFieldValue.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.lang.annotation.Retention;
4545
import java.lang.annotation.RetentionPolicy;
4646
import java.lang.annotation.Target;
47+
import java.lang.reflect.Field;
4748

4849
import org.graalvm.nativeimage.Platform;
4950
import org.graalvm.nativeimage.Platforms;
@@ -113,6 +114,13 @@ enum Kind {
113114
* @since 22.3
114115
*/
115116
FieldOffset,
117+
/**
118+
* The static field base Object as it would be computed by
119+
* {@link sun.misc.Unsafe#staticFieldBase(Field)}.
120+
*
121+
* @since 23.0
122+
*/
123+
StaticFieldBase,
116124
/**
117125
* The int or long field is set to the offset of the first array element of the array class
118126
* {@link #declClass}, as it would be computed by

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RecomputedFields.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
//Checkstyle: stop
2828

2929
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.AtomicFieldUpdaterOffset;
30-
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.FieldOffset;
3130
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.Reset;
3231

3332
import java.lang.ref.ReferenceQueue;
@@ -341,7 +340,6 @@ public static int getCommonPoolParallelism() {
341340
private static Unsafe U;
342341

343342
@Alias @TargetElement(onlyWith = JDK19OrLater.class) //
344-
@RecomputeFieldValue(kind = FieldOffset, name = "poolIds") //
345343
private static long POOLIDS;
346344

347345
@Substitute

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/ComputedValueField.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.AtomicFieldUpdaterOffset;
2828
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.FieldOffset;
29+
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.StaticFieldBase;
2930
import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind.TranslateFieldOffset;
3031
import static com.oracle.svm.core.util.VMError.guarantee;
3132
import static com.oracle.svm.core.util.VMError.shouldNotReachHere;
@@ -48,6 +49,7 @@
4849
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
4950
import com.oracle.graal.pointsto.util.GraalAccess;
5051
import com.oracle.svm.core.BuildPhaseProvider;
52+
import com.oracle.svm.core.StaticFieldsSupport;
5153
import com.oracle.svm.core.annotate.RecomputeFieldValue;
5254
import com.oracle.svm.core.config.ConfigurationValues;
5355
import com.oracle.svm.core.fieldvaluetransformer.FieldValueTransformerWithAvailability;
@@ -133,11 +135,11 @@ public ComputedValueField(ResolvedJavaField original, ResolvedJavaField annotate
133135
constantValue = JavaConstant.defaultForKind(getJavaKind());
134136
break;
135137
case FieldOffset:
136-
try {
137-
f = targetClass.getDeclaredField(targetName);
138-
} catch (NoSuchFieldException e) {
139-
throw shouldNotReachHere("could not find target field " + targetClass.getName() + "." + targetName + " for alias " + annotated.format("%H.%n"));
140-
}
138+
f = getField(annotated, targetClass, targetName);
139+
break;
140+
case StaticFieldBase:
141+
f = getField(annotated, targetClass, targetName);
142+
UserError.guarantee(Modifier.isStatic(f.getModifiers()), "Target field must be static for %s computation of %s", StaticFieldBase, fieldFormat());
141143
break;
142144
case Custom:
143145
if (initialTransformer != null) {
@@ -154,15 +156,24 @@ public ComputedValueField(ResolvedJavaField original, ResolvedJavaField annotate
154156
}
155157
}
156158
boolean isOffsetField = isOffsetRecomputation(kind);
159+
boolean isStaticFieldBase = kind == StaticFieldBase;
157160
guarantee(!isFinal || !isOffsetField);
158-
this.isValueAvailableBeforeAnalysis = customValueAvailableBeforeAnalysis && !isOffsetField;
159-
this.isValueAvailableOnlyAfterAnalysis = customValueAvailableOnlyAfterAnalysis || isOffsetField;
161+
this.isValueAvailableBeforeAnalysis = customValueAvailableBeforeAnalysis && !isOffsetField && !isStaticFieldBase;
162+
this.isValueAvailableOnlyAfterAnalysis = customValueAvailableOnlyAfterAnalysis || isOffsetField || isStaticFieldBase;
160163
this.isValueAvailableOnlyAfterCompilation = customValueAvailableOnlyAfterCompilation;
161164
this.targetField = f;
162165
this.fieldValueTransformer = transformer;
163166
this.valueCache = EconomicMap.create();
164167
}
165168

169+
private static Field getField(ResolvedJavaField annotated, Class<?> targetClass, String targetName) {
170+
try {
171+
return targetClass.getDeclaredField(targetName);
172+
} catch (NoSuchFieldException e) {
173+
throw UserError.abort("Could not find target field %s.%s for alias %s.", targetClass.getName(), targetName, annotated.format("%H.%n"));
174+
}
175+
}
176+
166177
public static boolean isOffsetRecomputation(RecomputeFieldValue.Kind kind) {
167178
return offsetComputationKinds.contains(kind);
168179
}
@@ -282,6 +293,10 @@ public JavaConstant readValue(MetaAccessProvider metaAccess, JavaConstant receiv
282293
case ArrayIndexShift:
283294
constantValue = asConstant(ConfigurationValues.getObjectLayout().getArrayIndexShift(JavaKind.fromJavaClass(targetClass.getComponentType())));
284295
return constantValue;
296+
case StaticFieldBase:
297+
Object staticFieldsArray = targetField.getType().isPrimitive() ? StaticFieldsSupport.getStaticPrimitiveFields() : StaticFieldsSupport.getStaticObjectFields();
298+
constantValue = GraalAccess.getOriginalSnippetReflection().forObject(staticFieldsArray);
299+
return constantValue;
285300
}
286301

287302
ReadLock readLock = valueCacheLock.readLock();
@@ -342,9 +357,9 @@ private JavaConstant computeValue(MetaAccessProvider metaAccess, JavaConstant re
342357
originalValue = fetchOriginalValue(metaAccess, receiver, originalSnippetReflection);
343358
Object newValue = fieldValueTransformer.transform(receiverValue, originalValue);
344359
checkValue(newValue);
345-
result = originalSnippetReflection.forBoxed(annotated.getJavaKind(), newValue);
360+
result = originalSnippetReflection.forBoxed(original.getJavaKind(), newValue);
346361

347-
assert result.getJavaKind() == annotated.getJavaKind();
362+
assert result.getJavaKind() == original.getJavaKind();
348363
break;
349364
default:
350365
throw shouldNotReachHere("Field recomputation of kind " + kind + " for " + fieldFormat() + " not yet supported");

0 commit comments

Comments
 (0)