Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / compiler / test-js-typed-lowering.cc
index b6aa6d9..cf126c2 100644 (file)
@@ -21,12 +21,10 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
         binop(NULL),
         unop(NULL),
         javascript(main_zone()),
-        machine(main_zone()),
         simplified(main_zone()),
         common(main_zone()),
         graph(main_zone()),
         typer(main_zone()),
-        source_positions(&graph),
         context_node(NULL) {
     typer.DecorateGraph(&graph);
     Node* s = graph.NewNode(common.Start(num_parameters));
@@ -34,15 +32,14 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
   }
 
   Isolate* isolate;
-  Operator* binop;
-  Operator* unop;
+  const Operator* binop;
+  const Operator* unop;
   JSOperatorBuilder javascript;
   MachineOperatorBuilder machine;
   SimplifiedOperatorBuilder simplified;
   CommonOperatorBuilder common;
   Graph graph;
   Typer typer;
-  SourcePositionTable source_positions;
   Node* context_node;
 
   Node* Parameter(Type* t, int32_t index = 0) {
@@ -51,9 +48,32 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
     return n;
   }
 
+  Node* UndefinedConstant() {
+    Unique<Object> unique =
+        Unique<Object>::CreateImmovable(isolate->factory()->undefined_value());
+    return graph.NewNode(common.HeapConstant(unique));
+  }
+
+  Node* HeapConstant(Handle<Object> constant) {
+    Unique<Object> unique = Unique<Object>::CreateUninitialized(constant);
+    return graph.NewNode(common.HeapConstant(unique));
+  }
+
+  Node* EmptyFrameState(Node* context) {
+    Node* parameters = graph.NewNode(common.StateValues(0));
+    Node* locals = graph.NewNode(common.StateValues(0));
+    Node* stack = graph.NewNode(common.StateValues(0));
+
+    Node* state_node =
+        graph.NewNode(common.FrameState(JS_FRAME, BailoutId(0), kIgnoreOutput),
+                      parameters, locals, stack, context, UndefinedConstant());
+
+    return state_node;
+  }
+
   Node* reduce(Node* node) {
-    JSGraph jsgraph(&graph, &common, &typer);
-    JSTypedLowering reducer(&jsgraph, &source_positions);
+    JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine);
+    JSTypedLowering reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(node);
     if (reduction.Changed()) return reduction.replacement();
     return node;
@@ -75,25 +95,25 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
     CHECK_EQ(2, node->InputCount());  // should not have context, effect, etc.
   }
 
