Index: test/cctest/compiler/test-js-typed-lowering.cc |
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc |
index cc799448d3b03a254eb63a7ed0169b72f061afed..07c94af3fae033395ac622c425d8b3c599ee2b36 100644 |
--- a/test/cctest/compiler/test-js-typed-lowering.cc |
+++ b/test/cctest/compiler/test-js-typed-lowering.cc |
@@ -14,6 +14,7 @@ |
#include "src/compiler/simplified-operator.h" |
#include "src/compiler/typer.h" |
#include "test/cctest/cctest.h" |
+#include "test/cctest/compiler/function-tester.h" |
namespace v8 { |
namespace internal { |
@@ -42,6 +43,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { |
machine(main_zone()), |
simplified(main_zone()), |
common(main_zone()), |
+ deps(main_isolate(), main_zone()), |
graph(main_zone()), |
typer(main_isolate(), &graph), |
context_node(NULL) { |
@@ -57,6 +59,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { |
MachineOperatorBuilder machine; |
SimplifiedOperatorBuilder simplified; |
CommonOperatorBuilder common; |
+ CompilationDependencies deps; |
Graph graph; |
Typer typer; |
Node* context_node; |
@@ -94,7 +97,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { |
&machine); |
// TODO(titzer): mock the GraphReducer here for better unit testing. |
GraphReducer graph_reducer(main_zone(), &graph); |
- JSTypedLowering reducer(&graph_reducer, &jsgraph, main_zone()); |
+ JSTypedLowering reducer(&graph_reducer, &deps, &jsgraph, main_zone()); |
Reduction reduction = reducer.Reduce(node); |
if (reduction.Changed()) return reduction.replacement(); |
return node; |
@@ -129,6 +132,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { |
Node* Binop(const Operator* op, Node* left, Node* right) { |
// JS binops also require context, effect, and control |
+ DCHECK_EQ(op->ValueInputCount(), 2); |
std::vector<Node*> inputs; |
inputs.push_back(left); |
inputs.push_back(right); |
@@ -1264,6 +1268,46 @@ TEST_WITH_STRONG(Int32Comparisons) { |
} |
} |
+ |
+// Test that instanceOf is reduced if and only if the right-hand side is a |
+// function constant. Functional correctness is ensured elsewhere. |
+TEST(InstanceOfSpecialization) { |
Michael Starzinger
2015/11/09 19:59:59
Since these tests only check that "something is re
sigurds
2015/11/10 09:39:44
Done.
|
+ JSTypedLoweringTester R; |
+ FunctionTester F( |
+ "(function (){" |
+ " return function Bar(x){" |
+ " this.x= x;" |
+ " }" |
+ "})();"); |
+ |
+ // Reduce if left-hand side is known to be an object. |
+ Node* instanceOf = |
+ R.Binop(R.javascript.InstanceOf(), R.Parameter(Type::Object(), 0), |
+ R.HeapConstant(F.function)); |
+ Node* dummy = R.Unop(R.javascript.ToObject(), instanceOf); |
+ Node* replacement = R.reduce(instanceOf); |
+ CHECK(IrOpcode::IsPhiOpcode(replacement->opcode())); |
+ CHECK_EQ(replacement, dummy->InputAt(0)); |
+ CHECK_NE(instanceOf, dummy->InputAt(0)); |
+ |
+ // Reduce if left-hand side could be a Smi. |
+ instanceOf = R.Binop(R.javascript.InstanceOf(), R.Parameter(Type::Any(), 0), |
+ R.HeapConstant(F.function)); |
+ dummy = R.Unop(R.javascript.ToObject(), instanceOf); |
+ replacement = R.reduce(instanceOf); |
+ CHECK(IrOpcode::IsPhiOpcode(replacement->opcode())); |
+ CHECK_EQ(replacement, dummy->InputAt(0)); |
+ CHECK_NE(instanceOf, dummy->InputAt(0)); |
+ |
+ // Do not reduce if right-hand side is not a function constant. |
+ instanceOf = R.Binop(R.javascript.InstanceOf(), R.Parameter(Type::Any(), 0), |
+ R.Parameter(Type::Function(), 0)); |
+ dummy = R.Unop(R.javascript.ToObject(), instanceOf); |
+ replacement = R.reduce(instanceOf); |
+ CHECK_EQ(replacement, instanceOf); |
+ CHECK_EQ(instanceOf, dummy->InputAt(0)); |
+} |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |