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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 break; | 632 break; |
633 case IrOpcode::kCheckString: | 633 case IrOpcode::kCheckString: |
634 state = LowerCheckString(node, frame_state, *effect, *control); | 634 state = LowerCheckString(node, frame_state, *effect, *control); |
635 break; | 635 break; |
636 case IrOpcode::kCheckIf: | 636 case IrOpcode::kCheckIf: |
637 state = LowerCheckIf(node, frame_state, *effect, *control); | 637 state = LowerCheckIf(node, frame_state, *effect, *control); |
638 break; | 638 break; |
639 case IrOpcode::kCheckHeapObject: | 639 case IrOpcode::kCheckHeapObject: |
640 state = LowerCheckHeapObject(node, frame_state, *effect, *control); | 640 state = LowerCheckHeapObject(node, frame_state, *effect, *control); |
641 break; | 641 break; |
| 642 case IrOpcode::kCheckHasInPrototypeChain: |
| 643 state = |
| 644 LowerCheckHasInPrototypeChain(node, frame_state, *effect, *control); |
| 645 break; |
642 case IrOpcode::kCheckedInt32Add: | 646 case IrOpcode::kCheckedInt32Add: |
643 state = LowerCheckedInt32Add(node, frame_state, *effect, *control); | 647 state = LowerCheckedInt32Add(node, frame_state, *effect, *control); |
644 break; | 648 break; |
645 case IrOpcode::kCheckedInt32Sub: | 649 case IrOpcode::kCheckedInt32Sub: |
646 state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); | 650 state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); |
647 break; | 651 break; |
648 case IrOpcode::kCheckedInt32Div: | 652 case IrOpcode::kCheckedInt32Div: |
649 state = LowerCheckedInt32Div(node, frame_state, *effect, *control); | 653 state = LowerCheckedInt32Div(node, frame_state, *effect, *control); |
650 break; | 654 break; |
651 case IrOpcode::kCheckedInt32Mod: | 655 case IrOpcode::kCheckedInt32Mod: |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, | 1314 graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, |
1311 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); | 1315 jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); |
1312 control = effect = graph()->NewNode( | 1316 control = effect = graph()->NewNode( |
1313 common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1, | 1317 common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1, |
1314 frame_state, effect, control); | 1318 frame_state, effect, control); |
1315 | 1319 |
1316 return ValueEffectControl(value, effect, control); | 1320 return ValueEffectControl(value, effect, control); |
1317 } | 1321 } |
1318 | 1322 |
1319 EffectControlLinearizer::ValueEffectControl | 1323 EffectControlLinearizer::ValueEffectControl |
1320 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state, | 1324 EffectControlLinearizer::LowerCheckHasInPrototypeChain(Node* node, |
1321 Node* effect, Node* control) { | 1325 Node* frame_state, |
1322 Node* value = node->InputAt(0); | 1326 Node* effect, |
| 1327 Node* control) { |
| 1328 Node* object = node->InputAt(0); |
| 1329 Node* prototype = node->InputAt(1); |
1323 | 1330 |
1324 control = effect = | 1331 Node* check0 = ObjectIsSmi(object); |
1325 graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason), | 1332 Node* branch0 = |
1326 value, frame_state, effect, control); | 1333 graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); |
| 1334 |
| 1335 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 1336 Node* etrue0 = effect; |
| 1337 Node* vtrue0 = jsgraph()->Int32Constant(0); |
| 1338 |
| 1339 control = graph()->NewNode(common()->IfFalse(), branch0); |
| 1340 |
| 1341 // Loop through the {object}s prototype chain looking for the {prototype}. |
| 1342 Node* loop = control = graph()->NewNode(common()->Loop(2), control, control); |
| 1343 Node* eloop = effect = |
| 1344 graph()->NewNode(common()->EffectPhi(2), effect, effect, loop); |
| 1345 Node* vloop = object = graph()->NewNode( |
| 1346 common()->Phi(MachineRepresentation::kTagged, 2), object, object, loop); |
| 1347 |
| 1348 // Load the {object} map and instance type. |
| 1349 Node* object_map = effect = |
| 1350 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, |
| 1351 effect, control); |
| 1352 Node* object_instance_type = effect = graph()->NewNode( |
| 1353 simplified()->LoadField(AccessBuilder::ForMapInstanceType()), object_map, |
| 1354 effect, control); |
| 1355 |
| 1356 // Check if the {object} is a special receiver, because for special |
| 1357 // receivers, i.e. proxies or API objects that need access checks, |
| 1358 // we have to use the %HasInPrototypeChain runtime function instead. |
| 1359 Node* check1 = |
| 1360 graph()->NewNode(machine()->Uint32LessThanOrEqual(), object_instance_type, |
| 1361 jsgraph()->Uint32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
| 1362 Node* branch1 = |
| 1363 graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); |
| 1364 |
| 1365 control = graph()->NewNode(common()->IfFalse(), branch1); |
| 1366 |
| 1367 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 1368 Node* etrue1 = effect; |
| 1369 Node* vtrue1 = jsgraph()->Int32Constant(0); |
| 1370 |
| 1371 // Check if the {object} is not a receiver at all. |
| 1372 Node* check10 = |
| 1373 graph()->NewNode(machine()->Uint32LessThan(), object_instance_type, |
| 1374 jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE)); |
| 1375 if_true1 = etrue1 = graph()->NewNode( |
| 1376 common()->DeoptimizeUnless(DeoptimizeReason::kUnexpectedObject), check10, |
| 1377 frame_state, etrue1, if_true1); |
| 1378 |
| 1379 // Load the {object} prototype. |
| 1380 Node* object_prototype = effect = graph()->NewNode( |
| 1381 simplified()->LoadField(AccessBuilder::ForMapPrototype()), object_map, |
| 1382 effect, control); |
| 1383 |
| 1384 // Check if we reached the end of {object}s prototype chain. |
| 1385 Node* check2 = graph()->NewNode(machine()->WordEqual(), object_prototype, |
| 1386 jsgraph()->NullConstant()); |
| 1387 Node* branch2 = graph()->NewNode(common()->Branch(), check2, control); |
| 1388 |
| 1389 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
| 1390 Node* etrue2 = effect; |
| 1391 Node* vtrue2 = jsgraph()->Int32Constant(0); |
| 1392 |
| 1393 control = graph()->NewNode(common()->IfFalse(), branch2); |
| 1394 |
| 1395 // Check if we reached the {prototype}. |
| 1396 Node* check3 = |
| 1397 graph()->NewNode(machine()->WordEqual(), object_prototype, prototype); |
| 1398 Node* branch3 = graph()->NewNode(common()->Branch(), check3, control); |
| 1399 |
| 1400 Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3); |
| 1401 Node* etrue3 = effect; |
| 1402 Node* vtrue3 = jsgraph()->Int32Constant(1); |
| 1403 |
| 1404 control = graph()->NewNode(common()->IfFalse(), branch3); |
| 1405 |
| 1406 // Close the loop. |
| 1407 vloop->ReplaceInput(1, object_prototype); |
| 1408 eloop->ReplaceInput(1, effect); |
| 1409 loop->ReplaceInput(1, control); |
| 1410 |
| 1411 control = graph()->NewNode(common()->Merge(4), if_true0, if_true1, if_true2, |
| 1412 if_true3); |
| 1413 effect = graph()->NewNode(common()->EffectPhi(4), etrue0, etrue1, etrue2, |
| 1414 etrue3, control); |
| 1415 Node* value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 4), |
| 1416 vtrue0, vtrue1, vtrue2, vtrue3, control); |
1327 | 1417 |
1328 return ValueEffectControl(value, effect, control); | 1418 return ValueEffectControl(value, effect, control); |
1329 } | 1419 } |
1330 | 1420 |
1331 EffectControlLinearizer::ValueEffectControl | 1421 EffectControlLinearizer::ValueEffectControl |
1332 EffectControlLinearizer::LowerCheckHeapObject(Node* node, Node* frame_state, | 1422 EffectControlLinearizer::LowerCheckHeapObject(Node* node, Node* frame_state, |
1333 Node* effect, Node* control) { | 1423 Node* effect, Node* control) { |
1334 Node* value = node->InputAt(0); | 1424 Node* value = node->InputAt(0); |
1335 | 1425 |
1336 Node* check = ObjectIsSmi(value); | 1426 Node* check = ObjectIsSmi(value); |
1337 control = effect = | 1427 control = effect = |
1338 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check, | 1428 graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check, |
1339 frame_state, effect, control); | 1429 frame_state, effect, control); |
1340 | 1430 |
1341 return ValueEffectControl(value, effect, control); | 1431 return ValueEffectControl(value, effect, control); |
1342 } | 1432 } |
1343 | 1433 |
1344 EffectControlLinearizer::ValueEffectControl | 1434 EffectControlLinearizer::ValueEffectControl |
| 1435 EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state, |
| 1436 Node* effect, Node* control) { |
| 1437 Node* value = node->InputAt(0); |
| 1438 |
| 1439 control = effect = |
| 1440 graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason), |
| 1441 value, frame_state, effect, control); |
| 1442 |
| 1443 return ValueEffectControl(value, effect, control); |
| 1444 } |
| 1445 |
| 1446 EffectControlLinearizer::ValueEffectControl |
1345 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state, | 1447 EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state, |
1346 Node* effect, Node* control) { | 1448 Node* effect, Node* control) { |
1347 Node* lhs = node->InputAt(0); | 1449 Node* lhs = node->InputAt(0); |
1348 Node* rhs = node->InputAt(1); | 1450 Node* rhs = node->InputAt(1); |
1349 | 1451 |
1350 Node* value = | 1452 Node* value = |
1351 graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control); | 1453 graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control); |
1352 | 1454 |
1353 Node* check = graph()->NewNode(common()->Projection(1), value, control); | 1455 Node* check = graph()->NewNode(common()->Projection(1), value, control); |
1354 control = effect = | 1456 control = effect = |
(...skipping 2154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3509 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3611 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3510 Operator::kEliminatable); | 3612 Operator::kEliminatable); |
3511 to_number_operator_.set(common()->Call(desc)); | 3613 to_number_operator_.set(common()->Call(desc)); |
3512 } | 3614 } |
3513 return to_number_operator_.get(); | 3615 return to_number_operator_.get(); |
3514 } | 3616 } |
3515 | 3617 |
3516 } // namespace compiler | 3618 } // namespace compiler |
3517 } // namespace internal | 3619 } // namespace internal |
3518 } // namespace v8 | 3620 } // namespace v8 |
OLD | NEW |