-  void CheckPureBinop(Operator* expected, Node* node) {
+  void CheckPureBinop(const Operator* expected, Node* node) {
     CHECK_EQ(expected->opcode(), node->op()->opcode());
     CHECK_EQ(2, node->InputCount());  // should not have context, effect, etc.
   }
 
-  Node* ReduceUnop(Operator* op, Type* input_type) {
+  Node* ReduceUnop(const Operator* op, Type* input_type) {
     return reduce(Unop(op, Parameter(input_type)));
   }
 
-  Node* ReduceBinop(Operator* op, Type* left_type, Type* right_type) {
+  Node* ReduceBinop(const Operator* op, Type* left_type, Type* right_type) {
     return reduce(Binop(op, Parameter(left_type, 0), Parameter(right_type, 1)));
   }
 
-  Node* Binop(Operator* op, Node* left, Node* right) {
+  Node* Binop(const Operator* op, Node* left, Node* right) {
     // JS binops also require context, effect, and control
     return graph.NewNode(op, left, right, context(), start(), control());
   }
 
-  Node* Unop(Operator* op, Node* input) {
+  Node* Unop(const Operator* op, Node* input) {
     // JS unops also require context, effect, and control
     return graph.NewNode(op, input, context(), start(), control());
   }
@@ -110,17 +130,17 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
 
   void CheckInt32Constant(int32_t expected, Node* result) {
     CHECK_EQ(IrOpcode::kInt32Constant, result->opcode());
-    CHECK_EQ(expected, ValueOf<int32_t>(result->op()));
+    CHECK_EQ(expected, OpParameter<int32_t>(result));
   }
 
   void CheckNumberConstant(double expected, Node* result) {
     CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
-    CHECK_EQ(expected, ValueOf<double>(result->op()));
+    CHECK_EQ(expected, OpParameter<double>(result));
   }
 
   void CheckNaN(Node* result) {
     CHECK_EQ(IrOpcode::kNumberConstant, result->opcode());
-    double value = ValueOf<double>(result->op());
+    double value = OpParameter<double>(result);
     CHECK(std::isnan(value));
   }
 
@@ -134,7 +154,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
 
   void CheckHandle(Handle<Object> expected, Node* result) {
     CHECK_EQ(IrOpcode::kHeapConstant, result->opcode());
-    Handle<Object> value = ValueOf<Handle<Object> >(result->op());
+    Handle<Object> value = OpParameter<Unique<Object> >(result).handle();
     CHECK_EQ(*expected, *value);
   }
 };
@@ -154,7 +174,7 @@ static Type* kNumberTypes[] = {
     Type::OtherUnsigned32(), Type::OtherSigned32(),    Type::SignedSmall(),
     Type::Signed32(),        Type::Unsigned32(),       Type::Integral32(),
     Type::MinusZero(),       Type::NaN(),              Type::OtherNumber(),
-    Type::Number()};
+    Type::OrderedNumber(),   Type::Number()};
 
 
 static Type* kJSTypes[] = {Type::Undefined(), Type::Null(),   Type::Boolean(),
@@ -171,13 +191,15 @@ static IrOpcode::Value NumberToI32(bool is_signed) {
 }
 
 
+// TODO(turbofan): Lowering of StringAdd is disabled for now.
+#if 0
 TEST(StringBinops) {
   JSTypedLoweringTester R;
 
-  for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); ++i) {
+  for (size_t i = 0; i < arraysize(kStringTypes); ++i) {
     Node* p0 = R.Parameter(kStringTypes[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); ++j) {
+    for (size_t j = 0; j < arraysize(kStringTypes); ++j) {
       Node* p1 = R.Parameter(kStringTypes[j], 1);
 
       Node* add = R.Binop(R.javascript.Add(), p0, p1);
@@ -189,11 +211,12 @@ TEST(StringBinops) {
     }
   }
 }
+#endif
 
 
 TEST(AddNumber1) {
   JSTypedLoweringTester R;
-  for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+  for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
     Node* p0 = R.Parameter(kNumberTypes[i], 0);
     Node* p1 = R.Parameter(kNumberTypes[i], 1);
     Node* add = R.Binop(R.javascript.Add(), p0, p1);
@@ -208,7 +231,7 @@ TEST(AddNumber1) {
 
 TEST(NumberBinops) {
   JSTypedLoweringTester R;
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.Add(),      R.simplified.NumberAdd(),
       R.javascript.Subtract(), R.simplified.NumberSubtract(),
       R.javascript.Multiply(), R.simplified.NumberMultiply(),
@@ -216,13 +239,13 @@ TEST(NumberBinops) {
       R.javascript.Modulus(),  R.simplified.NumberModulus(),
   };
 
-  for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); ++i) {
+  for (size_t i = 0; i < arraysize(kNumberTypes); ++i) {
     Node* p0 = R.Parameter(kNumberTypes[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); ++j) {
+    for (size_t j = 0; j < arraysize(kNumberTypes); ++j) {
       Node* p1 = R.Parameter(kNumberTypes[j], 1);
 
-      for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+      for (size_t k = 0; k < arraysize(ops); k += 2) {
         Node* add = R.Binop(ops[k], p0, p1);
         Node* r = R.reduce(add);
 
@@ -242,7 +265,7 @@ static void CheckToI32(Node* old_input, Node* new_input, bool is_signed) {
     CHECK_EQ(old_input, new_input);
   } else if (new_input->opcode() == IrOpcode::kNumberConstant) {
     CHECK(NodeProperties::GetBounds(new_input).upper->Is(expected_type));
-    double v = ValueOf<double>(new_input->op());
+    double v = OpParameter<double>(new_input);
     double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v));
     CHECK_EQ(e, v);
   } else {
@@ -255,7 +278,7 @@ static void CheckToI32(Node* old_input, Node* new_input, bool is_signed) {
 class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
  public:
   static const int kNumberOps = 6;
-  Operator* ops[kNumberOps];
+  const Operator* ops[kNumberOps];
   bool signedness[kNumberOps];
 
   JSBitwiseShiftTypedLoweringTester() {
@@ -269,7 +292,7 @@ class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
   }
 
  private:
-  void set(int idx, Operator* op, bool s) {
+  void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
   }
@@ -286,10 +309,10 @@ TEST(Int32BitwiseShifts) {
       Type::Null(),        Type::Boolean(),       Type::Number(),
       Type::String(),      Type::Object()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+  for (size_t i = 0; i < arraysize(types); ++i) {
     Node* p0 = R.Parameter(types[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+    for (size_t j = 0; j < arraysize(types); ++j) {
       Node* p1 = R.Parameter(types[j], 1);
 
       for (int k = 0; k < R.kNumberOps; k += 2) {
@@ -315,7 +338,7 @@ TEST(Int32BitwiseShifts) {
 class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
  public:
   static const int kNumberOps = 6;
-  Operator* ops[kNumberOps];
+  const Operator* ops[kNumberOps];
   bool signedness[kNumberOps];
 
   JSBitwiseTypedLoweringTester() {
@@ -329,7 +352,7 @@ class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester {
   }
 
  private:
-  void set(int idx, Operator* op, bool s) {
+  void set(int idx, const Operator* op, bool s) {
     ops[idx] = op;
     signedness[idx] = s;
   }
@@ -346,10 +369,10 @@ TEST(Int32BitwiseBinops) {
       Type::Null(),        Type::Boolean(),       Type::Number(),
       Type::String(),      Type::Object()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); ++i) {
+  for (size_t i = 0; i < arraysize(types); ++i) {
     Node* p0 = R.Parameter(types[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(types); ++j) {
+    for (size_t j = 0; j < arraysize(types); ++j) {
       Node* p1 = R.Parameter(types[j], 1);
 
       for (int k = 0; k < R.kNumberOps; k += 2) {
@@ -368,9 +391,9 @@ TEST(Int32BitwiseBinops) {
 
 TEST(JSToNumber1) {
   JSTypedLoweringTester R;
-  Operator* ton = R.javascript.ToNumber();
+  const Operator* ton = R.javascript.ToNumber();
 
-  for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) {  // ToNumber(number)
+  for (size_t i = 0; i < arraysize(kNumberTypes); i++) {  // ToNumber(number)
     Node* r = R.ReduceUnop(ton, kNumberTypes[i]);
     CHECK_EQ(IrOpcode::kParameter, r->opcode());
   }
@@ -392,7 +415,7 @@ TEST(JSToNumber_replacement) {
 
   Type* types[] = {Type::Null(), Type::Undefined(), Type::Number()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+  for (size_t i = 0; i < arraysize(types); i++) {
     Node* n = R.Parameter(types[i]);
     Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
                               R.start(), R.start());
@@ -418,11 +441,12 @@ TEST(JSToNumber_replacement) {
 TEST(JSToNumberOfConstant) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {R.common.NumberConstant(0), R.common.NumberConstant(-1),
-                     R.common.NumberConstant(0.1), R.common.Int32Constant(1177),
-                     R.common.Float64Constant(0.99)};
+  const Operator* ops[] = {
+      R.common.NumberConstant(0), R.common.NumberConstant(-1),
+      R.common.NumberConstant(0.1), R.common.Int32Constant(1177),
+      R.common.Float64Constant(0.99)};
 
-  for (size_t i = 0; i < ARRAY_SIZE(ops); i++) {
+  for (size_t i = 0; i < arraysize(ops); i++) {
     Node* n = R.graph.NewNode(ops[i]);
     Node* convert = R.Unop(R.javascript.ToNumber(), n);
     Node* r = R.reduce(convert);
@@ -447,7 +471,7 @@ TEST(JSToNumberOfNumberOrOtherPrimitive) {
   Type* others[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
                     Type::String()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(others); i++) {
+  for (size_t i = 0; i < arraysize(others); i++) {
     Type* t = Type::Union(Type::Number(), others[i], R.main_zone());
     Node* r = R.ReduceUnop(R.javascript.ToNumber(), t);
     CHECK_EQ(IrOpcode::kJSToNumber, r->opcode());
@@ -457,7 +481,7 @@ TEST(JSToNumberOfNumberOrOtherPrimitive) {
 
 TEST(JSToBoolean) {
   JSTypedLoweringTester R;
-  Operator* op = R.javascript.ToBoolean();
+  const Operator* op = R.javascript.ToBoolean();
 
   {  // ToBoolean(undefined)
     Node* r = R.ReduceUnop(op, Type::Undefined());
@@ -474,12 +498,12 @@ TEST(JSToBoolean) {
     CHECK_EQ(IrOpcode::kParameter, r->opcode());
   }
 
-  {  // ToBoolean(number)
-    Node* r = R.ReduceUnop(op, Type::Number());
+  {  // ToBoolean(ordered-number)
+    Node* r = R.ReduceUnop(op, Type::OrderedNumber());
     CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
     Node* i = r->InputAt(0);
     CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
-    // ToBoolean(number) => BooleanNot(NumberEqual(x, #0))
+    // ToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
   }
 
   {  // ToBoolean(string)
@@ -508,10 +532,11 @@ TEST(JSToBoolean) {
 TEST(JSToBoolean_replacement) {
   JSTypedLoweringTester R;
 
-  Type* types[] = {Type::Null(), Type::Undefined(), Type::Boolean(),
+  Type* types[] = {Type::Null(),             Type::Undefined(),
+                   Type::Boolean(),          Type::OrderedNumber(),
                    Type::DetectableObject(), Type::Undetectable()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+  for (size_t i = 0; i < arraysize(types); i++) {
     Node* n = R.Parameter(types[i]);
     Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(),
                               R.start(), R.start());
@@ -523,6 +548,8 @@ TEST(JSToBoolean_replacement) {
 
     if (types[i]->Is(Type::Boolean())) {
       CHECK_EQ(n, r);
+    } else if (types[i]->Is(Type::OrderedNumber())) {
+      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
     } else {
       CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
     }
@@ -537,12 +564,12 @@ TEST(JSToBoolean_replacement) {
 TEST(JSToString1) {
   JSTypedLoweringTester R;
 
-  for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+  for (size_t i = 0; i < arraysize(kStringTypes); i++) {
     Node* r = R.ReduceUnop(R.javascript.ToString(), kStringTypes[i]);
     CHECK_EQ(IrOpcode::kParameter, r->opcode());
   }
 
-  Operator* op = R.javascript.ToString();
+  const Operator* op = R.javascript.ToString();
 
   {  // ToString(undefined) => "undefined"
     Node* r = R.ReduceUnop(op, Type::Undefined());
@@ -583,7 +610,7 @@ TEST(JSToString_replacement) {
 
   Type* types[] = {Type::Null(), Type::Undefined(), Type::String()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+  for (size_t i = 0; i < arraysize(types); i++) {
     Node* n = R.Parameter(types[i]);
     Node* c = R.graph.NewNode(R.javascript.ToString(), n, R.context(),
                               R.start(), R.start());
@@ -609,18 +636,18 @@ TEST(JSToString_replacement) {
 TEST(StringComparison) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.LessThan(),           R.simplified.StringLessThan(),
       R.javascript.LessThanOrEqual(),    R.simplified.StringLessThanOrEqual(),
       R.javascript.GreaterThan(),        R.simplified.StringLessThan(),
       R.javascript.GreaterThanOrEqual(), R.simplified.StringLessThanOrEqual()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(kStringTypes); i++) {
+  for (size_t i = 0; i < arraysize(kStringTypes); i++) {
     Node* p0 = R.Parameter(kStringTypes[i], 0);
-    for (size_t j = 0; j < ARRAY_SIZE(kStringTypes); j++) {
+    for (size_t j = 0; j < arraysize(kStringTypes); j++) {
       Node* p1 = R.Parameter(kStringTypes[j], 1);
 
-      for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+      for (size_t k = 0; k < arraysize(ops); k += 2) {
         Node* cmp = R.Binop(ops[k], p0, p1);
         Node* r = R.reduce(cmp);
 
@@ -643,6 +670,9 @@ TEST(StringComparison) {
 static void CheckIsConvertedToNumber(Node* val, Node* converted) {
   if (NodeProperties::GetBounds(val).upper->Is(Type::Number())) {
     CHECK_EQ(val, converted);
+  } else if (NodeProperties::GetBounds(val).upper->Is(Type::Boolean())) {
+    CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode());
+    CHECK_EQ(val, converted->InputAt(0));
   } else {
     if (converted->opcode() == IrOpcode::kNumberConstant) return;
     CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
@@ -654,23 +684,25 @@ static void CheckIsConvertedToNumber(Node* val, Node* converted) {
 TEST(NumberComparison) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.LessThan(),           R.simplified.NumberLessThan(),
       R.javascript.LessThanOrEqual(),    R.simplified.NumberLessThanOrEqual(),
       R.javascript.GreaterThan(),        R.simplified.NumberLessThan(),
       R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
 
-  for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
     Type* t0 = kJSTypes[i];
-    if (t0->Is(Type::String())) continue;  // skip Type::String
+    // Skip Type::String and Type::Receiver which might coerce into a string.
+    if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
     Node* p0 = R.Parameter(t0, 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(kJSTypes); j++) {
+    for (size_t j = 0; j < arraysize(kJSTypes); j++) {
       Type* t1 = kJSTypes[j];
-      if (t1->Is(Type::String())) continue;  // skip Type::String
+      // Skip Type::String and Type::Receiver which might coerce into a string.
+      if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
       Node* p1 = R.Parameter(t1, 1);
 
-      for (size_t k = 0; k < ARRAY_SIZE(ops); k += 2) {
+      for (size_t k = 0; k < arraysize(ops); k += 2) {
         Node* cmp = R.Binop(ops[k], p0, p1);
         Node* r = R.reduce(cmp);
 
@@ -696,10 +728,10 @@ TEST(MixedComparison1) {
   Type* types[] = {Type::Number(), Type::String(),
                    Type::Union(Type::Number(), Type::String(), R.main_zone())};
 
-  for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+  for (size_t i = 0; i < arraysize(types); i++) {
     Node* p0 = R.Parameter(types[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(types); j++) {
+    for (size_t j = 0; j < arraysize(types); j++) {
       Node* p1 = R.Parameter(types[j], 1);
       {
         Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
@@ -724,7 +756,7 @@ TEST(MixedComparison1) {
 TEST(ObjectComparison) {
   JSTypedLoweringTester R;
 
-  Node* p0 = R.Parameter(Type::Object(), 0);
+  Node* p0 = R.Parameter(Type::Number(), 0);
   Node* p1 = R.Parameter(Type::Object(), 1);
 
   Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
@@ -740,37 +772,48 @@ TEST(ObjectComparison) {
   Node* i0 = r->InputAt(0);
   Node* i1 = r->InputAt(1);
 
-  CHECK_NE(p0, i0);
+  CHECK_EQ(p0, i0);
   CHECK_NE(p1, i1);
-  CHECK_EQ(IrOpcode::kJSToNumber, i0->opcode());
+  CHECK_EQ(IrOpcode::kParameter, i0->opcode());
   CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode());
 
   // Check effect chain is correct.
-  R.CheckEffectInput(R.start(), i0);
-  R.CheckEffectInput(i0, i1);
+  R.CheckEffectInput(R.start(), i1);
   R.CheckEffectInput(i1, effect_use);
 }
 
 
 TEST(UnaryNot) {
   JSTypedLoweringTester R;
-  Operator* opnot = R.javascript.UnaryNot();
+  const Operator* opnot = R.javascript.UnaryNot();
 
-  for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
-    Node* r = R.ReduceUnop(opnot, kJSTypes[i]);
+  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
+    Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i]));
+    Node* use = R.graph.NewNode(R.common.Return(), orig);
+    Node* r = R.reduce(orig);
     // TODO(titzer): test will break if/when js-typed-lowering constant folds.
-    CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+    CHECK_EQ(IrOpcode::kBooleanNot, use->InputAt(0)->opcode());
+
+    if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
+      // The original node was turned into a ToBoolean.
+      CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
+    } else {
+      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
+    }
   }
 }
 
 
 TEST(RemoveToNumberEffects) {
+  FLAG_turbo_deoptimization = true;
+
   JSTypedLoweringTester R;
 
   Node* effect_use = NULL;
   for (int i = 0; i < 10; i++) {
     Node* p0 = R.Parameter(Type::Number());
     Node* ton = R.Unop(R.javascript.ToNumber(), p0);
+    Node* frame_state = R.EmptyFrameState(R.context());
     effect_use = NULL;
 
     switch (i) {
@@ -786,11 +829,11 @@ TEST(RemoveToNumberEffects) {
         effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
       case 3:
         effect_use = R.graph.NewNode(R.javascript.Add(), ton, ton, R.context(),
-                                     ton, R.start());
+                                     frame_state, ton, R.start());
         break;
       case 4:
         effect_use = R.graph.NewNode(R.javascript.Add(), p0, p0, R.context(),
-                                     ton, R.start());
+                                     frame_state, ton, R.start());
         break;
       case 5:
         effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
@@ -822,7 +865,7 @@ TEST(RemoveToNumberEffects) {
 // Helper class for testing the reduction of a single binop.
 class BinopEffectsTester {
  public:
-  explicit BinopEffectsTester(Operator* op, Type* t0, Type* t1)
+  explicit BinopEffectsTester(const Operator* op, Type* t0, Type* t1)
       : R(),
         p0(R.Parameter(t0, 0)),
         p1(R.Parameter(t1, 1)),
@@ -910,10 +953,10 @@ TEST(EqualityForNumbers) {
                                  Type::Number()};
 
 
-  for (size_t i = 0; i < ARRAY_SIZE(simple_number_types); ++i) {
+  for (size_t i = 0; i < arraysize(simple_number_types); ++i) {
     Node* p0 = R.Parameter(simple_number_types[i], 0);
 
-    for (size_t j = 0; j < ARRAY_SIZE(simple_number_types); ++j) {
+    for (size_t j = 0; j < arraysize(simple_number_types); ++j) {
       Node* p1 = R.Parameter(simple_number_types[j], 1);
 
       CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kNumberEqual);
@@ -930,7 +973,7 @@ TEST(StrictEqualityForRefEqualTypes) {
                    Type::Object(), Type::Receiver()};
 
   Node* p0 = R.Parameter(Type::Any());
-  for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
+  for (size_t i = 0; i < arraysize(types); i++) {
     Node* p1 = R.Parameter(types[i]);
     CheckEqualityReduction(&R, true, p0, p1, IrOpcode::kReferenceEqual);
   }
@@ -951,7 +994,7 @@ TEST(StringEquality) {
 TEST(RemovePureNumberBinopEffects) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.Equal(),           R.simplified.NumberEqual(),
       R.javascript.Add(),             R.simplified.NumberAdd(),
       R.javascript.Subtract(),        R.simplified.NumberSubtract(),
@@ -962,7 +1005,7 @@ TEST(RemovePureNumberBinopEffects) {
       R.javascript.LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
   };
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
     BinopEffectsTester B(ops[j], Type::Number(), Type::Number());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
 
@@ -979,14 +1022,14 @@ TEST(RemovePureNumberBinopEffects) {
 TEST(OrderNumberBinopEffects1) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.Subtract(), R.simplified.NumberSubtract(),
       R.javascript.Multiply(), R.simplified.NumberMultiply(),
       R.javascript.Divide(),   R.simplified.NumberDivide(),
       R.javascript.Modulus(),  R.simplified.NumberModulus(),
   };
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
     BinopEffectsTester B(ops[j], Type::Object(), Type::String());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
 
@@ -1005,7 +1048,7 @@ TEST(OrderNumberBinopEffects1) {
 TEST(OrderNumberBinopEffects2) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.Add(),      R.simplified.NumberAdd(),
       R.javascript.Subtract(), R.simplified.NumberSubtract(),
       R.javascript.Multiply(), R.simplified.NumberMultiply(),
@@ -1013,8 +1056,8 @@ TEST(OrderNumberBinopEffects2) {
       R.javascript.Modulus(),  R.simplified.NumberModulus(),
   };
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
+    BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());
 
     Node* i0 = B.CheckNoOp(0);
     Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
@@ -1026,8 +1069,8 @@ TEST(OrderNumberBinopEffects2) {
     B.CheckEffectOrdering(i1);
   }
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());
 
     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
     Node* i1 = B.CheckNoOp(1);
@@ -1044,13 +1087,13 @@ TEST(OrderNumberBinopEffects2) {
 TEST(OrderCompareEffects) {
   JSTypedLoweringTester R;
 
-  Operator* ops[] = {
+  const Operator* ops[] = {
       R.javascript.GreaterThan(), R.simplified.NumberLessThan(),
       R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
   };
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Object(), Type::String());
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::String());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
 
     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
@@ -1064,8 +1107,8 @@ TEST(OrderCompareEffects) {
     B.CheckEffectOrdering(i1, i0);
   }
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Number(), Type::Object());
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
+    BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());
 
     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
     Node* i1 = B.result->InputAt(1);
@@ -1077,8 +1120,8 @@ TEST(OrderCompareEffects) {
     B.CheckEffectOrdering(i0);
   }
 
-  for (size_t j = 0; j < ARRAY_SIZE(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Object(), Type::Number());
+  for (size_t j = 0; j < arraysize(ops); j += 2) {
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());
 
     Node* i0 = B.result->InputAt(0);
     Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
@@ -1177,25 +1220,25 @@ TEST(Int32BinopEffects) {
 
 TEST(UnaryNotEffects) {
   JSTypedLoweringTester R;
-  Operator* opnot = R.javascript.UnaryNot();
+  const Operator* opnot = R.javascript.UnaryNot();
 
-  for (size_t i = 0; i < ARRAY_SIZE(kJSTypes); i++) {
+  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
     Node* p0 = R.Parameter(kJSTypes[i], 0);
     Node* orig = R.Unop(opnot, p0);
     Node* effect_use = R.UseForEffect(orig);
     Node* value_use = R.graph.NewNode(R.common.Return(), orig);
     Node* r = R.reduce(orig);
     // TODO(titzer): test will break if/when js-typed-lowering constant folds.
-    CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-
-    CHECK_EQ(r, value_use->InputAt(0));
+    CHECK_EQ(IrOpcode::kBooleanNot, value_use->InputAt(0)->opcode());
 
-    if (r->InputAt(0) == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
+    if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
       // The original node was turned into a ToBoolean, which has an effect.
+      CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
       R.CheckEffectInput(R.start(), orig);
       R.CheckEffectInput(orig, effect_use);
     } else {
       // effect should have been removed from this node.
+      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
       R.CheckEffectInput(R.start(), effect_use);
     }
   }
@@ -1207,9 +1250,9 @@ TEST(Int32AddNarrowing) {
     JSBitwiseTypedLoweringTester R;
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
-      for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+      for (size_t i = 0; i < arraysize(kInt32Types); i++) {
         Node* n0 = R.Parameter(kInt32Types[i]);
-        for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+        for (size_t j = 0; j < arraysize(kInt32Types); j++) {
           Node* n1 = R.Parameter(kInt32Types[j]);
           Node* one = R.graph.NewNode(R.common.NumberConstant(1));
 
@@ -1234,9 +1277,9 @@ TEST(Int32AddNarrowing) {
     JSBitwiseShiftTypedLoweringTester R;
 
     for (int o = 0; o < R.kNumberOps; o += 2) {
-      for (size_t i = 0; i < ARRAY_SIZE(kInt32Types); i++) {
+      for (size_t i = 0; i < arraysize(kInt32Types); i++) {
         Node* n0 = R.Parameter(kInt32Types[i]);
-        for (size_t j = 0; j < ARRAY_SIZE(kInt32Types); j++) {
+        for (size_t j = 0; j < arraysize(kInt32Types); j++) {
           Node* n1 = R.Parameter(kInt32Types[j]);
           Node* one = R.graph.NewNode(R.common.NumberConstant(1));
 
@@ -1289,10 +1332,10 @@ TEST(Int32Comparisons) {
   JSTypedLoweringTester R;
 
   struct Entry {
-    Operator* js_op;
-    Operator* uint_op;
-    Operator* int_op;
-    Operator* num_op;
+    const Operator* js_op;
+    const Operator* uint_op;
+    const Operator* int_op;
+    const Operator* num_op;
     bool commute;
   };
 
@@ -1308,19 +1351,19 @@ TEST(Int32Comparisons) {
        R.machine.Int32LessThanOrEqual(), R.simplified.NumberLessThanOrEqual(),
        true}};
 
-  for (size_t o = 0; o < ARRAY_SIZE(ops); o++) {
-    for (size_t i = 0; i < ARRAY_SIZE(kNumberTypes); i++) {
+  for (size_t o = 0; o < arraysize(ops); o++) {
+    for (size_t i = 0; i < arraysize(kNumberTypes); i++) {
       Type* t0 = kNumberTypes[i];
       Node* p0 = R.Parameter(t0, 0);
 
-      for (size_t j = 0; j < ARRAY_SIZE(kNumberTypes); j++) {
+      for (size_t j = 0; j < arraysize(kNumberTypes); j++) {
         Type* t1 = kNumberTypes[j];
         Node* p1 = R.Parameter(t1, 1);
 
         Node* cmp = R.Binop(ops[o].js_op, p0, p1);
         Node* r = R.reduce(cmp);
 
-        Operator* expected;
+        const Operator* expected;
         if (t0->Is(Type::Unsigned32()) && t1->Is(Type::Unsigned32())) {
           expected = ops[o].uint_op;
         } else if (t0->Is(Type::Signed32()) && t1->Is(Type::Signed32())) {