Skip to content

Commit 6e77c28

Browse files
committed
Move bytecode dataflow analysis functionality from the compiler to SVM.
1 parent 7d0a2b4 commit 6e77c28

22 files changed

+185
-149
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BytecodeParser.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@
269269
import java.util.function.IntConsumer;
270270
import java.util.function.Supplier;
271271

272-
import jdk.graal.compiler.nodes.graphbuilderconf.MethodParsingPlugin;
273272
import org.graalvm.collections.EconomicMap;
274273
import org.graalvm.collections.Equivalence;
275274
import org.graalvm.word.LocationIdentity;
@@ -1102,10 +1101,6 @@ protected void build(FixedWithNextNode startInstruction, FrameStateBuilder start
11021101
graph.recordMethod(method);
11031102
}
11041103

1105-
for (MethodParsingPlugin plugin : graphBuilderConfig.getPlugins().getMethodParsingPlugins()) {
1106-
plugin.execute(method, intrinsicContext);
1107-
}
1108-
11091104
// compute the block map, setup exception handlers and get the entrypoint(s)
11101105
this.blockMap = generateBlockMap();
11111106
this.firstInstructionArray = new FixedWithNextNode[blockMap.getBlockCount()];

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public static class Plugins {
4242
private TypePlugin[] typePlugins;
4343
private InlineInvokePlugin[] inlineInvokePlugins;
4444
private ClassInitializationPlugin classInitializationPlugin;
45-
private MethodParsingPlugin[] methodPlugins;
4645

4746
/**
4847
* Creates a copy of a given set of plugins. The {@link InvocationPlugins} in
@@ -56,7 +55,6 @@ public Plugins(Plugins copyFrom, InvocationPlugins invocationPlugins) {
5655
this.typePlugins = copyFrom.typePlugins;
5756
this.inlineInvokePlugins = copyFrom.inlineInvokePlugins;
5857
this.classInitializationPlugin = copyFrom.classInitializationPlugin;
59-
this.methodPlugins = copyFrom.methodPlugins;
6058
}
6159

6260
public Plugins(Plugins copyFrom) {
@@ -75,7 +73,6 @@ public Plugins(InvocationPlugins invocationPlugins) {
7573
this.parameterPlugins = new ParameterPlugin[0];
7674
this.typePlugins = new TypePlugin[0];
7775
this.inlineInvokePlugins = new InlineInvokePlugin[0];
78-
this.methodPlugins = new MethodParsingPlugin[0];
7976
}
8077

8178
public InvocationPlugins getInvocationPlugins() {
@@ -160,22 +157,6 @@ public StampPair getOverridingStamp(GraphBuilderTool b, JavaType type, boolean n
160157
}
161158
return null;
162159
}
163-
164-
public void appendMethodParsingPlugin(MethodParsingPlugin plugin) {
165-
methodPlugins = Arrays.copyOf(methodPlugins, methodPlugins.length + 1);
166-
methodPlugins[methodPlugins.length - 1] = plugin;
167-
}
168-
169-
public void prependMethodParsingPlugin(MethodParsingPlugin plugin) {
170-
MethodParsingPlugin[] newPlugins = new MethodParsingPlugin[methodPlugins.length + 1];
171-
System.arraycopy(methodPlugins, 0, newPlugins, 1, methodPlugins.length);
172-
newPlugins[0] = plugin;
173-
methodPlugins = newPlugins;
174-
}
175-
176-
public MethodParsingPlugin[] getMethodParsingPlugins() {
177-
return methodPlugins;
178-
}
179160
}
180161

181162
private final boolean eagerResolving;

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/graphbuilderconf/GraphBuilderContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ default int getDepth() {
291291
* returns true, the resulting call stack does not include the target of the
292292
* invocation plugin.
293293
*/
294-
default List<StackTraceElement> getCallStack(boolean ignoreInvocationPluginTarget) {
294+
default List<StackTraceElement> getInliningCallStack(boolean ignoreInvocationPluginTarget) {
295295
List<StackTraceElement> callStack = new ArrayList<>();
296296
for (GraphBuilderContext cur = this; cur != null; cur = cur.getParent()) {
297297
callStack.add(cur.getMethod().asStackTraceElement(cur.bci()));

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/IntrinsicGraphBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public int getDepth() {
329329
}
330330

331331
@Override
332-
public List<StackTraceElement> getCallStack(boolean ignoreInvocationPluginTarget) {
332+
public List<StackTraceElement> getInliningCallStack(boolean ignoreInvocationPluginTarget) {
333333
return new ArrayList<>();
334334
}
335335

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/PEGraphDecoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ public int getDepth() {
414414
}
415415

416416
@Override
417-
public List<StackTraceElement> getCallStack(boolean ignoreInvocationPluginTarget) {
417+
public List<StackTraceElement> getInliningCallStack(boolean ignoreInvocationPluginTarget) {
418418
StackTraceElement[] callStackArray = methodScope.getCallStack();
419419
List<StackTraceElement> callStack = new ArrayList<>(callStackArray.length);
420420
Collections.addAll(callStack, callStackArray);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ private static final class RuntimeBytecodeParser extends AnalysisGraphBuilderPha
461461

462462
RuntimeBytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI,
463463
IntrinsicContext intrinsicContext, SVMHost svmHost) {
464-
super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext, svmHost, false);
464+
super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext, svmHost, false, null);
465465
}
466466

467467
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ protected void setupNativeImage(String imageName, OptionValues options, Map<Meth
945945
ImageSingletons.add(ClassLoaderSupport.class, classLoaderSupport);
946946
ImageSingletons.add(LinkAtBuildTimeSupport.class, new LinkAtBuildTimeSupport(loader, classLoaderSupport));
947947
ImageSingletons.add(ObservableImageHeapMapProvider.class, new ObservableImageHeapMapProviderImpl());
948+
ImageSingletons.add(PreParseCallbackSupport.class, new PreParseCallbackSupport());
948949

949950
ClassInitializationSupport classInitializationSupport = new ClassInitializationSupport(originalMetaAccess, loader);
950951
ImageSingletons.add(RuntimeClassInitializationSupport.class, classInitializationSupport);
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 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
@@ -22,16 +22,21 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package jdk.graal.compiler.nodes.graphbuilderconf;
25+
package com.oracle.svm.hosted;
2626

27+
import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext;
2728
import jdk.vm.ci.meta.ResolvedJavaMethod;
2829

2930
/**
30-
* Plugin for accessing the method currently being parsed. These plugins are executed before
31-
* invocation and other types of bytecode parser plugins and can be used for collecting certain
32-
* information from the parsed method that the other plugins may rely on.
31+
* Callback executed at the start of method parsing. It is executed before any bytecode parser
32+
* invocation plugin, and can as such be used to collect information from the method that the
33+
* plugins may rely on.
3334
*/
34-
public interface MethodParsingPlugin extends GraphBuilderPlugin {
35+
public interface PreParseCallback {
3536

37+
/**
38+
* Execute the callback for {@code method}. {@code IntrinsicContext} is null if no intrinsic is
39+
* currently being processed.
40+
*/
3641
void execute(ResolvedJavaMethod method, IntrinsicContext intrinsicContext);
3742
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
package com.oracle.svm.hosted;
26+
27+
import jdk.graal.compiler.nodes.graphbuilderconf.IntrinsicContext;
28+
import jdk.vm.ci.meta.ResolvedJavaMethod;
29+
import org.graalvm.nativeimage.ImageSingletons;
30+
31+
import java.util.ArrayList;
32+
import java.util.List;
33+
34+
/**
35+
* Represents a hook for callbacks executed right before the start of method parsing by
36+
* {@link com.oracle.svm.hosted.phases.SharedGraphBuilderPhase.SharedBytecodeParser}.
37+
*/
38+
public class PreParseCallbackSupport {
39+
40+
private final List<PreParseCallback> preParseCallbacks = new ArrayList<>();
41+
42+
public static PreParseCallbackSupport singleton() {
43+
return ImageSingletons.lookup(PreParseCallbackSupport.class);
44+
}
45+
46+
/**
47+
* Add a {@link PreParseCallback} to be executed at the start of method parsing, i.e., before
48+
* any invocation plugins are executed.
49+
*/
50+
public void addCallback(PreParseCallback preParseCallback) {
51+
preParseCallbacks.add(preParseCallback);
52+
}
53+
54+
public void executeCallbacks(ResolvedJavaMethod method, IntrinsicContext intrinsicContext) {
55+
preParseCallbacks.forEach(cb -> cb.execute(method, intrinsicContext));
56+
}
57+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/classinitialization/ClassInitializerGraphBuilderPhase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.hosted.classinitialization;
2626

27+
import com.oracle.svm.hosted.PreParseCallbackSupport;
2728
import com.oracle.svm.hosted.phases.SharedGraphBuilderPhase;
2829

2930
import jdk.graal.compiler.java.BytecodeParser;
@@ -73,7 +74,7 @@ protected BytecodeParser createBytecodeParser(StructuredGraph graph, BytecodePar
7374
static class ClassInitializerBytecodeParser extends SharedBytecodeParser {
7475
ClassInitializerBytecodeParser(GraphBuilderPhase.Instance graphBuilderInstance, StructuredGraph graph, BytecodeParser parent, ResolvedJavaMethod method, int entryBCI,
7576
IntrinsicContext intrinsicContext) {
76-
super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext, true, false);
77+
super(graphBuilderInstance, graph, parent, method, entryBCI, intrinsicContext, true, false, PreParseCallbackSupport.singleton());
7778
}
7879
}
7980
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/dataflow/AbstractFrame.java renamed to substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dataflow/AbstractFrame.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, 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
@@ -22,9 +22,9 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package jdk.graal.compiler.java.dataflow;
25+
package com.oracle.svm.hosted.dataflow;
2626

27-
import jdk.graal.compiler.debug.GraalError;
27+
import com.oracle.svm.core.util.VMError;
2828

2929
import java.util.ArrayList;
3030
import java.util.HashMap;
@@ -173,12 +173,12 @@ void push(ValueWithSlots<T> value) {
173173
}
174174

175175
ValueWithSlots<T> pop() {
176-
GraalError.guarantee(!stack.isEmpty(), "Cannot pop from empty stack");
176+
VMError.guarantee(!stack.isEmpty(), "Cannot pop from empty stack");
177177
return stack.removeLast();
178178
}
179179

180180
ValueWithSlots<T> peek(int depth) {
181-
GraalError.guarantee(0 <= depth && depth < size(), "Operand stack doesn't contain enough values");
181+
VMError.guarantee(0 <= depth && depth < size(), "Operand stack doesn't contain enough values");
182182
return stack.get(stack.size() - depth - 1);
183183
}
184184

@@ -191,11 +191,11 @@ void clear() {
191191
}
192192

193193
void mergeWith(OperandStack<T> other, BiFunction<T, T, T> mergeFunction) {
194-
GraalError.guarantee(size() == other.size(), "Operand stack size must match upon merging");
194+
VMError.guarantee(size() == other.size(), "Operand stack size must match upon merging");
195195
for (int i = 0; i < stack.size(); i++) {
196196
ValueWithSlots<T> thisValue = stack.get(i);
197197
ValueWithSlots<T> thatValue = other.stack.get(i);
198-
GraalError.guarantee(thisValue.size() == thatValue.size(), "The size of operand stack values must match upon merging");
198+
VMError.guarantee(thisValue.size() == thatValue.size(), "The size of operand stack values must match upon merging");
199199
ValueWithSlots<T> mergedValue = new ValueWithSlots<>(mergeFunction.apply(thisValue.value(), thatValue.value()), thisValue.size());
200200
stack.set(i, mergedValue);
201201
}
@@ -281,7 +281,7 @@ void put(int index, ValueWithSlots<T> value) {
281281
}
282282

283283
ValueWithSlots<T> get(int index) {
284-
GraalError.guarantee(variables.containsKey(index), "Attempted to access non-existent variable in local variable table");
284+
VMError.guarantee(variables.containsKey(index), "Attempted to access non-existent variable in local variable table");
285285
return variables.get(index);
286286
}
287287

0 commit comments

Comments
 (0)