Skip to content

Commit 0d105b2

Browse files
committed
[GR-53530] Make static fields base support layer aware.
PullRequest: graal/20018
2 parents dd67f65 + fa6021c commit 0d105b2

32 files changed

+559
-248
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/StaticFieldsSupport.java

Lines changed: 214 additions & 76 deletions
Large diffs are not rendered by default.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateSegfaultHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.oracle.svm.core.heap.RestrictHeapAccess;
5858
import com.oracle.svm.core.heap.UnknownPrimitiveField;
5959
import com.oracle.svm.core.jdk.RuntimeSupport;
60+
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
6061
import com.oracle.svm.core.log.Log;
6162
import com.oracle.svm.core.option.RuntimeOptionKey;
6263
import com.oracle.svm.core.stack.StackOverflowCheck;
@@ -223,7 +224,8 @@ private static boolean isValid(Isolate isolate) {
223224
* value as an extra sanity check. Note that the heap base register still contains an
224225
* invalid value when we execute this code, which makes things a bit more complex.
225226
*/
226-
UnsignedWord staticFieldsOffsets = ReferenceAccess.singleton().getCompressedRepresentation(StaticFieldsSupport.getStaticPrimitiveFields());
227+
UnsignedWord staticFieldsOffsets = ReferenceAccess.singleton()
228+
.getCompressedRepresentation(StaticFieldsSupport.getStaticPrimitiveFieldsAtRuntime(MultiLayeredImageSingleton.UNKNOWN_LAYER_NUMBER));
227229
UnsignedWord wellKnownFieldOffset = staticFieldsOffsets.shiftLeft(ReferenceAccess.singleton().getCompressionShift()).add(Word.unsigned(offsetOfStaticFieldWithWellKnownValue));
228230
Pointer wellKnownField = ((Pointer) isolate).add(wellKnownFieldOffset);
229231
return wellKnownField.readLong(0) == MARKER_VALUE;
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package com.oracle.svm.hosted.imagelayer;
25+
package com.oracle.svm.core.fieldvaluetransformer;
2626

2727
import java.util.function.Function;
2828

29-
import com.oracle.svm.core.fieldvaluetransformer.FieldValueTransformerWithAvailability;
3029
import com.oracle.svm.core.util.VMError;
3130

3231
import jdk.vm.ci.meta.JavaConstant;
32+
import jdk.vm.ci.meta.ResolvedJavaField;
3333

3434
/**
3535
* Special field value transformer which, instead of returning an object, returns an
3636
* {@link JavaConstant} of the transformed value.
3737
*/
3838
public interface ObjectToConstantFieldValueTransformer extends FieldValueTransformerWithAvailability {
3939

40-
JavaConstant transformToConstant(Object receiver, Object originalValue, Function<Object, JavaConstant> toConstant);
40+
JavaConstant transformToConstant(ResolvedJavaField field, Object receiver, Object originalValue, Function<Object, JavaConstant> toConstant);
4141

4242
@Override
4343
default Object transform(Object receiver, Object originalValue) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/fieldvaluetransformer/StaticFieldBaseFieldValueTransformer.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package com.oracle.svm.core.fieldvaluetransformer;
2626

2727
import java.lang.reflect.Field;
28+
import java.util.function.Function;
2829

2930
import com.oracle.svm.core.BuildPhaseProvider;
3031
import com.oracle.svm.core.StaticFieldsSupport;
@@ -33,24 +34,25 @@
3334
import jdk.graal.compiler.nodes.ValueNode;
3435
import jdk.graal.compiler.nodes.spi.CoreProviders;
3536
import jdk.vm.ci.meta.JavaConstant;
37+
import jdk.vm.ci.meta.ResolvedJavaField;
3638

3739
/**
3840
* Implements the field value transformation semantics of {@link Kind#StaticFieldBase}.
3941
*/
40-
public record StaticFieldBaseFieldValueTransformer(Field targetField) implements FieldValueTransformerWithAvailability {
42+
public record StaticFieldBaseFieldValueTransformer(Field targetField) implements ObjectToConstantFieldValueTransformer {
4143

4244
@Override
4345
public boolean isAvailable() {
4446
return BuildPhaseProvider.isHostedUniverseBuilt();
4547
}
4648

4749
@Override
48-
public Object transform(Object receiver, Object originalValue) {
49-
return targetField.getType().isPrimitive() ? StaticFieldsSupport.getStaticPrimitiveFields() : StaticFieldsSupport.getStaticObjectFields();
50+
public JavaConstant transformToConstant(ResolvedJavaField field, Object receiver, Object originalValue, Function<Object, JavaConstant> toConstant) {
51+
return StaticFieldsSupport.getStaticFieldsConstant(field, toConstant);
5052
}
5153

5254
@Override
5355
public ValueNode intrinsify(CoreProviders providers, JavaConstant receiver) {
54-
return StaticFieldsSupport.createStaticFieldBaseNode(targetField.getType().isPrimitive());
56+
return StaticFieldsSupport.createStaticFieldBaseNode(providers.getMetaAccess().lookupJavaField(targetField));
5557
}
5658
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpWriter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
import com.oracle.svm.core.heap.dump.HeapDumpMetadata.FieldNameAccess;
7272
import com.oracle.svm.core.hub.DynamicHub;
7373
import com.oracle.svm.core.hub.LayoutEncoding;
74+
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
7475
import com.oracle.svm.core.log.Log;
7576
import com.oracle.svm.core.nmt.NmtCategory;
7677
import com.oracle.svm.core.os.BufferedFileOperationSupport;
@@ -686,9 +687,9 @@ private void writeFieldDescriptors(int fieldCount, FieldInfoPointer fieldInfos,
686687

687688
private static Object getStaticFieldDataHolder(HProfType type) {
688689
if (type == HProfType.NORMAL_OBJECT) {
689-
return StaticFieldsSupport.getStaticObjectFields();
690+
return StaticFieldsSupport.getStaticObjectFieldsAtRuntime(MultiLayeredImageSingleton.UNKNOWN_LAYER_NUMBER);
690691
} else {
691-
return StaticFieldsSupport.getStaticPrimitiveFields();
692+
return StaticFieldsSupport.getStaticPrimitiveFieldsAtRuntime(MultiLayeredImageSingleton.UNKNOWN_LAYER_NUMBER);
692693
}
693694
}
694695

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/imagelayer/DynamicImageLayerInfo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@
2525
package com.oracle.svm.core.imagelayer;
2626

2727
import org.graalvm.nativeimage.ImageSingletons;
28+
import org.graalvm.nativeimage.Platform;
29+
import org.graalvm.nativeimage.Platforms;
2830

2931
import com.oracle.svm.core.graal.code.CGlobalDataInfo;
3032
import com.oracle.svm.core.meta.SharedMethod;
3133

34+
@Platforms(Platform.HOSTED_ONLY.class)
3235
public abstract class DynamicImageLayerInfo {
3336
public static final int CREMA_LAYER_ID = Byte.MAX_VALUE;
3437

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.graalvm.nativeimage.impl.InternalPlatform;
4141
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
4242

43-
import com.oracle.svm.core.StaticFieldsSupport;
4443
import com.oracle.svm.core.SubstrateUtil;
4544
import com.oracle.svm.core.annotate.Alias;
4645
import com.oracle.svm.core.annotate.InjectAccessors;
@@ -259,18 +258,6 @@ public static int getCommonPoolParallelism() {
259258
return ForkJoinPoolCommonAccessor.get().getParallelism();
260259
}
261260

262-
@Alias //
263-
private static Unsafe U;
264-
265-
@Alias //
266-
private static long POOLIDS;
267-
268-
@Substitute
269-
private static int getAndAddPoolIds(int x) {
270-
// Original method wrongly uses ForkJoinPool.class instead of calling U.staticFieldBase()
271-
return U.getAndAddInt(StaticFieldsSupport.getStaticPrimitiveFields(), POOLIDS, x);
272-
}
273-
274261
@Alias //
275262
Target_java_util_concurrent_ForkJoinPool(byte forCommonPoolOnly) {
276263
}

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
package com.oracle.svm.core.jdk;
2626

27+
import java.util.function.Function;
28+
2729
import org.graalvm.nativeimage.ImageSingletons;
2830

2931
import com.oracle.svm.core.BuildPhaseProvider;
@@ -35,6 +37,7 @@
3537
import com.oracle.svm.core.annotate.TargetClass;
3638
import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode;
3739
import com.oracle.svm.core.fieldvaluetransformer.FieldValueTransformerWithAvailability;
40+
import com.oracle.svm.core.fieldvaluetransformer.ObjectToConstantFieldValueTransformer;
3841
import com.oracle.svm.core.graal.nodes.FieldOffsetNode;
3942
import com.oracle.svm.core.util.VMError;
4043

@@ -109,17 +112,17 @@ class VarHandleFieldOffsetAsLongComputer extends VarHandleFieldOffsetComputer {
109112
}
110113
}
111114

112-
class VarHandleStaticBaseComputer implements FieldValueTransformerWithAvailability {
115+
class VarHandleStaticBaseComputer implements ObjectToConstantFieldValueTransformer {
113116
@Override
114117
public boolean isAvailable() {
115118
return BuildPhaseProvider.isHostedUniverseBuilt();
116119
}
117120

118121
@Override
119-
public Object transform(Object receiver, Object originalValue) {
120-
ResolvedJavaField field = VarHandleSupport.singleton().findVarHandleField(receiver, false);
121-
StaticFieldsSupport.StaticFieldValidator.checkFieldOffsetAllowed(field);
122-
return field.getType().getJavaKind().isPrimitive() ? StaticFieldsSupport.getStaticPrimitiveFields() : StaticFieldsSupport.getStaticObjectFields();
122+
public JavaConstant transformToConstant(ResolvedJavaField field, Object receiver, Object originalValue, Function<Object, JavaConstant> toConstant) {
123+
ResolvedJavaField varHandleField = VarHandleSupport.singleton().findVarHandleField(receiver, false);
124+
StaticFieldsSupport.StaticFieldValidator.checkFieldOffsetAllowed(varHandleField);
125+
return StaticFieldsSupport.getStaticFieldsConstant(varHandleField, toConstant);
123126
}
124127

125128
@Override
@@ -128,7 +131,7 @@ public ValueNode intrinsify(CoreProviders providers, JavaConstant receiver) {
128131
if (varHandle != null) {
129132
ResolvedJavaField field = VarHandleSupport.singleton().findVarHandleField(varHandle, false);
130133
StaticFieldsSupport.StaticFieldValidator.checkFieldOffsetAllowed(field);
131-
return StaticFieldsSupport.createStaticFieldBaseNode(field.getType().getJavaKind().isPrimitive());
134+
return StaticFieldsSupport.createStaticFieldBaseNode(field);
132135
}
133136
return null;
134137
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/access/JNIAccessibleField.java

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

2727
import java.lang.reflect.Modifier;
2828

29-
import jdk.graal.compiler.word.Word;
3029
import org.graalvm.collections.EconomicSet;
3130
import org.graalvm.nativeimage.Platform.HOSTED_ONLY;
3231
import org.graalvm.nativeimage.Platforms;
@@ -37,8 +36,12 @@
3736
import com.oracle.svm.core.StaticFieldsSupport;
3837
import com.oracle.svm.core.Uninterruptible;
3938
import com.oracle.svm.core.heap.UnknownPrimitiveField;
39+
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
4040
import com.oracle.svm.core.jni.headers.JNIFieldId;
41+
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
42+
import com.oracle.svm.core.util.VMError;
4143

44+
import jdk.graal.compiler.word.Word;
4245
import jdk.vm.ci.meta.JavaKind;
4346

4447
/**
@@ -51,8 +54,11 @@ public final class JNIAccessibleField extends JNIAccessibleMember {
5154
private static final UnsignedWord ID_OBJECT_FLAG = ID_STATIC_FLAG.unsignedShiftRight(1);
5255
/* 00100000...0 */
5356
private static final UnsignedWord ID_NEGATIVE_FLAG = ID_OBJECT_FLAG.unsignedShiftRight(1);
54-
/* 00111111...1 */
55-
private static final UnsignedWord ID_OFFSET_MASK = ID_NEGATIVE_FLAG.subtract(1);
57+
/* 00010000...0 */
58+
private static final UnsignedWord ID_LAYER_NUMBER_MASK = ID_NEGATIVE_FLAG.unsignedShiftRight(1);
59+
private static final int ID_LAYER_NUMBER_SHIFT = 60;
60+
/* 00001111...1 */
61+
private static final UnsignedWord ID_OFFSET_MASK = ID_LAYER_NUMBER_MASK.subtract(1);
5662

5763
public static JNIAccessibleField negativeFieldQuery(JNIAccessibleClass jniClass) {
5864
return new JNIAccessibleField(jniClass, null, 0);
@@ -62,8 +68,8 @@ public static JNIAccessibleField negativeFieldQuery(JNIAccessibleClass jniClass)
6268
* For instance fields, the offset of the field in an object of the
6369
* {@linkplain JNIAccessibleMember#getDeclaringClass() declaring class}. For static fields,
6470
* depending on the field's type, the offset of the field in either
65-
* {@link StaticFieldsSupport#getStaticPrimitiveFields()} or
66-
* {@link StaticFieldsSupport#getStaticObjectFields()}.
71+
* {@link StaticFieldsSupport#getStaticPrimitiveFieldsAtRuntime} or
72+
* {@link StaticFieldsSupport#getStaticObjectFieldsAtRuntime}.
6773
*/
6874
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
6975
public static WordBase getOffsetFromId(JNIFieldId id) {
@@ -72,6 +78,27 @@ public static WordBase getOffsetFromId(JNIFieldId id) {
7278
return result;
7379
}
7480

81+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
82+
public static Object getStaticObjectFieldsAtRuntime(JNIFieldId fieldId) {
83+
int layerNumber = getLayerNumberFromId((UnsignedWord) fieldId);
84+
return StaticFieldsSupport.getStaticObjectFieldsAtRuntime(layerNumber);
85+
}
86+
87+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
88+
public static Object getStaticPrimitiveFieldsAtRuntime(JNIFieldId fieldId) {
89+
int layerNumber = getLayerNumberFromId((UnsignedWord) fieldId);
90+
return StaticFieldsSupport.getStaticPrimitiveFieldsAtRuntime(layerNumber);
91+
}
92+
93+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
94+
private static int getLayerNumberFromId(UnsignedWord id) {
95+
if (ImageLayerBuildingSupport.buildingImageLayer()) {
96+
return (int) id.and(ID_LAYER_NUMBER_MASK).unsignedShiftRight(ID_LAYER_NUMBER_SHIFT).rawValue();
97+
} else {
98+
return MultiLayeredImageSingleton.UNUSED_LAYER_NUMBER;
99+
}
100+
}
101+
75102
@Platforms(HOSTED_ONLY.class) private final UnsignedWord flags;
76103

77104
/**
@@ -121,11 +148,17 @@ public boolean isNegative() {
121148
}
122149

123150
@Platforms(HOSTED_ONLY.class)
124-
public void finishBeforeCompilation(int offset, EconomicSet<Class<?>> hidingSubclasses) {
151+
public void finishBeforeCompilation(int offset, int layerNumber, EconomicSet<Class<?>> hidingSubclasses) {
125152
assert id.equal(0);
126153
assert isNegativeHosted() || ID_OFFSET_MASK.and(offset).equal(offset) : "Offset is too large to be encoded in the JNIAccessibleField ID";
127154

128155
id = isNegativeHosted() ? flags : flags.or(offset);
156+
if (layerNumber == 1 || layerNumber == 0) {
157+
id = id.or(Word.unsigned(layerNumber).shiftLeft(ID_LAYER_NUMBER_SHIFT));
158+
VMError.guarantee(getLayerNumberFromId(id) == layerNumber);
159+
} else {
160+
assert layerNumber == MultiLayeredImageSingleton.UNUSED_LAYER_NUMBER;
161+
}
129162
setHidingSubclasses(hidingSubclasses);
130163
}
131164
}

0 commit comments

Comments
 (0)