Skip to content

Commit 73a626e

Browse files
committed
[GR-64193] Vector API runtime compilation support
PullRequest: graal/20544
2 parents 2dd8a27 + 4cc4b95 commit 73a626e

File tree

7 files changed

+160
-22
lines changed

7 files changed

+160
-22
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/spi/JavaConstantFieldProvider.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -174,6 +174,27 @@ protected boolean isSyntheticEnumSwitchMap(ResolvedJavaField field) {
174174
private final ResolvedJavaField stringHashField;
175175

176176
protected boolean isWellKnownImplicitStableField(ResolvedJavaField field) {
177+
if (isArray(field) && field.isFinal() && field.getName().equals("cache")) {
178+
ResolvedJavaType type = field.getDeclaringClass();
179+
String typeName = type.getName();
180+
if (typeName.equals("Ljdk/incubator/vector/VectorOperators$ImplCache;")) {
181+
return true;
182+
}
183+
}
184+
if (field.getName().equals("dummyVector")) {
185+
ResolvedJavaType type = field.getDeclaringClass();
186+
String typeName = type.getName();
187+
if (typeName.equals("Ljdk/incubator/vector/AbstractSpecies;")) {
188+
return true;
189+
}
190+
}
191+
if (field.getName().equals("asIntegral") || field.getName().equals("asFloating")) {
192+
ResolvedJavaType type = field.getDeclaringClass();
193+
String typeName = type.getName();
194+
if (typeName.equals("Ljdk/incubator/vector/LaneType;")) {
195+
return true;
196+
}
197+
}
177198
return field.equals(stringValueField);
178199
}
179200
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/MacroNode.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,11 @@
2424
*/
2525
package jdk.graal.compiler.replacements.nodes;
2626

27-
import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
2827
import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
2928
import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
29+
import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
30+
31+
import org.graalvm.word.LocationIdentity;
3032

3133
import jdk.graal.compiler.core.common.type.ObjectStamp;
3234
import jdk.graal.compiler.core.common.type.StampPair;
@@ -47,8 +49,6 @@
4749
import jdk.graal.compiler.nodes.ValueNode;
4850
import jdk.graal.compiler.nodes.graphbuilderconf.GraphBuilderContext;
4951
import jdk.graal.compiler.nodes.java.MethodCallTargetNode;
50-
import org.graalvm.word.LocationIdentity;
51-
5252
import jdk.vm.ci.meta.JavaKind;
5353
import jdk.vm.ci.meta.ResolvedJavaMethod;
5454

@@ -243,6 +243,15 @@ public final boolean hasSideEffect() {
243243
return true;
244244
}
245245

246+
/**
247+
* Returns {@code true} if the lowered version of the macro, or the fallback invoke, can
248+
* deoptimize in any way or throw any implicit or explicit exception. Such nodes should be
249+
* represented as {@link MacroWithExceptionNode} in SVM runtime compilations.
250+
*/
251+
public boolean canDeoptimizeOrThrow() {
252+
return true;
253+
}
254+
246255
/**
247256
* Returns {@link LocationIdentity#any()}. This node needs to kill any location because it might
248257
* get {@linkplain MacroInvokable#replaceWithInvoke() replaced with an invoke} and

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/FrameInfoQueryResult.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
2626

2727
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
2828

29-
import jdk.graal.compiler.word.Word;
3029
import org.graalvm.nativeimage.c.function.CodePointer;
3130

3231
import com.oracle.svm.core.CalleeSavedRegisters;
@@ -40,6 +39,7 @@
4039

4140
import jdk.graal.compiler.core.common.SuppressFBWarnings;
4241
import jdk.graal.compiler.nodes.FrameState;
42+
import jdk.graal.compiler.word.Word;
4343
import jdk.vm.ci.code.Register;
4444
import jdk.vm.ci.code.StackSlot;
4545
import jdk.vm.ci.code.VirtualObject;
@@ -105,7 +105,7 @@ public enum ValueType {
105105
}
106106
}
107107

108-
public static class ValueInfo {
108+
public static final class ValueInfo {
109109
protected ValueType type;
110110
protected JavaKind kind;
111111
protected boolean isCompressedReference; // for JavaKind.Object
@@ -159,6 +159,23 @@ public long getData() {
159159
public JavaConstant getValue() {
160160
return value;
161161
}
162+
163+
/**
164+
* Copy {@code this} value info, with all fields unchanged except for the {@link #getKind()}
165+
* replaced by the given {@code kind} and the {@link #getData()} adjusted (not replaced!) by
166+
* the given {@code offset}. This is used to access element information for special compound
167+
* objects like Vector API values.
168+
*/
169+
public ValueInfo copyForElement(JavaKind javaKind, int offset) {
170+
ValueInfo copy = new ValueInfo();
171+
copy.type = type;
172+
copy.kind = javaKind;
173+
copy.isCompressedReference = isCompressedReference;
174+
copy.isEliminatedMonitor = isEliminatedMonitor;
175+
copy.data = data + offset;
176+
copy.value = value;
177+
return copy;
178+
}
162179
}
163180

