Index: test/unittests/compiler/js-type-feedback-unittest.cc |
diff --git a/test/unittests/compiler/js-type-feedback-unittest.cc b/test/unittests/compiler/js-type-feedback-unittest.cc |
index c243c5f088ea78197f658ce237774ecb2cfff670..2691d3f822dfb4fd53e7a64706214fb4f0c01f25 100644 |
--- a/test/unittests/compiler/js-type-feedback-unittest.cc |
+++ b/test/unittests/compiler/js-type-feedback-unittest.cc |
@@ -34,7 +34,8 @@ class JSTypeFeedbackTest : public TypedGraphTest { |
~JSTypeFeedbackTest() override { dependencies_.Rollback(); } |
protected: |
- Reduction Reduce(Node* node) { |
+ Reduction Reduce(Node* node, |
+ JSTypeFeedbackSpecializer::DeoptimizationMode mode) { |
Handle<GlobalObject> global_object( |
isolate()->native_context()->global_object(), isolate()); |
@@ -44,7 +45,7 @@ class JSTypeFeedbackTest : public TypedGraphTest { |
// TODO(titzer): mock the GraphReducer here for better unit testing. |
GraphReducer graph_reducer(graph(), zone()); |
JSTypeFeedbackSpecializer reducer(&graph_reducer, &jsgraph, &table, nullptr, |
- global_object, &dependencies_); |
+ global_object, mode, &dependencies_); |
return reducer.Reduce(node); |
} |
@@ -73,8 +74,9 @@ class JSTypeFeedbackTest : public TypedGraphTest { |
result.Assert(); |
} |
- Node* ReturnLoadNamedFromGlobal(const char* string, Node* effect, |
- Node* control) { |
+ Node* ReturnLoadNamedFromGlobal( |
+ const char* string, Node* effect, Node* control, |
+ JSTypeFeedbackSpecializer::DeoptimizationMode mode) { |
VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(), |
FeedbackVectorICSlot::Invalid()); |
Node* global = Parameter(Type::GlobalObject()); |
@@ -84,7 +86,7 @@ class JSTypeFeedbackTest : public TypedGraphTest { |
isolate()->factory()->NewStringFromAsciiChecked(string)); |
const Operator* op = javascript()->LoadNamed(name, feedback); |
Node* load = graph()->NewNode(op, global, context); |
- if (FLAG_turbo_deoptimization) { |
+ if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { |
for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); |
i++) { |
load->AppendInput(zone(), EmptyFrameState()); |
@@ -103,180 +105,240 @@ class JSTypeFeedbackTest : public TypedGraphTest { |
CompilationDependencies dependencies_; |
}; |
-#define WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION \ |
- for (int i = FLAG_turbo_deoptimization = 0; i < 2; \ |
- FLAG_turbo_deoptimization = ++i) |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) { |
+ const int kValue = 111; |
+ const char* kName = "banana"; |
+ SetGlobalProperty(kName, kValue); |
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_smi) { |
- const int const_value = 111; |
- const char* property_name = "banana"; |
- SetGlobalProperty(property_name, const_value); |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { |
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), |
- graph()->start()); |
- graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ EXPECT_FALSE(r.Changed()); |
+ EXPECT_TRUE(dependencies()->IsEmpty()); |
+} |
- Reduction r = Reduce(ret->InputAt(0)); |
- if (FLAG_turbo_deoptimization) { |
- // Check LoadNamed(global) => HeapConstant[const_value] |
- ASSERT_TRUE(r.Changed()); |
- EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) { |
+ const int kValue = 111; |
+ const char* kName = "banana"; |
+ SetGlobalProperty(kName, kValue); |
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), |
- graph()->start())); |
- EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- EXPECT_FALSE(dependencies()->IsEmpty()); |
- dependencies()->Rollback(); |
- } else { |
- ASSERT_FALSE(r.Changed()); |
- EXPECT_TRUE(dependencies()->IsEmpty()); |
- } |
- } |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ |
+ // Check LoadNamed(global) => HeapConstant[kValue] |
+ ASSERT_TRUE(r.Changed()); |
+ EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
+ |
+ EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
+ graph()->start())); |
+ EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ |
+ EXPECT_FALSE(dependencies()->IsEmpty()); |
+ dependencies()->Rollback(); |
} |
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_derble) { |
- const double const_value = -11.25; |
- const char* property_name = "kiwi"; |
- SetGlobalProperty(property_name, const_value); |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) { |
+ const double kValue = -11.25; |
+ const char* kName = "kiwi"; |
+ SetGlobalProperty(kName, kValue); |
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { |
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), |
- graph()->start()); |
- graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- Reduction r = Reduce(ret->InputAt(0)); |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
- if (FLAG_turbo_deoptimization) { |
- // Check LoadNamed(global) => HeapConstant[const_value] |
- ASSERT_TRUE(r.Changed()); |
- EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); |
+ EXPECT_FALSE(r.Changed()); |
+ EXPECT_TRUE(dependencies()->IsEmpty()); |
+} |
- EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), |
- graph()->start())); |
- EXPECT_THAT(graph()->end(), IsEnd(ret)); |
- EXPECT_FALSE(dependencies()->IsEmpty()); |
- } else { |
- ASSERT_FALSE(r.Changed()); |
- EXPECT_TRUE(dependencies()->IsEmpty()); |
- } |
- } |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) { |
+ const double kValue = -11.25; |
+ const char* kName = "kiwi"; |
+ SetGlobalProperty(kName, kValue); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ |
+ // Check LoadNamed(global) => HeapConstant[kValue] |
+ ASSERT_TRUE(r.Changed()); |
+ EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
+ |
+ EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
+ graph()->start())); |
+ EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ |
+ EXPECT_FALSE(dependencies()->IsEmpty()); |
} |
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_string) { |
- Unique<HeapObject> const_value = Unique<HeapObject>::CreateImmovable( |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { |
+ Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
isolate()->factory()->undefined_string()); |
- const char* property_name = "mango"; |
- SetGlobalProperty(property_name, const_value.handle()); |
- |
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { |
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), |
- graph()->start()); |
- graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- |
- Reduction r = Reduce(ret->InputAt(0)); |
- |
- if (FLAG_turbo_deoptimization) { |
- // Check LoadNamed(global) => HeapConstant[const_value] |
- ASSERT_TRUE(r.Changed()); |
- EXPECT_THAT(r.replacement(), IsHeapConstant(const_value)); |
- |
- EXPECT_THAT(ret, IsReturn(IsHeapConstant(const_value), graph()->start(), |
- graph()->start())); |
- EXPECT_THAT(graph()->end(), IsEnd(ret)); |
- |
- EXPECT_FALSE(dependencies()->IsEmpty()); |
- dependencies()->Rollback(); |
- } else { |
- ASSERT_FALSE(r.Changed()); |
- EXPECT_TRUE(dependencies()->IsEmpty()); |
- } |
- } |
+ const char* kName = "mango"; |
+ SetGlobalProperty(kName, kValue.handle()); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ ASSERT_FALSE(r.Changed()); |
+ EXPECT_TRUE(dependencies()->IsEmpty()); |
} |
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_smi) { |
- const char* property_name = "melon"; |
- SetGlobalProperty(property_name, 123); |
- SetGlobalProperty(property_name, 124); |
- |
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { |
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), |
- graph()->start()); |
- graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- |
- Reduction r = Reduce(ret->InputAt(0)); |
- |
- if (FLAG_turbo_deoptimization) { |
- // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
- ASSERT_TRUE(r.Changed()); |
- FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
- Capture<Node*> cell_capture; |
- Matcher<Node*> load_field_match = IsLoadField( |
- access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
- EXPECT_THAT(r.replacement(), load_field_match); |
- |
- HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
- EXPECT_TRUE(cell.HasValue()); |
- EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
- |
- EXPECT_THAT( |
- ret, IsReturn(load_field_match, load_field_match, graph()->start())); |
- EXPECT_THAT(graph()->end(), IsEnd(ret)); |
- |
- EXPECT_FALSE(dependencies()->IsEmpty()); |
- dependencies()->Rollback(); |
- } else { |
- ASSERT_FALSE(r.Changed()); |
- EXPECT_TRUE(dependencies()->IsEmpty()); |
- } |
- } |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { |
+ Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
+ isolate()->factory()->undefined_string()); |
+ const char* kName = "mango"; |
+ SetGlobalProperty(kName, kValue.handle()); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ |
+ // Check LoadNamed(global) => HeapConstant[kValue] |
+ ASSERT_TRUE(r.Changed()); |
+ EXPECT_THAT(r.replacement(), IsHeapConstant(kValue)); |
+ |
+ EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(), |
+ graph()->start())); |
+ EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ |
+ EXPECT_FALSE(dependencies()->IsEmpty()); |
+ dependencies()->Rollback(); |
} |
-TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_string) { |
- const char* property_name = "pineapple"; |
- SetGlobalProperty(property_name, isolate()->factory()->undefined_string()); |
- SetGlobalProperty(property_name, isolate()->factory()->undefined_value()); |
- |
- WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { |
- Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), |
- graph()->start()); |
- graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
- |
- Reduction r = Reduce(ret->InputAt(0)); |
- |
- if (FLAG_turbo_deoptimization) { |
- // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
- ASSERT_TRUE(r.Changed()); |
- FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
- Capture<Node*> cell_capture; |
- Matcher<Node*> load_field_match = IsLoadField( |
- access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
- EXPECT_THAT(r.replacement(), load_field_match); |
- |
- HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
- EXPECT_TRUE(cell.HasValue()); |
- EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
- |
- EXPECT_THAT( |
- ret, IsReturn(load_field_match, load_field_match, graph()->start())); |
- EXPECT_THAT(graph()->end(), IsEnd(ret)); |
- |
- EXPECT_FALSE(dependencies()->IsEmpty()); |
- dependencies()->Rollback(); |
- } else { |
- ASSERT_FALSE(r.Changed()); |
- EXPECT_TRUE(dependencies()->IsEmpty()); |
- } |
- } |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) { |
+ const char* kName = "melon"; |
+ SetGlobalProperty(kName, 123); |
+ SetGlobalProperty(kName, 124); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ ASSERT_FALSE(r.Changed()); |
+ EXPECT_TRUE(dependencies()->IsEmpty()); |
} |
+ |
+ |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) { |
+ const char* kName = "melon"; |
+ SetGlobalProperty(kName, 123); |
+ SetGlobalProperty(kName, 124); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ |
+ // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
+ ASSERT_TRUE(r.Changed()); |
+ FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
+ Capture<Node*> cell_capture; |
+ Matcher<Node*> load_field_match = IsLoadField( |
+ access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
+ EXPECT_THAT(r.replacement(), load_field_match); |
+ |
+ HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
+ EXPECT_TRUE(cell.HasValue()); |
+ EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
+ |
+ EXPECT_THAT(ret, |
+ IsReturn(load_field_match, load_field_match, graph()->start())); |
+ EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ |
+ EXPECT_FALSE(dependencies()->IsEmpty()); |
+ dependencies()->Rollback(); |
} |
+ |
+ |
+TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) { |
+ const char* kName = "pineapple"; |
+ SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
+ SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
+ ASSERT_FALSE(r.Changed()); |
+ EXPECT_TRUE(dependencies()->IsEmpty()); |
} |
+ |
+ |
+TEST_F(JSTypeFeedbackTest, |
+ JSLoadNamedGlobalPropertyCellStringWithDeoptimization) { |
+ const char* kName = "pineapple"; |
+ SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
+ SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
+ |
+ Node* ret = ReturnLoadNamedFromGlobal( |
+ kName, graph()->start(), graph()->start(), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ graph()->SetEnd(graph()->NewNode(common()->End(), ret)); |
+ |
+ Reduction r = Reduce(ret->InputAt(0), |
+ JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
+ |
+ // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
+ ASSERT_TRUE(r.Changed()); |
+ FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
+ Capture<Node*> cell_capture; |
+ Matcher<Node*> load_field_match = IsLoadField( |
+ access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
+ EXPECT_THAT(r.replacement(), load_field_match); |
+ |
+ HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
+ EXPECT_TRUE(cell.HasValue()); |
+ EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
+ |
+ EXPECT_THAT(ret, |
+ IsReturn(load_field_match, load_field_match, graph()->start())); |
+ EXPECT_THAT(graph()->end(), IsEnd(ret)); |
+ |
+ EXPECT_FALSE(dependencies()->IsEmpty()); |
+ dependencies()->Rollback(); |
} |
+ |
+} // namespace compiler |
+} // namespace internal |
+} // namespace v8 |