[turbofan] Disable recursive inlining for now.
authorbmeurer <bmeurer@chromium.org>
Tue, 30 Jun 2015 11:05:03 +0000 (04:05 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 30 Jun 2015 11:05:16 +0000 (11:05 +0000)
The deoptimizer (and probably various other places) cannot deal properly
with recursive function inlining, so we disallow it in TurboFan as well.
We might want to reconsider that decision at some point in the future.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1211243007

Cr-Commit-Position: refs/heads/master@{#29374}

src/compiler/js-inlining.cc
test/cctest/compiler/test-run-inlining.cc

index 6d7de1d..1251952 100644 (file)
@@ -251,6 +251,23 @@ Reduction JSInliner::Reduce(Node* node) {
     return NoChange();
   }
 
+  // TODO(turbofan): TranslatedState::GetAdaptedArguments() currently relies on
+  // not inlining recursive functions. We might want to relax that at some
+  // point.
+  for (Node* frame_state = call.frame_state();
+       frame_state->opcode() == IrOpcode::kFrameState;
+       frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) {
+    FrameStateInfo const& info = OpParameter<FrameStateInfo>(frame_state);
+    Handle<SharedFunctionInfo> shared_info;
+    if (info.shared_info().ToHandle(&shared_info) &&
+        *shared_info == function->shared()) {
+      TRACE("Not inlining %s into %s because call is recursive\n",
+            function->shared()->DebugName()->ToCString().get(),
+            info_->shared_info()->DebugName()->ToCString().get());
+      return NoChange();
+    }
+  }
+
   Zone zone;
   ParseInfo parse_info(&zone, function);
   CompilationInfo info(&parse_info);
index 76cd4a8..7f8ae25 100644 (file)
@@ -541,4 +541,38 @@ TEST(StrongModeArityOuter) {
   T.CheckThrows(T.undefined(), T.undefined());
 }
 
+
+TEST(InlineSelfRecursive) {
+  FunctionTester T(
+      "(function () {"
+      "  function foo(x) { "
+      "    AssertInlineCount(1);"
+      "    if (x == 1) return foo(12);"
+      "    return x;"
+      "  }"
+      "  return foo;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(12), T.Val(1));
+}
+
+
+TEST(InlineMutuallyRecursive) {
+  FunctionTester T(
+      "(function () {"
+      "  function bar(x) { AssertInlineCount(2); return foo(x); }"
+      "  function foo(x) { "
+      "    if (x == 1) return bar(42);"
+      "    return x;"
+      "  }"
+      "  return foo;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(42), T.Val(1));
+}
+
 #endif  // V8_TURBOFAN_TARGET