Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java @ 15050:90e8e3b90558
prevent recursive inlining when a method substitution calls the original (i.e., substituted) method
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 09 Apr 2014 21:10:52 +0200 |
parents | db4254246f9a |
children | 04f1723150b4 |
comparison
equal
deleted
inserted
replaced
15049:f4186cbd8a20 | 15050:90e8e3b90558 |
---|---|
37 import com.oracle.graal.api.replacements.*; | 37 import com.oracle.graal.api.replacements.*; |
38 import com.oracle.graal.debug.*; | 38 import com.oracle.graal.debug.*; |
39 import com.oracle.graal.debug.Debug.Scope; | 39 import com.oracle.graal.debug.Debug.Scope; |
40 import com.oracle.graal.debug.internal.*; | 40 import com.oracle.graal.debug.internal.*; |
41 import com.oracle.graal.graph.*; | 41 import com.oracle.graal.graph.*; |
42 import com.oracle.graal.graph.Graph.Mark; | |
42 import com.oracle.graal.java.*; | 43 import com.oracle.graal.java.*; |
43 import com.oracle.graal.java.GraphBuilderPhase.Instance; | 44 import com.oracle.graal.java.GraphBuilderPhase.Instance; |
44 import com.oracle.graal.nodes.*; | 45 import com.oracle.graal.nodes.*; |
45 import com.oracle.graal.nodes.java.*; | 46 import com.oracle.graal.nodes.java.*; |
46 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; | 47 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; |
458 } | 459 } |
459 } | 460 } |
460 | 461 |
461 private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) { | 462 private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) { |
462 assert inliningDepth < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded"; | 463 assert inliningDepth < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded"; |
463 assert isInlinableSnippet(methodToParse) : methodToParse; | 464 assert isInlinable(methodToParse) : methodToParse; |
464 final StructuredGraph graph = buildInitialGraph(methodToParse); | 465 final StructuredGraph graph = buildInitialGraph(methodToParse); |
465 try (Scope s = Debug.scope("buildGraph", graph)) { | 466 try (Scope s = Debug.scope("buildGraph", graph)) { |
466 | 467 Set<MethodCallTargetNode> doNotInline = null; |
467 for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) { | 468 for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) { |
469 if (doNotInline != null && doNotInline.contains(callTarget)) { | |
470 continue; | |
471 } | |
468 ResolvedJavaMethod callee = callTarget.targetMethod(); | 472 ResolvedJavaMethod callee = callTarget.targetMethod(); |
469 if (callee.equals(recursiveEntry)) { | 473 if (callee.equals(recursiveEntry)) { |
470 if (isInlinableSnippet(substitutedMethod)) { | 474 if (isInlinable(substitutedMethod)) { |
471 final StructuredGraph originalGraph = buildInitialGraph(substitutedMethod); | 475 final StructuredGraph originalGraph = buildInitialGraph(substitutedMethod); |
476 Mark mark = graph.getMark(); | |
472 InliningUtil.inline(callTarget.invoke(), originalGraph, true); | 477 InliningUtil.inline(callTarget.invoke(), originalGraph, true); |
473 | 478 for (MethodCallTargetNode inlinedCallTarget : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) { |
479 if (doNotInline == null) { | |
480 doNotInline = new HashSet<>(); | |
481 } | |
482 // We do not want to do further inlining (now) for calls | |
483 // in the original method as this can cause unlimited | |
484 // recursive inlining given an eager inlining policy such | |
485 // as DefaultSnippetInliningPolicy. | |
486 doNotInline.add(inlinedCallTarget); | |
487 } | |
474 Debug.dump(graph, "after inlining %s", callee); | 488 Debug.dump(graph, "after inlining %s", callee); |
475 afterInline(graph, originalGraph, null); | 489 afterInline(graph, originalGraph, null); |
476 } | 490 } |
477 } else { | 491 } else { |
478 Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(ReplacementsImpl.this, callee); | 492 Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(ReplacementsImpl.this, callee); |
514 } | 528 } |
515 return graph; | 529 return graph; |
516 } | 530 } |
517 } | 531 } |
518 | 532 |
519 private static boolean isInlinableSnippet(final ResolvedJavaMethod methodToParse) { | 533 private static boolean isInlinable(final ResolvedJavaMethod method) { |
520 return !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers()); | 534 return !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()); |
521 } | 535 } |
522 | 536 |
523 private static String originalName(Method substituteMethod, String methodSubstitution) { | 537 private static String originalName(Method substituteMethod, String methodSubstitution) { |
524 if (methodSubstitution.isEmpty()) { | 538 if (methodSubstitution.isEmpty()) { |
525 return substituteMethod.getName(); | 539 return substituteMethod.getName(); |