Skip to content

Commit

Permalink
[GR-31363] Do not parse bytecode again after static analysis.
Browse files Browse the repository at this point in the history
PullRequest: graal/8173
  • Loading branch information
Christian Wimmer committed May 20, 2021
2 parents 341cf06 + e92dab0 commit aa2f6e8
Show file tree
Hide file tree
Showing 41 changed files with 1,383 additions and 524 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public class NodeSourcePosition extends BytecodePosition implements Iterable<Nod
private final Marker marker;
private final SourceLanguagePosition sourceLanguagePosition;

public Marker getMarker() {
return marker;
}

/**
* Remove marker frames.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ protected final StructuredGraph getGraph(DebugContext debug, CompilationIdentifi
ResolvedJavaMethod getAndClearObjectResult = foreignCallSnippets.getAndClearObjectResult.getMethod();
ResolvedJavaMethod verifyObject = foreignCallSnippets.verifyObject.getMethod();
ResolvedJavaMethod thisMethod = getGraphMethod();
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString());
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString(), false);
StructuredGraph graph = kit.getGraph();
graph.disableFrameStateVerification();
ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,14 +679,15 @@ public void logInliningTree() {
*/
@Override
protected Graph copy(String newName, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback, DebugContext debugForCopy) {
return copy(newName, duplicationMapCallback, compilationId, debugForCopy);
return copy(newName, rootMethod, getOptions(), duplicationMapCallback, compilationId, debugForCopy);
}

@SuppressWarnings("try")
private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback, CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
private StructuredGraph copy(String newName, ResolvedJavaMethod rootMethodForCopy, OptionValues optionsForCopy, Consumer<UnmodifiableEconomicMap<Node, Node>> duplicationMapCallback,
CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
AllowAssumptions allowAssumptions = allowAssumptions();
StructuredGraph copy = new StructuredGraph(newName,
method(),
rootMethodForCopy,
entryBCI,
assumptions == null ? null : new Assumptions(),
speculationLog,
Expand All @@ -695,7 +696,7 @@ private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<No
methods != null ? new ArrayList<>(methods) : null,
trackNodeSourcePosition,
newCompilationId,
getOptions(), debugForCopy, null, callerContext);
optionsForCopy, debugForCopy, null, callerContext);
if (allowAssumptions == AllowAssumptions.YES && assumptions != null) {
copy.assumptions.record(assumptions);
}
Expand Down Expand Up @@ -727,7 +728,11 @@ private StructuredGraph copy(String newName, Consumer<UnmodifiableEconomicMap<No
* accessed by multiple threads).
*/
public StructuredGraph copyWithIdentifier(CompilationIdentifier newCompilationId, DebugContext debugForCopy) {
return copy(name, null, newCompilationId, debugForCopy);
return copy(name, rootMethod, getOptions(), null, newCompilationId, debugForCopy);
}

public StructuredGraph copy(ResolvedJavaMethod rootMethodForCopy, OptionValues optionsForCopy, DebugContext debugForCopy) {
return copy(name, rootMethodForCopy, optionsForCopy, null, compilationId, debugForCopy);
}

