Upgrade to 3.29

Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.

Bug: 17370214

Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
new file mode 100644
index 0000000..c57ac33
--- /dev/null
+++ b/src/compiler/js-builtin-reducer.cc
@@ -0,0 +1,174 @@
+// Copyright 2014 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/graph-inl.h"
+#include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/types.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+// Helper method that assumes replacement nodes are pure values that don't
+// produce an effect. Replaces {node} with {reduction} and relaxes effects.
+static Reduction ReplaceWithPureReduction(Node* node, Reduction reduction) {
+  if (reduction.Changed()) {
+    NodeProperties::ReplaceWithValue(node, reduction.replacement());
+    return reduction;
+  }
+  return Reducer::NoChange();
+}
+
+
+// Helper class to access JSCallFunction nodes that are potential candidates
+// for reduction when they have a BuiltinFunctionId associated with them.
+class JSCallReduction {
+ public:
+  explicit JSCallReduction(Node* node) : node_(node) {}
+
+  // Determines whether the node is a JSCallFunction operation that targets a
+  // constant callee being a well-known builtin with a BuiltinFunctionId.
+  bool HasBuiltinFunctionId() {
+    if (node_->opcode() != IrOpcode::kJSCallFunction) return false;
+    HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
+    if (!m.HasValue() || !m.Value().handle()->IsJSFunction()) return false;
+    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
+    return function->shared()->HasBuiltinFunctionId();
+  }
+
+  // Retrieves the BuiltinFunctionId as described above.
+  BuiltinFunctionId GetBuiltinFunctionId() {
+    DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
+    HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
+    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
+    return function->shared()->builtin_function_id();
+  }
+
+  // Determines whether the call takes zero inputs.
+  bool InputsMatchZero() { return GetJSCallArity() == 0; }
+
+  // Determines whether the call takes one input of the given type.
+  bool InputsMatchOne(Type* t1) {
+    return GetJSCallArity() == 1 &&
+           NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1);
+  }
+
+  // Determines whether the call takes two inputs of the given types.
+  bool InputsMatchTwo(Type* t1, Type* t2) {
+    return GetJSCallArity() == 2 &&
+           NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1) &&
+           NodeProperties::GetBounds(GetJSCallInput(1)).upper->Is(t2);
+  }
+
+  // Determines whether the call takes inputs all of the given type.
+  bool InputsMatchAll(Type* t) {
+    for (int i = 0; i < GetJSCallArity(); i++) {
+      if (!NodeProperties::GetBounds(GetJSCallInput(i)).upper->Is(t)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  Node* left() { return GetJSCallInput(0); }
+  Node* right() { return GetJSCallInput(1); }
+
+  int GetJSCallArity() {
+    DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
+    // Skip first (i.e. callee) and second (i.e. receiver) operand.
+    return OperatorProperties::GetValueInputCount(node_->op()) - 2;
+  }
+
+  Node* GetJSCallInput(int index) {
+    DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
+    DCHECK_LT(index, GetJSCallArity());
+    // Skip first (i.e. callee) and second (i.e. receiver) operand.
+    return NodeProperties::GetValueInput(node_, index + 2);
+  }
+
+ private:
+  Node* node_;
+};
+
+
+// ECMA-262, section 15.8.2.17.
+Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
+  JSCallReduction r(node);
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.sqrt(a:number) -> Float64Sqrt(a)
+    Node* value = graph()->NewNode(machine()->Float64Sqrt(), r.left());
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+// ECMA-262, section 15.8.2.11.
+Reduction JSBuiltinReducer::ReduceMathMax(Node* node) {
+  JSCallReduction r(node);
+  if (r.InputsMatchZero()) {
+    // Math.max() -> -Infinity
+    return Replace(jsgraph()->Constant(-V8_INFINITY));
+  }
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.max(a:number) -> a
+    return Replace(r.left());
+  }
+  if (r.InputsMatchAll(Type::Integral32())) {
+    // Math.max(a:int32, b:int32, ...)
+    Node* value = r.GetJSCallInput(0);
+    for (int i = 1; i < r.GetJSCallArity(); i++) {
+      Node* p = r.GetJSCallInput(i);
+      Node* control = graph()->start();
+      Node* tag = graph()->NewNode(simplified()->NumberLessThan(), value, p);
+
+      Node* branch = graph()->NewNode(common()->Branch(), tag, control);
+      Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+      Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+
+      value = graph()->NewNode(common()->Phi(kMachNone, 2), p, value, merge);
+    }
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+// ES6 draft 08-24-14, section 20.2.2.19.
+Reduction JSBuiltinReducer::ReduceMathImul(Node* node) {
+  JSCallReduction r(node);
+  if (r.InputsMatchTwo(Type::Integral32(), Type::Integral32())) {
+    // Math.imul(a:int32, b:int32) -> Int32Mul(a, b)
+    Node* value = graph()->NewNode(machine()->Int32Mul(), r.left(), r.right());
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+Reduction JSBuiltinReducer::Reduce(Node* node) {
+  JSCallReduction r(node);
+
+  // Dispatch according to the BuiltinFunctionId if present.
+  if (!r.HasBuiltinFunctionId()) return NoChange();
+  switch (r.GetBuiltinFunctionId()) {
+    case kMathSqrt:
+      return ReplaceWithPureReduction(node, ReduceMathSqrt(node));
+    case kMathMax:
+      return ReplaceWithPureReduction(node, ReduceMathMax(node));
+    case kMathImul:
+      return ReplaceWithPureReduction(node, ReduceMathImul(node));
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8