Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/compiler/tail-call-optimization.cc b/src/compiler/tail-call-optimization.cc
new file mode 100644
index 0000000..6635fb9
--- /dev/null
+++ b/src/compiler/tail-call-optimization.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/tail-call-optimization.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction TailCallOptimization::Reduce(Node* node) {
+  if (node->opcode() != IrOpcode::kReturn) return NoChange();
+  // The value which is returned must be the result of a potential tail call,
+  // there must be no try/catch/finally around the Call, and there must be no
+  // other effect between the Call and the Return nodes.
+  Node* const call = NodeProperties::GetValueInput(node, 0);
+  if (call->opcode() == IrOpcode::kCall &&
+      OpParameter<CallDescriptor const*>(call)->SupportsTailCalls() &&
+      NodeProperties::GetEffectInput(node) == call &&
+      !NodeProperties::IsExceptionalCall(call)) {
+    Node* const control = NodeProperties::GetControlInput(node);
+    if (control->opcode() == IrOpcode::kIfSuccess &&
+        call->OwnedBy(node, control) && control->OwnedBy(node)) {
+      // Furthermore, control has to flow via an IfSuccess from the Call, so
+      // the Return node value and effect depends directly on the Call node,
+      // and indirectly control depends on the Call via an IfSuccess.
+
+      // Value1 ... ValueN Effect Control
+      //   ^          ^      ^       ^
+      //   |          |      |       |
+      //   |          +--+ +-+       |
+      //   +----------+  | |  +------+
+      //               \ | | /
+      //             Call[Descriptor]
+      //                ^ ^ ^
+      //                | | |
+      //              +-+ | |
+      //              |   | |
+      //              | +-+ |
+      //              | | IfSuccess
+      //              | |  ^
+      //              | |  |
+      //              Return
+      //                ^
+      //                |
+
+      // The resulting graph looks like this:
+
+      // Value1 ... ValueN Effect Control
+      //   ^          ^      ^       ^
+      //   |          |      |       |
+      //   |          +--+ +-+       |
+      //   +----------+  | |  +------+
+      //               \ | | /
+      //           TailCall[Descriptor]
+      //                 ^
+      //                 |
+
+      DCHECK_EQ(call, NodeProperties::GetControlInput(control, 0));
+      DCHECK_EQ(3, node->InputCount());
+      node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
+      node->ReplaceInput(1, NodeProperties::GetControlInput(call));
+      node->RemoveInput(2);
+      for (int index = 0; index < call->op()->ValueInputCount(); ++index) {
+        node->InsertInput(graph()->zone(), index,
+                          NodeProperties::GetValueInput(call, index));
+      }
+      NodeProperties::ChangeOp(
+          node, common()->TailCall(OpParameter<CallDescriptor const*>(call)));
+      return Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8