Skip to content

Commit e92dab0

Browse files
author
Christian Wimmer
committed
Do not parse bytecode again after static analysis
1 parent eacbea8 commit e92dab0

File tree

41 files changed

+1383
-524
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1383
-524
lines changed

compiler/src/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public class NodeSourcePosition extends BytecodePosition implements Iterable<Nod
5151
private final Marker marker;
5252
private final SourceLanguagePosition sourceLanguagePosition;
5353

54+
public Marker getMarker() {
55+
return marker;
56+
}
57+
5458
/**
5559
* Remove marker frames.
5660
*/

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/AbstractForeignCallStub.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ protected final StructuredGraph getGraph(DebugContext debug, CompilationIdentifi
221221
ResolvedJavaMethod getAndClearObjectResult = foreignCallSnippets.getAndClearObjectResult.getMethod();
222222
ResolvedJavaMethod verifyObject = foreignCallSnippets.verifyObject.getMethod();
223223
ResolvedJavaMethod thisMethod = getGraphMethod();
224-
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString());
224+
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString(), false);
225225
StructuredGraph graph = kit.getGraph();
226226
graph.disableFrameStateVerification();
227227
ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,14 +679,15 @@ public void logInliningTree() {
679679
*/
680680
@Override
681681
protected Graph copy(String newName, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback, DebugContext debugForCopy) {
682-
return copy(newName, duplicationMapCallback, compilationId, debugForCopy);
682+
return copy(newName, rootMethod, getOptions(), duplicationMapCallback, compilationId, debugForCopy);
683683
}
684684

685685
@SuppressWarnings("try")
686-
private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback, CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
686+
private StructuredGraph copy(String newName, ResolvedJavaMethod rootMethodForCopy, OptionValues optionsForCopy, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback,
687+
CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
687688
AllowAssumptions allowAssumptions = allowAssumptions();
688689
StructuredGraph copy = new StructuredGraph(newName,
689-
method(),
690+
rootMethodForCopy,
690691
entryBCI,
691692
assumptions == null ? null : new Assumptions(),
692693
speculationLog,
@@ -695,7 +696,7 @@ private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<No
695696
methods != null ? new ArrayList<>(methods) : null,
696697
trackNodeSourcePosition,
697698
newCompilationId,
698-
getOptions(), debugForCopy, null, callerContext);
699+
optionsForCopy, debugForCopy, null, callerContext);
699700
if (allowAssumptions == AllowAssumptions.YES && assumptions != null) {
700701
copy.assumptions.record(assumptions);
701702
}
@@ -727,7 +728,11 @@ private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<No
727728
* accessed by multiple threads).
728729
*/
729730
public StructuredGraph copyWithIdentifier(CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
730-
return copy(name, null, newCompilationId, debugForCopy);
731+
return copy(name, rootMethod, getOptions(), null, newCompilationId, debugForCopy);
732+
}
733+
734+
public StructuredGraph copy(ResolvedJavaMethod rootMethodForCopy, OptionValues optionsForCopy, DebugContext debugForCopy) {
735+
return copy(name, rootMethodForCopy, optionsForCopy, null, compilationId, debugForCopy);
731736
}
732737

