| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler.h" | 5 #include "src/compiler.h" |
| 6 | 6 |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
| 10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 } | 75 } |
| 76 | 76 |
| 77 Node* ReturnLoadNamedFromGlobal( | 77 Node* ReturnLoadNamedFromGlobal( |
| 78 const char* string, Node* effect, Node* control, | 78 const char* string, Node* effect, Node* control, |
| 79 JSTypeFeedbackSpecializer::DeoptimizationMode mode) { | 79 JSTypeFeedbackSpecializer::DeoptimizationMode mode) { |
| 80 VectorSlotPair feedback; | 80 VectorSlotPair feedback; |
| 81 Node* global = UndefinedConstant(); | 81 Node* global = UndefinedConstant(); |
| 82 Node* vector = UndefinedConstant(); | 82 Node* vector = UndefinedConstant(); |
| 83 Node* context = UndefinedConstant(); | 83 Node* context = UndefinedConstant(); |
| 84 | 84 |
| 85 Unique<Name> name = Unique<Name>::CreateUninitialized( | 85 Handle<Name> name = isolate()->factory()->InternalizeUtf8String(string); |
| 86 isolate()->factory()->InternalizeUtf8String(string)); | |
| 87 const Operator* op = javascript()->LoadGlobal(name, feedback); | 86 const Operator* op = javascript()->LoadGlobal(name, feedback); |
| 88 Node* load = graph()->NewNode(op, context, global, vector, context); | 87 Node* load = graph()->NewNode(op, context, global, vector, context); |
| 89 if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { | 88 if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { |
| 90 for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); | 89 for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); |
| 91 i++) { | 90 i++) { |
| 92 load->AppendInput(zone(), EmptyFrameState()); | 91 load->AppendInput(zone(), EmptyFrameState()); |
| 93 } | 92 } |
| 94 } | 93 } |
| 95 load->AppendInput(zone(), effect); | 94 load->AppendInput(zone(), effect); |
| 96 load->AppendInput(zone(), control); | 95 load->AppendInput(zone(), control); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 185 |
| 187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), | 186 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
| 188 graph()->start())); | 187 graph()->start())); |
| 189 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 188 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 190 | 189 |
| 191 EXPECT_FALSE(dependencies()->IsEmpty()); | 190 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 192 } | 191 } |
| 193 | 192 |
| 194 | 193 |
| 195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { | 194 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { |
| 196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 195 Handle<HeapObject> kValue = isolate()->factory()->undefined_string(); |
| 197 isolate()->factory()->undefined_string()); | |
| 198 const char* kName = "mango"; | 196 const char* kName = "mango"; |
| 199 SetGlobalProperty(kName, kValue.handle()); | 197 SetGlobalProperty(kName, kValue); |
| 200 | 198 |
| 201 Node* ret = ReturnLoadNamedFromGlobal( | 199 Node* ret = ReturnLoadNamedFromGlobal( |
| 202 kName, graph()->start(), graph()->start(), | 200 kName, graph()->start(), graph()->start(), |
| 203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 201 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 204 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); | 202 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 205 | 203 |
| 206 Reduction r = Reduce(ret->InputAt(0), | 204 Reduction r = Reduce(ret->InputAt(0), |
| 207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 205 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 208 ASSERT_FALSE(r.Changed()); | 206 ASSERT_FALSE(r.Changed()); |
| 209 EXPECT_TRUE(dependencies()->IsEmpty()); | 207 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 210 } | 208 } |
| 211 | 209 |
| 212 | 210 |
| 213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { | 211 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { |
| 214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 212 Handle<HeapObject> kValue = isolate()->factory()->undefined_string(); |
| 215 isolate()->factory()->undefined_string()); | |
| 216 const char* kName = "mango"; | 213 const char* kName = "mango"; |
| 217 SetGlobalProperty(kName, kValue.handle()); | 214 SetGlobalProperty(kName, kValue); |
| 218 | 215 |
| 219 Node* ret = ReturnLoadNamedFromGlobal( | 216 Node* ret = ReturnLoadNamedFromGlobal( |
| 220 kName, graph()->start(), graph()->start(), | 217 kName, graph()->start(), graph()->start(), |
| 221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 218 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 222 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); | 219 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 223 | 220 |
| 224 Reduction r = Reduce(ret->InputAt(0), | 221 Reduction r = Reduce(ret->InputAt(0), |
| 225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 222 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 226 | 223 |
| 227 // Check LoadNamed(global) => HeapConstant[kValue] | 224 // Check LoadNamed(global) => HeapConstant[kValue] |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 267 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
| 271 ASSERT_TRUE(r.Changed()); | 268 ASSERT_TRUE(r.Changed()); |
| 272 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 269 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
| 273 Capture<Node*> cell_capture; | 270 Capture<Node*> cell_capture; |
| 274 Matcher<Node*> load_field_match = IsLoadField( | 271 Matcher<Node*> load_field_match = IsLoadField( |
| 275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 272 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
| 276 EXPECT_THAT(r.replacement(), load_field_match); | 273 EXPECT_THAT(r.replacement(), load_field_match); |
| 277 | 274 |
| 278 HeapObjectMatcher cell(cell_capture.value()); | 275 HeapObjectMatcher cell(cell_capture.value()); |
| 279 EXPECT_TRUE(cell.HasValue()); | 276 EXPECT_TRUE(cell.HasValue()); |
| 280 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); | 277 EXPECT_TRUE(cell.Value()->IsPropertyCell()); |
| 281 | 278 |
| 282 EXPECT_THAT(ret, | 279 EXPECT_THAT(ret, |
| 283 IsReturn(load_field_match, load_field_match, graph()->start())); | 280 IsReturn(load_field_match, load_field_match, graph()->start())); |
| 284 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 281 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 285 | 282 |
| 286 EXPECT_FALSE(dependencies()->IsEmpty()); | 283 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 287 dependencies()->Rollback(); | 284 dependencies()->Rollback(); |
| 288 } | 285 } |
| 289 | 286 |
| 290 | 287 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 319 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
| 323 ASSERT_TRUE(r.Changed()); | 320 ASSERT_TRUE(r.Changed()); |
| 324 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 321 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
| 325 Capture<Node*> cell_capture; | 322 Capture<Node*> cell_capture; |
| 326 Matcher<Node*> load_field_match = IsLoadField( | 323 Matcher<Node*> load_field_match = IsLoadField( |
| 327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 324 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
| 328 EXPECT_THAT(r.replacement(), load_field_match); | 325 EXPECT_THAT(r.replacement(), load_field_match); |
| 329 | 326 |
| 330 HeapObjectMatcher cell(cell_capture.value()); | 327 HeapObjectMatcher cell(cell_capture.value()); |
| 331 EXPECT_TRUE(cell.HasValue()); | 328 EXPECT_TRUE(cell.HasValue()); |
| 332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); | 329 EXPECT_TRUE(cell.Value()->IsPropertyCell()); |
| 333 | 330 |
| 334 EXPECT_THAT(ret, | 331 EXPECT_THAT(ret, |
| 335 IsReturn(load_field_match, load_field_match, graph()->start())); | 332 IsReturn(load_field_match, load_field_match, graph()->start())); |
| 336 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 333 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 337 | 334 |
| 338 EXPECT_FALSE(dependencies()->IsEmpty()); | 335 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 339 dependencies()->Rollback(); | 336 dependencies()->Rollback(); |
| 340 } | 337 } |
| 341 | 338 |
| 342 } // namespace compiler | 339 } // namespace compiler |
| 343 } // namespace internal | 340 } // namespace internal |
| 344 } // namespace v8 | 341 } // namespace v8 |
| OLD | NEW |