Mercurial > hg > graal-compiler
changeset 8631:a5ad23f6f9ca
fixed more concurrency issues in ReplacementsImpl
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 04 Apr 2013 14:28:34 +0200 |
parents | f32fa4cdfbb1 |
children | c50bfedfb704 |
files | graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java |
diffstat | 3 files changed, 77 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java Wed Apr 03 22:52:11 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/PointerTest.java Thu Apr 04 14:28:34 2013 +0200 @@ -56,7 +56,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); } @Test
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java Wed Apr 03 22:52:11 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/WordTest.java Thu Apr 04 14:28:34 2013 +0200 @@ -50,7 +50,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); } @LongTest
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Apr 03 22:52:11 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Thu Apr 04 14:28:34 2013 +0200 @@ -54,7 +54,10 @@ private BoxingMethodPool pool; - private final ConcurrentMap<ResolvedJavaMethod, StructuredGraph> graphCache; + /** + * The preprocessed replacement graphs. + */ + private final ConcurrentMap<ResolvedJavaMethod, StructuredGraph> graphs; // These data structures are all fully initialized during single-threaded // compiler startup and so do not need to be concurrent. @@ -66,7 +69,7 @@ this.runtime = runtime; this.target = target; this.assumptions = assumptions; - this.graphCache = new ConcurrentHashMap<>(); + this.graphs = new ConcurrentHashMap<>(); this.registeredMethodSubstitutions = new HashMap<>(); this.registeredSnippets = new HashSet<>(); this.registerMacroSubstitutions = new HashMap<>(); @@ -90,10 +93,10 @@ if (!registeredSnippets.contains(method)) { return null; } - StructuredGraph graph = graphCache.get(method); + StructuredGraph graph = graphs.get(method); if (graph == null) { - graph = createGraphMaker(null, null).makeGraph(method, inliningPolicy(method)); - assert graph == graphCache.get(method); + graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method))); + graph = graphs.get(method); } return graph; @@ -104,10 +107,10 @@ if (substitute == null) { return null; } - StructuredGraph graph = graphCache.get(original); + StructuredGraph graph = graphs.get(substitute); if (graph == null) { - graph = createGraphMaker(substitute, original).makeGraph(substitute, inliningPolicy(substitute)); - assert graph == graphCache.get(substitute); + graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute))); + graph = graphs.get(substitute); } return graph; @@ -210,35 +213,80 @@ } } - public StructuredGraph makeGraph(ResolvedJavaMethod method, SnippetInliningPolicy policy) { - return createGraphMaker(null, null).makeGraph(method, policy); + /** + * Creates a preprocessed graph for a snippet or method substitution. + * + * @param method the snippet or method substitution for which a graph will be created + * @param original the original method if {@code method} is a {@linkplain MethodSubstitution + * substitution} otherwise null + * @param policy the inlining policy to use during preprocessing + */ + public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy) { + return createGraphMaker(method, original).makeGraph(policy); } + /** + * Can be overridden to return an object that specializes various parts of graph preprocessing. + */ protected GraphMaker createGraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original) { return new GraphMaker(substitute, original); } + /** + * Cache to speed up preprocessing of replacement graphs. + */ + final ConcurrentMap<ResolvedJavaMethod, StructuredGraph> graphCache = new ConcurrentHashMap<>(); + + /** + * Creates and preprocesses a graph for a replacement. + */ protected class GraphMaker { - // These fields are used to detect calls from the substitute method to the original method. - protected final ResolvedJavaMethod substitute; + /** + * The method for which a graph is being created. + */ + protected final ResolvedJavaMethod method; + + /** + * The original method if {@link #method} is a {@linkplain MethodSubstitution substitution} + * otherwise null. + */ protected final ResolvedJavaMethod original; boolean substituteCallsOriginal; protected GraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original) { - this.substitute = substitute; + this.method = substitute; this.original = original; } + public StructuredGraph makeGraph(final SnippetInliningPolicy policy) { + return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() { + + @Override + public StructuredGraph call() throws Exception { + StructuredGraph graph = parseGraph(method, policy); + + // Cannot have a finalized version of a graph in the cache + graph = graph.copy(); + + finalizeGraph(graph); + + Debug.dump(graph, "%s: Final", method.getName()); + + return graph; + } + }); + } + /** * Does final processing of a snippet graph. */ - protected void finalizeGraph(ResolvedJavaMethod method, StructuredGraph graph) { + protected void finalizeGraph(StructuredGraph graph) { new NodeIntrinsificationPhase(runtime, pool()).apply(graph); assert SnippetTemplate.hasConstantParameter(method) || NodeIntrinsificationVerificationPhase.verify(graph); - if (substitute == null) { + if (original == null) { new SnippetFrameStateCleanupPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); new InsertStateAfterPlaceholderPhase().apply(graph); @@ -247,27 +295,11 @@ } } - public StructuredGraph makeGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() { - - @Override - public StructuredGraph call() throws Exception { - StructuredGraph graph = parseGraph(method, policy); - - finalizeGraph(method, graph); - - Debug.dump(graph, "%s: Final", method.getName()); - - return graph; - } - }); - } - - private StructuredGraph parseGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - StructuredGraph graph = graphCache.get(method); + private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + StructuredGraph graph = graphCache.get(methodToParse); if (graph == null) { - graphCache.putIfAbsent(method, buildGraph(method, policy == null ? inliningPolicy(method) : policy)); - graph = graphCache.get(method); + graphCache.putIfAbsent(methodToParse, buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy)); + graph = graphCache.get(methodToParse); assert graph != null; } return graph; @@ -276,13 +308,13 @@ /** * Builds the initial graph for a snippet. */ - protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod method) { - final StructuredGraph graph = new StructuredGraph(method); + protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) { + final StructuredGraph graph = new StructuredGraph(methodToParse); GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); graphBuilder.apply(graph); - Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName()); + Debug.dump(graph, "%s: %s", methodToParse.getName(), GraphBuilderPhase.class.getSimpleName()); new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph); new NodeIntrinsificationPhase(runtime, pool()).apply(graph); @@ -317,14 +349,14 @@ } } - private StructuredGraph buildGraph(final ResolvedJavaMethod method, final SnippetInliningPolicy policy) { - assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : method; - final StructuredGraph graph = buildInitialGraph(method); + private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { + assert !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers()) : methodToParse; + final StructuredGraph graph = buildInitialGraph(methodToParse); for (Invoke invoke : graph.getInvokes()) { MethodCallTargetNode callTarget = invoke.methodCallTarget(); ResolvedJavaMethod callee = callTarget.targetMethod(); - if (callee == substitute) { + if (callee == method) { final StructuredGraph originalGraph = new StructuredGraph(original); new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); InliningUtil.inline(invoke, originalGraph, true); @@ -333,7 +365,7 @@ afterInline(graph, originalGraph); substituteCallsOriginal = true; } else { - if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, method)) { + if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && policy.shouldInline(callee, methodToParse)) { StructuredGraph targetGraph = parseGraph(callee, policy); InliningUtil.inline(invoke, targetGraph, true); Debug.dump(graph, "after inlining %s", callee);