164181
protected FrameInfoQueryResult caller;

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/DeoptState.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,17 @@
2424
*/
2525
package com.oracle.svm.core.deopt;
2626

27+
import static com.oracle.svm.core.deopt.Deoptimizer.fatalDeoptimizationError;
28+
29+
import java.lang.reflect.Array;
30+
31+
import org.graalvm.nativeimage.CurrentIsolate;
32+
import org.graalvm.nativeimage.ImageSingletons;
33+
import org.graalvm.nativeimage.IsolateThread;
34+
import org.graalvm.word.Pointer;
35+
import org.graalvm.word.SignedWord;
36+
import org.graalvm.word.UnsignedWord;
37+
2738
import com.oracle.svm.core.ReservedRegisters;
2839
import com.oracle.svm.core.code.FrameInfoQueryResult;
2940
import com.oracle.svm.core.config.ConfigurationValues;
@@ -32,20 +43,12 @@
3243
import com.oracle.svm.core.hub.DynamicHub;
3344
import com.oracle.svm.core.hub.LayoutEncoding;
3445
import com.oracle.svm.core.meta.SubstrateObjectConstant;
35-
import jdk.internal.misc.Unsafe;
46+
3647
import jdk.graal.compiler.core.common.util.TypeConversion;
3748
import jdk.graal.compiler.word.Word;
49+
import jdk.internal.misc.Unsafe;
3850
import jdk.vm.ci.meta.JavaConstant;
3951
import jdk.vm.ci.meta.JavaKind;
40-
import org.graalvm.nativeimage.CurrentIsolate;
41-
import org.graalvm.nativeimage.IsolateThread;
42-
import org.graalvm.word.Pointer;
43-
import org.graalvm.word.SignedWord;
44-
import org.graalvm.word.UnsignedWord;
45-
46-
import java.lang.reflect.Array;
47-
48-
import static com.oracle.svm.core.deopt.Deoptimizer.fatalDeoptimizationError;
4952

