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();