| 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 |