5053
public class DeoptState {
5154

@@ -162,6 +165,16 @@ private Object materializeObject(int virtualObjectId, FrameInfoQueryResult sourc
162165
materializedObjects[virtualObjectId] = obj;
163166
Deoptimizer.maybeTestGC();
164167

168+
if (ImageSingletons.contains(VectorAPIDeoptimizationSupport.class)) {
169+
VectorAPIDeoptimizationSupport deoptSupport = ImageSingletons.lookup(VectorAPIDeoptimizationSupport.class);
170+
Object payloadArray = deoptSupport.materializePayload(this, hub, encodings[curIdx], sourceFrame);
171+
if (payloadArray != null) {
172+
JavaConstant arrayConstant = SubstrateObjectConstant.forObject(payloadArray, ReferenceAccess.singleton().haveCompressedReferences());
173+
Deoptimizer.writeValueInMaterializedObj(obj, curOffset, arrayConstant, sourceFrame);
174+
return obj;
175+
}
176+
}
177+
165178
while (curIdx < encodings.length) {
166179
FrameInfoQueryResult.ValueInfo value = encodings[curIdx];
167180
JavaKind kind = value.getKind();
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.oracle.svm.core.deopt;
27+
28+
import org.graalvm.word.UnsignedWord;
29+
30+
import com.oracle.svm.core.code.FrameInfoQueryResult;
31+
import com.oracle.svm.core.hub.DynamicHub;
32+
import com.oracle.svm.core.util.VMError;
33+
34+
import jdk.vm.ci.meta.JavaConstant;
35+
36+
/**
37+
* Support for deoptimization with virtual Vector API objects in the state. This class is a
38+
* placeholder until GR-59869 is done.
39+
*/
40+
public abstract class VectorAPIDeoptimizationSupport {
41+
42+
/**
43+
* If the {@code hub} refers to a Vector API vector, materialize its payload array. That is,
44+
* allocate a primitive array of the appropriate element type and length for the Vector API
45+
* value. Read the vector's entries from the stack and store them in the array.
46+
*
47+
* @param deoptState state for accessing values on the stack
48+
* @param hub the hub of the object to be materialized
49+
* @param vectorEncoding describes the location of the vector on the stack
50+
* @param sourceFrame the source frame containing the vector
51+
* @return a materialized primitive array if the object to be materialized is a Vector API
52+
* vector; {@code null} otherwise
53+
*/
54+
public Object materializePayload(DeoptState deoptState, DynamicHub hub, FrameInfoQueryResult.ValueInfo vectorEncoding, FrameInfoQueryResult sourceFrame) {
55+
throw VMError.intentionallyUnimplemented();
56+
}
57+
58+
protected static JavaConstant readValue(DeoptState deoptState, FrameInfoQueryResult.ValueInfo valueInfo, FrameInfoQueryResult sourceFrame) {
59+
return deoptState.readValue(valueInfo, sourceFrame);
60+
}
61+
62+
protected static void writeValueInMaterializedObj(Object materializedObj, UnsignedWord offsetInObj, JavaConstant constant, FrameInfoQueryResult frameInfo) {
63+
Deoptimizer.writeValueInMaterializedObj(materializedObj, offsetInObj, constant, frameInfo);
64+
}
65+
}

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,18 @@ private static final class Target_jdk_incubator_vector_VectorOperators_Conversio
6060
* their hot path callers and their callees are all @ForceInline.
6161
*/
6262

63+
@AnnotateOriginal
64+
@AlwaysInline("Vector API performance")
65+
native char kind();
66+
67+
@AnnotateOriginal
68+
@AlwaysInline("Vector API performance")
69+
native Target_jdk_incubator_vector_LaneType domain();
70+
71+
@AnnotateOriginal
72+
@AlwaysInline("Vector API performance")
73+
native Target_jdk_incubator_vector_LaneType range();
74+
6375
@AnnotateOriginal
6476
@AlwaysInline("Vector API performance")
6577
private static native Target_jdk_incubator_vector_VectorOperators_ConversionImpl<?, ?> ofCopy(Target_jdk_incubator_vector_LaneType dom);

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/hosted/runtimecompilation/RuntimeCompiledMethodSupport.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -486,7 +486,8 @@ public static class ConvertMacroNodes extends Phase {
486486
@Override
487487
protected void run(StructuredGraph graph) {
488488
for (Node n : graph.getNodes().snapshot()) {
489-
VMError.guarantee(!(n instanceof MacroNode), "DeoptTarget Methods do not support Macro Nodes: method %s, node %s", graph.method(), n);
489+
VMError.guarantee(!(n instanceof MacroNode macro && macro.canDeoptimizeOrThrow()), "DeoptTarget Methods do not support Macro Nodes that may deopt or throw: method %s, node %s",
490+
graph.method(), n);
490491

491492
if (n instanceof MacroWithExceptionNode macro) {
492493
macro.replaceWithInvoke();

0 commit comments

Comments
 (0)