733738
public ParameterNode getParameter(int index) {

compiler/src/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ public class GraphKit extends CoreProvidersDelegate implements GraphBuilderTool
107107
protected abstract static class Structure {
108108
}
109109

110-
public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, Plugins graphBuilderPlugins, CompilationIdentifier compilationId, String name) {
110+
public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, Plugins graphBuilderPlugins, CompilationIdentifier compilationId, String name,
111+
boolean trackNodeSourcePosition) {
111112
super(providers);
112113
StructuredGraph.Builder builder = new StructuredGraph.Builder(debug.getOptions(), debug).compilationId(compilationId);
113114
if (name != null) {
@@ -117,6 +118,9 @@ public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers pro
117118
}
118119
this.graph = builder.build();
119120
graph.disableUnsafeAccessTracking();
121+
if (trackNodeSourcePosition) {
122+
graph.setTrackNodeSourcePosition();
123+
}
120124
if (graph.trackNodeSourcePosition()) {
121125
// Set up a default value that everything constructed by GraphKit will use.
122126
graph.withNodeSourcePosition(NodeSourcePosition.substitution(stubMethod));

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/BigBang.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,10 @@ public abstract class BigBang {
128128
public final Timer processFeaturesTimer;
129129
public final Timer analysisTimer;
130130

131+
private final boolean strengthenGraalGraphs;
132+
131133
public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders providers, HostVM hostVM, ForkJoinPool executorService, Runnable heartbeatCallback,
132-
UnsupportedFeatures unsupportedFeatures) {
134+
UnsupportedFeatures unsupportedFeatures, boolean strengthenGraalGraphs) {
133135
this.options = options;
134136
this.debugHandlerFactories = Collections.singletonList(new GraalDebugHandlersFactory(providers.getSnippetReflection()));
135137
this.debug = new Builder(options, debugHandlerFactories).build();
@@ -145,6 +147,7 @@ public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders
145147
this.replacements = providers.getReplacements();
146148
this.unsupportedFeatures = unsupportedFeatures;
147149
this.providers = providers;
150+
this.strengthenGraalGraphs = strengthenGraalGraphs;
148151

149152
this.objectType = metaAccess.lookupJavaType(Object.class);
150153
/*
@@ -174,6 +177,10 @@ public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders
174177
: HeapScanningPolicy.skipTypes(skippedHeapTypes());
175178
}
176179

180+
public boolean strengthenGraalGraphs() {
181+
return strengthenGraalGraphs;
182+
}
183+
177184
public AnalysisType[] skippedHeapTypes() {
178185
return new AnalysisType[]{metaAccess.lookupJavaType(String.class)};
179186
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ public interface HostVM {
7070

7171
boolean isInitialized(AnalysisType type);
7272

73+
/**
74+
* Hook to change the {@link GraphBuilderConfiguration} used for parsing a method during
75+
* analysis.
76+
*
77+
* @param config The default configuration used by the static analysis.
78+
* @param method The method that is going to be parsed with the returned configuration.
79+
* @return The updated configuration for the method.
80+
*/
81+
default GraphBuilderConfiguration updateGraphBuilderConfiguration(GraphBuilderConfiguration config, AnalysisMethod method) {
82+
return config;
83+
}
84+
7385
Optional<AnalysisMethod> handleForeignCall(ForeignCallDescriptor foreignCallDescriptor, ForeignCallsProvider foreignCallsProvider);
7486

7587
GraphBuilderPhase.Instance createGraphBuilderPhase(HostedProviders providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AnalysisParsedGraph.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,14 @@ public static AnalysisParsedGraph parseBytecode(BigBang bb, AnalysisMethod metho
9999
// enable this logging to get log output in compilation passes
100100
try (Indent indent2 = debug.logAndIndent("parse graph phases")) {
101101

102-
GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins()).withEagerResolving(true)
102+
GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins())
103+
.withEagerResolving(true)
103104
.withUnresolvedIsError(PointstoOptions.UnresolvedIsError.getValue(bb.getOptions()))
104-
.withNodeSourcePosition(true).withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll);
105-
106-
/*
107-
* We want to always disable the liveness analysis, since we want the points-to
108-
* analysis to be as conservative as possible. The analysis results can then be
109-
* used with the liveness analysis enabled or disabled.
110-
*/
111-
config = config.withRetainLocalVariables(true);
105+
.withNodeSourcePosition(true)
106+
.withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll)
107+
.withRetainLocalVariables(true);
108+
109+
config = bb.getHostVM().updateGraphBuilderConfiguration(config, method);
112110

113111
bb.getHostVM().createGraphBuilderPhase(bb.getProviders(), config, OptimisticOptimizations.NONE, null).apply(graph);
114112
} catch (PermanentBailoutException ex) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MergeTypeFlow.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
package com.oracle.graal.pointsto.flow;
2626

27-
import org.graalvm.compiler.nodes.ValueNode;
27+
import org.graalvm.compiler.graph.Node;
2828

2929
import com.oracle.graal.pointsto.BigBang;
3030
import com.oracle.graal.pointsto.typestate.TypeState;
@@ -33,7 +33,7 @@
3333

3434
public class MergeTypeFlow extends TypeFlow<BytecodePosition> {
3535

36-
public MergeTypeFlow(ValueNode node) {
36+
public MergeTypeFlow(Node node) {
3737
super(node.getNodeSourcePosition(), null);
3838
}
3939

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodFlowsGraph.java

Lines changed: 19 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@
3939
import java.util.Set;
4040
import java.util.stream.Collectors;
4141

42+
import org.graalvm.compiler.nodes.Invoke;
43+
4244
import com.oracle.graal.pointsto.BigBang;
43-
import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.LoadIndexedTypeFlow;
4445
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
4546
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4647

@@ -60,16 +61,8 @@ public class MethodFlowsGraph {
6061
// points in the method
6162
private FormalParamTypeFlow[] parameters;
6263
private InitialParamTypeFlow[] initialParameterFlows;
63-
private List<SourceTypeFlow> sources;
64-
private List<LoadFieldTypeFlow> fieldLoads;
65-
private List<LoadIndexedTypeFlow> indexedLoads;
6664
private List<TypeFlow<?>> miscEntryFlows;
67-
68-
private List<NewInstanceTypeFlow> allocations;
69-
private List<DynamicNewInstanceTypeFlow> dynamicAllocations;
70-
private List<CloneTypeFlow> clones;
71-
private List<MonitorEnterTypeFlow> monitorEntries;
72-
65+
private Map<Object, TypeFlow<?>> nodeFlows;
7366
/*
7467
* We keep a bci->flow mapping for instanceof and invoke flows since they are queried by the
7568
* analysis results builder.
@@ -114,32 +107,9 @@ public MethodFlowsGraph(AnalysisMethod analysisMethod) {
114107
// never linked and parsed
115108
method.getSignature().getReturnType(method.getDeclaringClass());
116109

117-
// allocations
118-
allocations = new ArrayList<>();
119-
120-
dynamicAllocations = new ArrayList<>();
121-
122-
monitorEntries = new ArrayList<>();
123-
124-
// clones
125-
clones = new ArrayList<>();
126-
127-
// sources
128-
sources = new ArrayList<>();
129-
130-
// field loads
131-
fieldLoads = new ArrayList<>();
132-
133-
// indexed loads
134-
indexedLoads = new ArrayList<>();
135-
136-
// misc entry inputs
137110
miscEntryFlows = new ArrayList<>();
138-
139-
// instanceof
111+
nodeFlows = new HashMap<>();
140112
instanceOfFlows = new HashMap<>();
141-
142-
// invoke
143113
invokeFlows = new HashMap<>(4, 0.75f);
144114
nonUniqueBcis = new HashSet<>();
145115
}
@@ -172,40 +142,12 @@ public void cloneOriginalFlows(BigBang bb) {
172142
}
173143
}
174144

175-
// initial parameter flows
176145
initialParameterFlows = new InitialParamTypeFlow[originalMethodFlowsGraph.initialParameterFlows.length];
177146

178-
// allocations
179-
allocations = originalMethodFlowsGraph.allocations.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
180-
181-
// dynamic allocations
182-
dynamicAllocations = originalMethodFlowsGraph.dynamicAllocations.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
183-
184-
// monitor entries
185-
monitorEntries = originalMethodFlowsGraph.monitorEntries.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
186-
187-
// clones
188-
clones = originalMethodFlowsGraph.clones.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
189-
190-
// sources
191-
sources = originalMethodFlowsGraph.sources.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
192-
193-
// result
147+
nodeFlows = originalMethodFlowsGraph.nodeFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));
194148
result = originalMethodFlowsGraph.getResult() != null ? lookupCloneOf(bb, originalMethodFlowsGraph.getResult()) : null;
195-
196-
// field loads
197-
fieldLoads = originalMethodFlowsGraph.fieldLoads.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
198-
199-
// indexed loads
200-
indexedLoads = originalMethodFlowsGraph.indexedLoads.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
201-
202-
// instanceof
203149
instanceOfFlows = originalMethodFlowsGraph.instanceOfFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));
204-
205-
// misc entry flows (merge, proxy, etc.)
206150
miscEntryFlows = originalMethodFlowsGraph.miscEntryFlows.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());
207-
208-
// instanceof
209151
invokeFlows = originalMethodFlowsGraph.invokeFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));
210152

211153
/* At this point all the clones should have been created. */
@@ -347,15 +289,8 @@ private TypeFlow<?>[] doLinearizeGraph() {
347289
}
348290
}
349291

350-
worklist.addAll(allocations);
351-
worklist.addAll(dynamicAllocations);
352-
worklist.addAll(monitorEntries);
353-
worklist.addAll(clones);
354-
worklist.addAll(sources);
292+
worklist.addAll(nodeFlows.values());
355293
worklist.addAll(miscEntryFlows);
356-
worklist.addAll(fieldLoads);
357-
worklist.addAll(indexedLoads);
358-
359294
worklist.addAll(instanceOfFlows.values());
360295
worklist.addAll(invokeFlows.values());
361296

@@ -439,55 +374,25 @@ public TypeFlow<?>[] getInitialParameterFlows() {
439374
return initialParameterFlows;
440375
}
441376

442-
public void addAllocation(NewInstanceTypeFlow allocation) {
443-
allocations.add(allocation);
444-
}
445-
446-
public List<NewInstanceTypeFlow> getAllocations() {
447-
return allocations;
448-
}
449-
450-
public void addDynamicAllocation(DynamicNewInstanceTypeFlow allocation) {
451-
dynamicAllocations.add(allocation);
452-
}
453-
454-
public List<DynamicNewInstanceTypeFlow> getDynamicAllocations() {
455-
return dynamicAllocations;
456-
}
457-
458-
public void addMonitorEntry(MonitorEnterTypeFlow monitorEntry) {
459-
monitorEntries.add(monitorEntry);
377+
public void addNodeFlow(Object key, TypeFlow<?> flow) {
378+
assert flow != null && !(flow instanceof AllInstantiatedTypeFlow);
379+
Object previous = nodeFlows.put(key, flow);
380+
assert previous == null : "Overwriting flow for " + key + ": " + previous + " - " + flow;
460381
}
461382

462-
public List<MonitorEnterTypeFlow> getMonitorEntries() {
463-
return monitorEntries;
383+
public Collection<TypeFlow<?>> getMiscFlows() {
384+
return miscEntryFlows;
464385
}
465386

466-
public void addClone(CloneTypeFlow clone) {
467-
clones.add(clone);
468-
}
469-
470-
public List<CloneTypeFlow> getClones() {
471-
return clones;
472-
}
473-
474-
public void addSource(SourceTypeFlow source) {
475-
sources.add(source);
387+
public Map<Object, TypeFlow<?>> getNodeFlows() {
388+
return nodeFlows;
476389
}
477390

478391
public void addMiscEntryFlow(TypeFlow<?> entryFlow) {
479392
assert !(entryFlow instanceof AllInstantiatedTypeFlow);
480393
miscEntryFlows.add(entryFlow);
481394
}
482395

483-
public void addFieldLoad(LoadFieldTypeFlow fieldLoad) {
484-
fieldLoads.add(fieldLoad);
485-
}
486-
487-
public void addIndexedLoad(LoadIndexedTypeFlow indexedLoad) {
488-
indexedLoads.add(indexedLoad);
489-
}
490-
491396
public void setResult(FormalReturnTypeFlow result) {
492397
this.result = result;
493398
}
@@ -500,7 +405,11 @@ public Set<Entry<Object, InvokeTypeFlow>> getInvokes() {
500405
return invokeFlows.entrySet();
501406
}
502407

503-
public Collection<InvokeTypeFlow> getInvokeFlows() {
408+
public InvokeTypeFlow getInvokeFlow(Invoke invoke) {
409+
return invokeFlows.get(invoke);
410+
}
411+
412+
Collection<InvokeTypeFlow> getInvokeFlows() {
504413
return invokeFlows.values();
505414
}
506415

0 commit comments

Comments
 (0)