public ParameterNode getParameter(int index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public class GraphKit extends CoreProvidersDelegate implements GraphBuilderTool
protected abstract static class Structure {
}

public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, Plugins graphBuilderPlugins, CompilationIdentifier compilationId, String name) {
public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers providers, WordTypes wordTypes, Plugins graphBuilderPlugins, CompilationIdentifier compilationId, String name,
boolean trackNodeSourcePosition) {
super(providers);
StructuredGraph.Builder builder = new StructuredGraph.Builder(debug.getOptions(), debug).compilationId(compilationId);
if (name != null) {
Expand All @@ -117,6 +118,9 @@ public GraphKit(DebugContext debug, ResolvedJavaMethod stubMethod, Providers pro
}
this.graph = builder.build();
graph.disableUnsafeAccessTracking();
if (trackNodeSourcePosition) {
graph.setTrackNodeSourcePosition();
}
if (graph.trackNodeSourcePosition()) {
// Set up a default value that everything constructed by GraphKit will use.
graph.withNodeSourcePosition(NodeSourcePosition.substitution(stubMethod));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ public abstract class BigBang {
public final Timer processFeaturesTimer;
public final Timer analysisTimer;

private final boolean strengthenGraalGraphs;

public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders providers, HostVM hostVM, ForkJoinPool executorService, Runnable heartbeatCallback,
UnsupportedFeatures unsupportedFeatures) {
UnsupportedFeatures unsupportedFeatures, boolean strengthenGraalGraphs) {
this.options = options;
this.debugHandlerFactories = Collections.singletonList(new GraalDebugHandlersFactory(providers.getSnippetReflection()));
this.debug = new Builder(options, debugHandlerFactories).build();
Expand All @@ -145,6 +147,7 @@ public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders
this.replacements = providers.getReplacements();
this.unsupportedFeatures = unsupportedFeatures;
this.providers = providers;
this.strengthenGraalGraphs = strengthenGraalGraphs;

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

public boolean strengthenGraalGraphs() {
return strengthenGraalGraphs;
}

public AnalysisType[] skippedHeapTypes() {
return new AnalysisType[]{metaAccess.lookupJavaType(String.class)};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,18 @@ public interface HostVM {

boolean isInitialized(AnalysisType type);

/**
* Hook to change the {@link GraphBuilderConfiguration} used for parsing a method during
* analysis.
*
* @param config The default configuration used by the static analysis.
* @param method The method that is going to be parsed with the returned configuration.
* @return The updated configuration for the method.
*/
default GraphBuilderConfiguration updateGraphBuilderConfiguration(GraphBuilderConfiguration config, AnalysisMethod method) {
return config;
}

Optional<AnalysisMethod> handleForeignCall(ForeignCallDescriptor foreignCallDescriptor, ForeignCallsProvider foreignCallsProvider);

GraphBuilderPhase.Instance createGraphBuilderPhase(HostedProviders providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,14 @@ public static AnalysisParsedGraph parseBytecode(BigBang bb, AnalysisMethod metho
// enable this logging to get log output in compilation passes
try (Indent indent2 = debug.logAndIndent("parse graph phases")) {

GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins()).withEagerResolving(true)
GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(bb.getProviders().getGraphBuilderPlugins())
.withEagerResolving(true)
.withUnresolvedIsError(PointstoOptions.UnresolvedIsError.getValue(bb.getOptions()))
.withNodeSourcePosition(true).withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll);

/*
* We want to always disable the liveness analysis, since we want the points-to
* analysis to be as conservative as possible. The analysis results can then be
* used with the liveness analysis enabled or disabled.
*/
config = config.withRetainLocalVariables(true);
.withNodeSourcePosition(true)
.withBytecodeExceptionMode(BytecodeExceptionMode.CheckAll)
.withRetainLocalVariables(true);

config = bb.getHostVM().updateGraphBuilderConfiguration(config, method);

bb.getHostVM().createGraphBuilderPhase(bb.getProviders(), config, OptimisticOptimizations.NONE, null).apply(graph);
} catch (PermanentBailoutException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
package com.oracle.graal.pointsto.flow;

import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.graph.Node;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.typestate.TypeState;
Expand All @@ -33,7 +33,7 @@

public class MergeTypeFlow extends TypeFlow<BytecodePosition> {

public MergeTypeFlow(ValueNode node) {
public MergeTypeFlow(Node node) {
super(node.getNodeSourcePosition(), null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.graalvm.compiler.nodes.Invoke;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.LoadIndexedTypeFlow;
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
import com.oracle.graal.pointsto.meta.AnalysisMethod;

Expand All @@ -60,16 +61,8 @@ public class MethodFlowsGraph {
// points in the method
private FormalParamTypeFlow[] parameters;
private InitialParamTypeFlow[] initialParameterFlows;
private List<SourceTypeFlow> sources;
private List<LoadFieldTypeFlow> fieldLoads;
private List<LoadIndexedTypeFlow> indexedLoads;
private List<TypeFlow<?>> miscEntryFlows;

private List<NewInstanceTypeFlow> allocations;
private List<DynamicNewInstanceTypeFlow> dynamicAllocations;
private List<CloneTypeFlow> clones;
private List<MonitorEnterTypeFlow> monitorEntries;

private Map<Object, TypeFlow<?>> nodeFlows;
/*
* We keep a bci->flow mapping for instanceof and invoke flows since they are queried by the
* analysis results builder.
Expand Down Expand Up @@ -114,32 +107,9 @@ public MethodFlowsGraph(AnalysisMethod analysisMethod) {
// never linked and parsed
method.getSignature().getReturnType(method.getDeclaringClass());

// allocations
allocations = new ArrayList<>();

dynamicAllocations = new ArrayList<>();

monitorEntries = new ArrayList<>();

// clones
clones = new ArrayList<>();

// sources
sources = new ArrayList<>();

// field loads
fieldLoads = new ArrayList<>();

// indexed loads
indexedLoads = new ArrayList<>();

// misc entry inputs
miscEntryFlows = new ArrayList<>();

// instanceof
nodeFlows = new HashMap<>();
instanceOfFlows = new HashMap<>();

// invoke
invokeFlows = new HashMap<>(4, 0.75f);
nonUniqueBcis = new HashSet<>();
}
Expand Down Expand Up @@ -172,40 +142,12 @@ public void cloneOriginalFlows(BigBang bb) {
}
}

// initial parameter flows
initialParameterFlows = new InitialParamTypeFlow[originalMethodFlowsGraph.initialParameterFlows.length];

// allocations
allocations = originalMethodFlowsGraph.allocations.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// dynamic allocations
dynamicAllocations = originalMethodFlowsGraph.dynamicAllocations.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// monitor entries
monitorEntries = originalMethodFlowsGraph.monitorEntries.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// clones
clones = originalMethodFlowsGraph.clones.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// sources
sources = originalMethodFlowsGraph.sources.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// result
nodeFlows = originalMethodFlowsGraph.nodeFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));
result = originalMethodFlowsGraph.getResult() != null ? lookupCloneOf(bb, originalMethodFlowsGraph.getResult()) : null;

// field loads
fieldLoads = originalMethodFlowsGraph.fieldLoads.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// indexed loads
indexedLoads = originalMethodFlowsGraph.indexedLoads.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// instanceof
instanceOfFlows = originalMethodFlowsGraph.instanceOfFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));

// misc entry flows (merge, proxy, etc.)
miscEntryFlows = originalMethodFlowsGraph.miscEntryFlows.stream().map(f -> lookupCloneOf(bb, f)).collect(Collectors.toList());

// instanceof
invokeFlows = originalMethodFlowsGraph.invokeFlows.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> lookupCloneOf(bb, e.getValue())));

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

worklist.addAll(allocations);
worklist.addAll(dynamicAllocations);
worklist.addAll(monitorEntries);
worklist.addAll(clones);
worklist.addAll(sources);
worklist.addAll(nodeFlows.values());
worklist.addAll(miscEntryFlows);
worklist.addAll(fieldLoads);
worklist.addAll(indexedLoads);

worklist.addAll(instanceOfFlows.values());
worklist.addAll(invokeFlows.values());

Expand Down Expand Up @@ -439,55 +374,25 @@ public TypeFlow<?>[] getInitialParameterFlows() {
return initialParameterFlows;
}

public void addAllocation(NewInstanceTypeFlow allocation) {
allocations.add(allocation);
}

public List<NewInstanceTypeFlow> getAllocations() {
return allocations;
}

public void addDynamicAllocation(DynamicNewInstanceTypeFlow allocation) {
dynamicAllocations.add(allocation);
}

public List<DynamicNewInstanceTypeFlow> getDynamicAllocations() {
return dynamicAllocations;
}

public void addMonitorEntry(MonitorEnterTypeFlow monitorEntry) {
monitorEntries.add(monitorEntry);
public void addNodeFlow(Object key, TypeFlow<?> flow) {
assert flow != null && !(flow instanceof AllInstantiatedTypeFlow);
Object previous = nodeFlows.put(key, flow);
assert previous == null : "Overwriting flow for " + key + ": " + previous + " - " + flow;
}

public List<MonitorEnterTypeFlow> getMonitorEntries() {
return monitorEntries;
public Collection<TypeFlow<?>> getMiscFlows() {
return miscEntryFlows;
}

public void addClone(CloneTypeFlow clone) {
clones.add(clone);
}

public List<CloneTypeFlow> getClones() {
return clones;
}

public void addSource(SourceTypeFlow source) {
sources.add(source);
public Map<Object, TypeFlow<?>> getNodeFlows() {
return nodeFlows;
}

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

public void addFieldLoad(LoadFieldTypeFlow fieldLoad) {
fieldLoads.add(fieldLoad);
}

public void addIndexedLoad(LoadIndexedTypeFlow indexedLoad) {
indexedLoads.add(indexedLoad);
}

public void setResult(FormalReturnTypeFlow result) {
this.result = result;
}
Expand All @@ -500,7 +405,11 @@ public Set<Entry<Object, InvokeTypeFlow>> getInvokes() {
return invokeFlows.entrySet();
}

public Collection<InvokeTypeFlow> getInvokeFlows() {
public InvokeTypeFlow getInvokeFlow(Invoke invoke) {
return invokeFlows.get(invoke);
}

Collection<InvokeTypeFlow> getInvokeFlows() {
return invokeFlows.values();
}

Expand Down
Loading

0 comments on commit aa2f6e8

Please sign in to comment.