| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, | 499 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, |
| 500 HInstruction* hinstr, | 500 HInstruction* hinstr, |
| 501 CanDeoptimize can_deoptimize) { | 501 CanDeoptimize can_deoptimize) { |
| 502 info()->MarkAsNonDeferredCalling(); | 502 info()->MarkAsNonDeferredCalling(); |
| 503 #ifdef DEBUG | 503 #ifdef DEBUG |
| 504 instr->VerifyCall(); | 504 instr->VerifyCall(); |
| 505 #endif | 505 #endif |
| 506 instr->MarkAsCall(); | 506 instr->MarkAsCall(); |
| 507 instr = AssignPointerMap(instr); | 507 instr = AssignPointerMap(instr); |
| 508 | 508 |
| 509 if (hinstr->HasObservableSideEffects()) { | |
| 510 ASSERT(hinstr->next()->IsSimulate()); | |
| 511 HSimulate* sim = HSimulate::cast(hinstr->next()); | |
| 512 ASSERT(instruction_pending_deoptimization_environment_ == NULL); | |
| 513 ASSERT(pending_deoptimization_ast_id_.IsNone()); | |
| 514 instruction_pending_deoptimization_environment_ = instr; | |
| 515 pending_deoptimization_ast_id_ = sim->ast_id(); | |
| 516 } | |
| 517 | |
| 518 // If instruction does not have side-effects lazy deoptimization | 509 // If instruction does not have side-effects lazy deoptimization |
| 519 // after the call will try to deoptimize to the point before the call. | 510 // after the call will try to deoptimize to the point before the call. |
| 520 // Thus we still need to attach environment to this call even if | 511 // Thus we still need to attach environment to this call even if |
| 521 // call sequence can not deoptimize eagerly. | 512 // call sequence can not deoptimize eagerly. |
| 522 bool needs_environment = | 513 bool needs_environment = |
| 523 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || | 514 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || |
| 524 !hinstr->HasObservableSideEffects(); | 515 !hinstr->HasObservableSideEffects(); |
| 525 if (needs_environment && !instr->HasEnvironment()) { | 516 if (needs_environment && !instr->HasEnvironment()) { |
| 526 instr = AssignEnvironment(instr); | 517 instr = AssignEnvironment(instr); |
| 527 } | 518 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 } | 720 } |
| 730 #endif | 721 #endif |
| 731 | 722 |
| 732 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 723 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 733 instr = AssignPointerMap(instr); | 724 instr = AssignPointerMap(instr); |
| 734 } | 725 } |
| 735 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 726 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 736 instr = AssignEnvironment(instr); | 727 instr = AssignEnvironment(instr); |
| 737 } | 728 } |
| 738 chunk_->AddInstruction(instr, current_block_); | 729 chunk_->AddInstruction(instr, current_block_); |
| 730 |
| 731 if (instr->IsCall()) { |
| 732 HValue* hydrogen_value_for_lazy_bailout = current; |
| 733 LInstruction* instruction_needing_environment = NULL; |
| 734 if (current->HasObservableSideEffects()) { |
| 735 HSimulate* sim = HSimulate::cast(current->next()); |
| 736 instruction_needing_environment = instr; |
| 737 sim->ReplayEnvironment(current_block_->last_environment()); |
| 738 hydrogen_value_for_lazy_bailout = sim; |
| 739 } |
| 740 LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout()); |
| 741 bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); |
| 742 chunk_->AddInstruction(bailout, current_block_); |
| 743 if (instruction_needing_environment != NULL) { |
| 744 // Store the lazy deopt environment with the instruction if needed. |
| 745 // Right now it is only used for LInstanceOfKnownGlobal. |
| 746 instruction_needing_environment-> |
| 747 SetDeferredLazyDeoptimizationEnvironment(bailout->environment()); |
| 748 } |
| 749 } |
| 739 } | 750 } |
| 740 current_instruction_ = old_current; | 751 current_instruction_ = old_current; |
| 741 } | 752 } |
| 742 | 753 |
| 743 | 754 |
| 744 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 755 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
| 745 HEnvironment* hydrogen_env = current_block_->last_environment(); | 756 HEnvironment* hydrogen_env = current_block_->last_environment(); |
| 746 int argument_index_accumulator = 0; | 757 int argument_index_accumulator = 0; |
| 747 ZoneList<HValue*> objects_to_materialize(0, zone()); | 758 ZoneList<HValue*> objects_to_materialize(0, zone()); |
| 748 instr->set_environment(CreateEnvironment(hydrogen_env, | 759 instr->set_environment(CreateEnvironment(hydrogen_env, |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 } | 871 } |
| 861 } | 872 } |
| 862 | 873 |
| 863 | 874 |
| 864 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 875 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
| 865 info()->MarkAsDeferredCalling(); | 876 info()->MarkAsDeferredCalling(); |
| 866 LOperand* context = UseAny(instr->context()); | 877 LOperand* context = UseAny(instr->context()); |
| 867 LOperand* size = UseRegisterOrConstant(instr->size()); | 878 LOperand* size = UseRegisterOrConstant(instr->size()); |
| 868 LOperand* temp1 = TempRegister(); | 879 LOperand* temp1 = TempRegister(); |
| 869 LOperand* temp2 = TempRegister(); | 880 LOperand* temp2 = TempRegister(); |
| 870 LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2); | 881 LOperand* temp3 = instr->MustPrefillWithFiller() ? TempRegister() : NULL; |
| 882 LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2, temp3); |
| 871 return AssignPointerMap(DefineAsRegister(result)); | 883 return AssignPointerMap(DefineAsRegister(result)); |
| 872 } | 884 } |
| 873 | 885 |
| 874 | 886 |
| 875 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 887 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 876 LOperand* function = UseFixed(instr->function(), x1); | 888 LOperand* function = UseFixed(instr->function(), x1); |
| 877 LOperand* receiver = UseFixed(instr->receiver(), x0); | 889 LOperand* receiver = UseFixed(instr->receiver(), x0); |
| 878 LOperand* length = UseFixed(instr->length(), x2); | 890 LOperand* length = UseFixed(instr->length(), x2); |
| 879 LOperand* elements = UseFixed(instr->elements(), x3); | 891 LOperand* elements = UseFixed(instr->elements(), x3); |
| 880 LApplyArguments* result = new(zone()) LApplyArguments(function, | 892 LApplyArguments* result = new(zone()) LApplyArguments(function, |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1134 TempRegister()); | 1146 TempRegister()); |
| 1135 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1147 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1136 } else { | 1148 } else { |
| 1137 STATIC_ASSERT((kMinInt == Smi::kMinValue) && | 1149 STATIC_ASSERT((kMinInt == Smi::kMinValue) && |
| 1138 (kMaxInt == Smi::kMaxValue)); | 1150 (kMaxInt == Smi::kMaxValue)); |
| 1139 LOperand* value = UseRegisterAtStart(instr->value()); | 1151 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1140 return DefineAsRegister(new(zone()) LSmiTag(value)); | 1152 return DefineAsRegister(new(zone()) LSmiTag(value)); |
| 1141 } | 1153 } |
| 1142 } else if (to.IsSmi()) { | 1154 } else if (to.IsSmi()) { |
| 1143 LOperand* value = UseRegisterAtStart(instr->value()); | 1155 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1156 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); |
| 1144 if (instr->value()->CheckFlag(HInstruction::kUint32)) { | 1157 if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
| 1145 LUint32ToSmi* result = new(zone()) LUint32ToSmi(value); | 1158 result = AssignEnvironment(result); |
| 1146 return AssignEnvironment(DefineAsRegister(result)); | |
| 1147 } else { | |
| 1148 // This cannot deoptimize because an A64 smi can represent any int32. | |
| 1149 return DefineAsRegister(new(zone()) LInteger32ToSmi(value)); | |
| 1150 } | 1159 } |
| 1160 return result; |
| 1151 } else { | 1161 } else { |
| 1152 ASSERT(to.IsDouble()); | 1162 ASSERT(to.IsDouble()); |
| 1153 if (instr->value()->CheckFlag(HInstruction::kUint32)) { | 1163 if (instr->value()->CheckFlag(HInstruction::kUint32)) { |
| 1154 return DefineAsRegister( | 1164 return DefineAsRegister( |
| 1155 new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value()))); | 1165 new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value()))); |
| 1156 } else { | 1166 } else { |
| 1157 return DefineAsRegister( | 1167 return DefineAsRegister( |
| 1158 new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value()))); | 1168 new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value()))); |
| 1159 } | 1169 } |
| 1160 } | 1170 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 LOperand* context = UseFixed(instr->context(), cp); | 1371 LOperand* context = UseFixed(instr->context(), cp); |
| 1362 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); | 1372 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1363 } | 1373 } |
| 1364 | 1374 |
| 1365 | 1375 |
| 1366 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 1376 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
| 1367 return AssignEnvironment(new(zone()) LDeoptimize); | 1377 return AssignEnvironment(new(zone()) LDeoptimize); |
| 1368 } | 1378 } |
| 1369 | 1379 |
| 1370 | 1380 |
| 1381 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
| 1382 ASSERT(instr->representation().IsInteger32()); |
| 1383 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1384 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1385 LOperand* dividend = UseRegister(instr->left()); |
| 1386 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1387 LInstruction* result = DefineAsRegister(new(zone()) LDivByPowerOf2I( |
| 1388 dividend, divisor)); |
| 1389 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1390 (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) || |
| 1391 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1392 divisor != 1 && divisor != -1)) { |
| 1393 result = AssignEnvironment(result); |
| 1394 } |
| 1395 return result; |
| 1396 } |
| 1397 |
| 1398 |
| 1399 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1400 ASSERT(instr->representation().IsInteger32()); |
| 1401 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1402 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1403 LOperand* dividend = UseRegister(instr->left()); |
| 1404 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1405 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
| 1406 ? NULL : TempRegister(); |
| 1407 LInstruction* result = DefineAsRegister(new(zone()) LDivByConstI( |
| 1408 dividend, divisor, temp)); |
| 1409 if (divisor == 0 || |
| 1410 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1411 !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1412 result = AssignEnvironment(result); |
| 1413 } |
| 1414 return result; |
| 1415 } |
| 1416 |
| 1417 |
| 1418 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { |
| 1419 ASSERT(instr->representation().IsSmiOrInteger32()); |
| 1420 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1421 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1422 LOperand* dividend = UseRegister(instr->left()); |
| 1423 LOperand* divisor = UseRegister(instr->right()); |
| 1424 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
| 1425 ? NULL : TempRegister(); |
| 1426 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
| 1427 return AssignEnvironment(DefineAsRegister(div)); |
| 1428 } |
| 1429 |
| 1430 |
| 1371 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1431 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1372 if (instr->representation().IsInteger32()) { | 1432 if (instr->representation().IsSmiOrInteger32()) { |
| 1373 // TODO(all): Update this case to support smi inputs. | |
| 1374 ASSERT(instr->left()->representation().Equals(instr->representation())); | |
| 1375 ASSERT(instr->right()->representation().Equals(instr->representation())); | |
| 1376 if (instr->RightIsPowerOf2()) { | 1433 if (instr->RightIsPowerOf2()) { |
| 1377 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1434 return DoDivByPowerOf2I(instr); |
| 1378 LOperand* value = UseRegister(instr->left()); | 1435 } else if (instr->right()->IsConstant()) { |
| 1379 LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); | 1436 return DoDivByConstI(instr); |
| 1380 return AssignEnvironment(DefineAsRegister(div)); | 1437 } else { |
| 1438 return DoDivI(instr); |
| 1381 } | 1439 } |
| 1382 LOperand* dividend = UseRegister(instr->left()); | |
| 1383 LOperand* divisor = UseRegister(instr->right()); | |
| 1384 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) | |
| 1385 ? NULL : TempRegister(); | |
| 1386 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); | |
| 1387 return AssignEnvironment(DefineAsRegister(div)); | |
| 1388 } else if (instr->representation().IsDouble()) { | 1440 } else if (instr->representation().IsDouble()) { |
| 1389 return DoArithmeticD(Token::DIV, instr); | 1441 return DoArithmeticD(Token::DIV, instr); |
| 1390 } else { | 1442 } else { |
| 1391 return DoArithmeticT(Token::DIV, instr); | 1443 return DoArithmeticT(Token::DIV, instr); |
| 1392 } | 1444 } |
| 1393 } | 1445 } |
| 1394 | 1446 |
| 1395 | 1447 |
| 1396 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 1448 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
| 1397 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 1449 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 return DefineAsRegister(new(zone()) LLoadRoot); | 1737 return DefineAsRegister(new(zone()) LLoadRoot); |
| 1686 } | 1738 } |
| 1687 | 1739 |
| 1688 | 1740 |
| 1689 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1741 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1690 LOperand* map = UseRegisterAtStart(instr->value()); | 1742 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1691 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1743 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1692 } | 1744 } |
| 1693 | 1745 |
| 1694 | 1746 |
| 1747 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { |
| 1748 ASSERT(instr->representation().IsInteger32()); |
| 1749 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1750 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1751 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1752 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1753 LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I( |
| 1754 dividend, divisor)); |
| 1755 if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1756 (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) { |
| 1757 result = AssignEnvironment(result); |
| 1758 } |
| 1759 return result; |
| 1760 } |
| 1761 |
| 1762 |
| 1763 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1764 ASSERT(instr->representation().IsInteger32()); |
| 1765 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1766 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1767 LOperand* dividend = UseRegister(instr->left()); |
| 1768 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1769 LInstruction* result = |
| 1770 DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor)); |
| 1771 bool can_deopt = |
| 1772 divisor == 0 || |
| 1773 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0); |
| 1774 return can_deopt ? AssignEnvironment(result) : result; |
| 1775 } |
| 1776 |
| 1777 |
| 1778 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
| 1779 LOperand* dividend = UseRegister(instr->left()); |
| 1780 LOperand* divisor = UseRegister(instr->right()); |
| 1781 LOperand* remainder = TempRegister(); |
| 1782 LInstruction* result = |
| 1783 DefineAsRegister(new(zone()) LFlooringDivI(dividend, divisor, remainder)); |
| 1784 return AssignEnvironment(result); |
| 1785 } |
| 1786 |
| 1787 |
| 1695 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1788 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1696 HValue* right = instr->right(); | 1789 if (instr->RightIsPowerOf2()) { |
| 1697 LOperand* dividend = UseRegister(instr->left()); | 1790 return DoFlooringDivByPowerOf2I(instr); |
| 1698 LOperand* divisor = UseRegister(right); | 1791 } else if (false && instr->right()->IsConstant()) { |
| 1699 LOperand* remainder = TempRegister(); | 1792 return DoFlooringDivByConstI(instr); // TODO(svenpanne) Fix and re-enable. |
| 1700 return AssignEnvironment(DefineAsRegister( | 1793 } else { |
| 1701 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1794 return DoFlooringDivI(instr); |
| 1795 } |
| 1702 } | 1796 } |
| 1703 | 1797 |
| 1704 | 1798 |
| 1705 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1799 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1706 LOperand* left = NULL; | 1800 LOperand* left = NULL; |
| 1707 LOperand* right = NULL; | 1801 LOperand* right = NULL; |
| 1708 if (instr->representation().IsSmiOrInteger32()) { | 1802 if (instr->representation().IsSmiOrInteger32()) { |
| 1709 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1803 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1710 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1804 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1711 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1805 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1712 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 1806 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 1713 } else { | 1807 } else { |
| 1714 ASSERT(instr->representation().IsDouble()); | 1808 ASSERT(instr->representation().IsDouble()); |
| 1715 ASSERT(instr->left()->representation().IsDouble()); | 1809 ASSERT(instr->left()->representation().IsDouble()); |
| 1716 ASSERT(instr->right()->representation().IsDouble()); | 1810 ASSERT(instr->right()->representation().IsDouble()); |
| 1717 left = UseRegisterAtStart(instr->left()); | 1811 left = UseRegisterAtStart(instr->left()); |
| 1718 right = UseRegisterAtStart(instr->right()); | 1812 right = UseRegisterAtStart(instr->right()); |
| 1719 } | 1813 } |
| 1720 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1814 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
| 1721 } | 1815 } |
| 1722 | 1816 |
| 1723 | 1817 |
| 1724 LInstruction* LChunkBuilder::DoMod(HMod* hmod) { | 1818 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
| 1725 HValue* hleft = hmod->left(); | 1819 ASSERT(instr->representation().IsInteger32()); |
| 1726 HValue* hright = hmod->right(); | 1820 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1821 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1822 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1823 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1824 LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( |
| 1825 dividend, divisor)); |
| 1826 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1827 result = AssignEnvironment(result); |
| 1828 } |
| 1829 return result; |
| 1830 } |
| 1727 | 1831 |
| 1728 // TODO(jbramley): Add smi support. | |
| 1729 if (hmod->representation().IsInteger32()) { | |
| 1730 ASSERT(hleft->representation().IsInteger32()); | |
| 1731 ASSERT(hleft->representation().IsInteger32()); | |
| 1732 LOperand* left_op; | |
| 1733 LOperand* right_op; | |
| 1734 | 1832 |
| 1735 if (hmod->RightIsPowerOf2()) { | 1833 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1736 left_op = UseRegisterAtStart(hleft); | 1834 ASSERT(instr->representation().IsInteger32()); |
| 1737 right_op = UseConstant(hright); | 1835 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1836 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1837 LOperand* dividend = UseRegister(instr->left()); |
| 1838 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1839 LOperand* temp = TempRegister(); |
| 1840 LInstruction* result = DefineAsRegister(new(zone()) LModByConstI( |
| 1841 dividend, divisor, temp)); |
| 1842 if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1843 result = AssignEnvironment(result); |
| 1844 } |
| 1845 return result; |
| 1846 } |
| 1847 |
| 1848 |
| 1849 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
| 1850 ASSERT(instr->representation().IsSmiOrInteger32()); |
| 1851 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1852 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1853 LOperand* dividend = UseRegister(instr->left()); |
| 1854 LOperand* divisor = UseRegister(instr->right()); |
| 1855 LInstruction* result = DefineAsRegister(new(zone()) LModI(dividend, divisor)); |
| 1856 if (instr->CheckFlag(HValue::kCanBeDivByZero) || |
| 1857 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1858 result = AssignEnvironment(result); |
| 1859 } |
| 1860 return result; |
| 1861 } |
| 1862 |
| 1863 |
| 1864 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1865 if (instr->representation().IsSmiOrInteger32()) { |
| 1866 if (instr->RightIsPowerOf2()) { |
| 1867 return DoModByPowerOf2I(instr); |
| 1868 } else if (instr->right()->IsConstant()) { |
| 1869 return DoModByConstI(instr); |
| 1738 } else { | 1870 } else { |
| 1739 right_op = UseRegister(hright); | 1871 return DoModI(instr); |
| 1740 left_op = UseRegister(hleft); | |
| 1741 } | 1872 } |
| 1742 | 1873 } else if (instr->representation().IsDouble()) { |
| 1743 LModI* lmod = new(zone()) LModI(left_op, right_op); | 1874 return DoArithmeticD(Token::MOD, instr); |
| 1744 | |
| 1745 if (hmod->right()->CanBeZero() || | |
| 1746 (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && | |
| 1747 hmod->left()->CanBeNegative() && hmod->CanBeZero())) { | |
| 1748 AssignEnvironment(lmod); | |
| 1749 } | |
| 1750 return DefineAsRegister(lmod); | |
| 1751 | |
| 1752 } else if (hmod->representation().IsSmiOrTagged()) { | |
| 1753 return DoArithmeticT(Token::MOD, hmod); | |
| 1754 } else { | 1875 } else { |
| 1755 return DoArithmeticD(Token::MOD, hmod); | 1876 return DoArithmeticT(Token::MOD, instr); |
| 1756 } | 1877 } |
| 1757 } | 1878 } |
| 1758 | 1879 |
| 1759 | 1880 |
| 1760 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1881 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1761 if (instr->representation().IsSmiOrInteger32()) { | 1882 if (instr->representation().IsSmiOrInteger32()) { |
| 1762 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1883 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1763 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1884 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1764 | 1885 |
| 1765 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1886 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1789 LMulConstIS* mul = new(zone()) LMulConstIS(left, right); | 1910 LMulConstIS* mul = new(zone()) LMulConstIS(left, right); |
| 1790 if (needs_environment) AssignEnvironment(mul); | 1911 if (needs_environment) AssignEnvironment(mul); |
| 1791 return DefineAsRegister(mul); | 1912 return DefineAsRegister(mul); |
| 1792 } | 1913 } |
| 1793 } | 1914 } |
| 1794 | 1915 |
| 1795 // LMulI/S can handle all cases, but it requires that a register is | 1916 // LMulI/S can handle all cases, but it requires that a register is |
| 1796 // allocated for the second operand. | 1917 // allocated for the second operand. |
| 1797 LInstruction* result; | 1918 LInstruction* result; |
| 1798 if (instr->representation().IsSmi()) { | 1919 if (instr->representation().IsSmi()) { |
| 1799 // TODO(jbramley/rmcilroy): Fix LMulS so we can UseRegisterAtStart here. | 1920 LOperand* right = UseRegisterAtStart(most_const); |
| 1800 LOperand* right = UseRegister(most_const); | |
| 1801 result = DefineAsRegister(new(zone()) LMulS(left, right)); | 1921 result = DefineAsRegister(new(zone()) LMulS(left, right)); |
| 1802 } else { | 1922 } else { |
| 1803 LOperand* right = UseRegisterAtStart(most_const); | 1923 LOperand* right = UseRegisterAtStart(most_const); |
| 1804 result = DefineAsRegister(new(zone()) LMulI(left, right)); | 1924 result = DefineAsRegister(new(zone()) LMulI(left, right)); |
| 1805 } | 1925 } |
| 1806 if (needs_environment) AssignEnvironment(result); | 1926 if (needs_environment) AssignEnvironment(result); |
| 1807 return result; | 1927 return result; |
| 1808 } else if (instr->representation().IsDouble()) { | 1928 } else if (instr->representation().IsDouble()) { |
| 1809 return DoArithmeticD(Token::MUL, instr); | 1929 return DoArithmeticD(Token::MUL, instr); |
| 1810 } else { | 1930 } else { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 } | 1982 } |
| 1863 | 1983 |
| 1864 | 1984 |
| 1865 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1985 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1866 LOperand* context = UseFixed(instr->context(), cp); | 1986 LOperand* context = UseFixed(instr->context(), cp); |
| 1867 return MarkAsCall( | 1987 return MarkAsCall( |
| 1868 DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr); | 1988 DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr); |
| 1869 } | 1989 } |
| 1870 | 1990 |
| 1871 | 1991 |
| 1992 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 1993 HValue* value = instr->value(); |
| 1994 ASSERT(value->representation().IsDouble()); |
| 1995 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 1996 } |
| 1997 |
| 1998 |
| 1999 LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) { |
| 2000 LOperand* lo = UseRegister(instr->lo()); |
| 2001 LOperand* hi = UseRegister(instr->hi()); |
| 2002 LOperand* temp = TempRegister(); |
| 2003 return DefineAsRegister(new(zone()) LConstructDouble(hi, lo, temp)); |
| 2004 } |
| 2005 |
| 2006 |
| 1872 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 2007 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
| 1873 LOperand* context = info()->IsStub() | 2008 LOperand* context = info()->IsStub() |
| 1874 ? UseFixed(instr->context(), cp) | 2009 ? UseFixed(instr->context(), cp) |
| 1875 : NULL; | 2010 : NULL; |
| 1876 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); | 2011 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); |
| 1877 return new(zone()) LReturn(UseFixed(instr->value(), x0), context, | 2012 return new(zone()) LReturn(UseFixed(instr->value(), x0), context, |
| 1878 parameter_count); | 2013 parameter_count); |
| 1879 } | 2014 } |
| 1880 | 2015 |
| 1881 | 2016 |
| 1882 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { | 2017 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { |
| 1883 // TODO(all): Use UseRegisterAtStart and UseRegisterOrConstantAtStart here. | 2018 LOperand* string = UseRegisterAtStart(instr->string()); |
| 1884 // We cannot do it now because the debug code in the implementation changes | 2019 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); |
| 1885 // temp. | |
| 1886 LOperand* string = UseRegister(instr->string()); | |
| 1887 LOperand* index = UseRegisterOrConstant(instr->index()); | |
| 1888 LOperand* temp = TempRegister(); | 2020 LOperand* temp = TempRegister(); |
| 1889 LSeqStringGetChar* result = | 2021 LSeqStringGetChar* result = |
| 1890 new(zone()) LSeqStringGetChar(string, index, temp); | 2022 new(zone()) LSeqStringGetChar(string, index, temp); |
| 1891 return DefineAsRegister(result); | 2023 return DefineAsRegister(result); |
| 1892 } | 2024 } |
| 1893 | 2025 |
| 1894 | 2026 |
| 1895 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { | 2027 LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { |
| 1896 LOperand* string = UseRegister(instr->string()); | 2028 LOperand* string = UseRegister(instr->string()); |
| 1897 LOperand* index = FLAG_debug_code | 2029 LOperand* index = FLAG_debug_code |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 } | 2107 } |
| 1976 | 2108 |
| 1977 | 2109 |
| 1978 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 2110 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| 1979 return DoShift(Token::SHR, instr); | 2111 return DoShift(Token::SHR, instr); |
| 1980 } | 2112 } |
| 1981 | 2113 |
| 1982 | 2114 |
| 1983 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2115 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 1984 instr->ReplayEnvironment(current_block_->last_environment()); | 2116 instr->ReplayEnvironment(current_block_->last_environment()); |
| 1985 | |
| 1986 // If there is an instruction pending deoptimization environment create a | |
| 1987 // lazy bailout instruction to capture the environment. | |
| 1988 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | |
| 1989 LInstruction* result = new(zone()) LLazyBailout; | |
| 1990 result = AssignEnvironment(result); | |
| 1991 // Store the lazy deopt environment with the instruction if needed. Right | |
| 1992 // now it is only used for LInstanceOfKnownGlobal. | |
| 1993 instruction_pending_deoptimization_environment_-> | |
| 1994 SetDeferredLazyDeoptimizationEnvironment(result->environment()); | |
| 1995 instruction_pending_deoptimization_environment_ = NULL; | |
| 1996 pending_deoptimization_ast_id_ = BailoutId::None(); | |
| 1997 return result; | |
| 1998 } | |
| 1999 | |
| 2000 return NULL; | 2117 return NULL; |
| 2001 } | 2118 } |
| 2002 | 2119 |
| 2003 | 2120 |
| 2004 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2121 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2005 if (instr->is_function_entry()) { | 2122 if (instr->is_function_entry()) { |
| 2006 LOperand* context = UseFixed(instr->context(), cp); | 2123 LOperand* context = UseFixed(instr->context(), cp); |
| 2007 return MarkAsCall(new(zone()) LStackCheck(context), instr); | 2124 return MarkAsCall(new(zone()) LStackCheck(context), instr); |
| 2008 } else { | 2125 } else { |
| 2009 ASSERT(instr->is_backwards_branch()); | 2126 ASSERT(instr->is_backwards_branch()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2049 } else { | 2166 } else { |
| 2050 return new(zone()) LStoreGlobalCell(value, TempRegister(), NULL); | 2167 return new(zone()) LStoreGlobalCell(value, TempRegister(), NULL); |
| 2051 } | 2168 } |
| 2052 } | 2169 } |
| 2053 | 2170 |
| 2054 | 2171 |
| 2055 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2172 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2056 LOperand* temp = NULL; | 2173 LOperand* temp = NULL; |
| 2057 LOperand* elements = NULL; | 2174 LOperand* elements = NULL; |
| 2058 LOperand* val = NULL; | 2175 LOperand* val = NULL; |
| 2059 LOperand* key = NULL; | 2176 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2060 | 2177 |
| 2061 if (!instr->is_typed_elements() && | 2178 if (!instr->is_typed_elements() && |
| 2062 instr->value()->representation().IsTagged() && | 2179 instr->value()->representation().IsTagged() && |
| 2063 instr->NeedsWriteBarrier()) { | 2180 instr->NeedsWriteBarrier()) { |
| 2064 // RecordWrite() will clobber all registers. | 2181 // RecordWrite() will clobber all registers. |
| 2065 elements = UseRegisterAndClobber(instr->elements()); | 2182 elements = UseRegisterAndClobber(instr->elements()); |
| 2066 val = UseRegisterAndClobber(instr->value()); | 2183 val = UseRegisterAndClobber(instr->value()); |
| 2067 key = UseRegisterAndClobber(instr->key()); | 2184 temp = TempRegister(); |
| 2068 } else { | 2185 } else { |
| 2069 elements = UseRegister(instr->elements()); | 2186 elements = UseRegister(instr->elements()); |
| 2070 val = UseRegister(instr->value()); | 2187 val = UseRegister(instr->value()); |
| 2071 key = UseRegisterOrConstantAtStart(instr->key()); | 2188 temp = instr->key()->IsConstant() ? NULL : TempRegister(); |
| 2072 } | 2189 } |
| 2073 | 2190 |
| 2074 if (instr->is_typed_elements()) { | 2191 if (instr->is_typed_elements()) { |
| 2075 ASSERT((instr->value()->representation().IsInteger32() && | 2192 ASSERT((instr->value()->representation().IsInteger32() && |
| 2076 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || | 2193 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || |
| 2077 (instr->value()->representation().IsDouble() && | 2194 (instr->value()->representation().IsDouble() && |
| 2078 IsDoubleOrFloatElementsKind(instr->elements_kind()))); | 2195 IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
| 2079 ASSERT((instr->is_fixed_typed_array() && | 2196 ASSERT((instr->is_fixed_typed_array() && |
| 2080 instr->elements()->representation().IsTagged()) || | 2197 instr->elements()->representation().IsTagged()) || |
| 2081 (instr->is_external() && | 2198 (instr->is_external() && |
| 2082 instr->elements()->representation().IsExternal())); | 2199 instr->elements()->representation().IsExternal())); |
| 2083 temp = instr->key()->IsConstant() ? NULL : TempRegister(); | |
| 2084 return new(zone()) LStoreKeyedExternal(elements, key, val, temp); | 2200 return new(zone()) LStoreKeyedExternal(elements, key, val, temp); |
| 2085 | 2201 |
| 2086 } else if (instr->value()->representation().IsDouble()) { | 2202 } else if (instr->value()->representation().IsDouble()) { |
| 2087 ASSERT(instr->elements()->representation().IsTagged()); | 2203 ASSERT(instr->elements()->representation().IsTagged()); |
| 2088 | |
| 2089 // The constraint used here is UseRegister, even though the StoreKeyed | |
| 2090 // instruction may canonicalize the value in the register if it is a NaN. | |
| 2091 temp = TempRegister(); | |
| 2092 return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp); | 2204 return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp); |
| 2093 | 2205 |
| 2094 } else { | 2206 } else { |
| 2095 ASSERT(instr->elements()->representation().IsTagged()); | 2207 ASSERT(instr->elements()->representation().IsTagged()); |
| 2096 ASSERT(instr->value()->representation().IsSmiOrTagged() || | 2208 ASSERT(instr->value()->representation().IsSmiOrTagged() || |
| 2097 instr->value()->representation().IsInteger32()); | 2209 instr->value()->representation().IsInteger32()); |
| 2098 | |
| 2099 temp = TempRegister(); | |
| 2100 return new(zone()) LStoreKeyedFixed(elements, key, val, temp); | 2210 return new(zone()) LStoreKeyedFixed(elements, key, val, temp); |
| 2101 } | 2211 } |
| 2102 } | 2212 } |
| 2103 | 2213 |
| 2104 | 2214 |
| 2105 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2215 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 2106 LOperand* context = UseFixed(instr->context(), cp); | 2216 LOperand* context = UseFixed(instr->context(), cp); |
| 2107 LOperand* object = UseFixed(instr->object(), x2); | 2217 LOperand* object = UseFixed(instr->object(), x2); |
| 2108 LOperand* key = UseFixed(instr->key(), x1); | 2218 LOperand* key = UseFixed(instr->key(), x1); |
| 2109 LOperand* value = UseFixed(instr->value(), x0); | 2219 LOperand* value = UseFixed(instr->value(), x0); |
| 2110 | 2220 |
| 2111 ASSERT(instr->object()->representation().IsTagged()); | 2221 ASSERT(instr->object()->representation().IsTagged()); |
| 2112 ASSERT(instr->key()->representation().IsTagged()); | 2222 ASSERT(instr->key()->representation().IsTagged()); |
| 2113 ASSERT(instr->value()->representation().IsTagged()); | 2223 ASSERT(instr->value()->representation().IsTagged()); |
| 2114 | 2224 |
| 2115 return MarkAsCall( | 2225 return MarkAsCall( |
| 2116 new(zone()) LStoreKeyedGeneric(context, object, key, value), instr); | 2226 new(zone()) LStoreKeyedGeneric(context, object, key, value), instr); |
| 2117 } | 2227 } |
| 2118 | 2228 |
| 2119 | 2229 |
| 2120 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 2230 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 2121 // TODO(jbramley): Optimize register usage in this instruction. For now, it | |
| 2122 // allocates everything that it might need because it keeps changing in the | |
| 2123 // merge and keeping it valid is time-consuming. | |
| 2124 | |
| 2125 // TODO(jbramley): It might be beneficial to allow value to be a constant in | 2231 // TODO(jbramley): It might be beneficial to allow value to be a constant in |
| 2126 // some cases. x64 makes use of this with FLAG_track_fields, for example. | 2232 // some cases. x64 makes use of this with FLAG_track_fields, for example. |
| 2127 | 2233 |
| 2128 LOperand* object = UseRegister(instr->object()); | 2234 LOperand* object = UseRegister(instr->object()); |
| 2129 LOperand* value = UseRegisterAndClobber(instr->value()); | 2235 LOperand* value; |
| 2130 LOperand* temp0 = TempRegister(); | 2236 LOperand* temp0 = NULL; |
| 2131 LOperand* temp1 = TempRegister(); | 2237 LOperand* temp1 = NULL; |
| 2238 |
| 2239 if (instr->access().IsExternalMemory() || |
| 2240 instr->field_representation().IsDouble()) { |
| 2241 value = UseRegister(instr->value()); |
| 2242 } else if (instr->NeedsWriteBarrier()) { |
| 2243 value = UseRegisterAndClobber(instr->value()); |
| 2244 temp0 = TempRegister(); |
| 2245 temp1 = TempRegister(); |
| 2246 } else if (instr->NeedsWriteBarrierForMap()) { |
| 2247 value = UseRegister(instr->value()); |
| 2248 temp0 = TempRegister(); |
| 2249 temp1 = TempRegister(); |
| 2250 } else { |
| 2251 value = UseRegister(instr->value()); |
| 2252 temp0 = TempRegister(); |
| 2253 } |
| 2132 | 2254 |
| 2133 LStoreNamedField* result = | 2255 LStoreNamedField* result = |
| 2134 new(zone()) LStoreNamedField(object, value, temp0, temp1); | 2256 new(zone()) LStoreNamedField(object, value, temp0, temp1); |
| 2135 if (FLAG_track_heap_object_fields && | 2257 if (instr->field_representation().IsHeapObject() && |
| 2136 instr->field_representation().IsHeapObject() && | |
| 2137 !instr->value()->type().IsHeapObject()) { | 2258 !instr->value()->type().IsHeapObject()) { |
| 2138 return AssignEnvironment(result); | 2259 return AssignEnvironment(result); |
| 2139 } | 2260 } |
| 2140 return result; | 2261 return result; |
| 2141 } | 2262 } |
| 2142 | 2263 |
| 2143 | 2264 |
| 2144 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 2265 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 2145 LOperand* context = UseFixed(instr->context(), cp); | 2266 LOperand* context = UseFixed(instr->context(), cp); |
| 2146 LOperand* object = UseFixed(instr->object(), x1); | 2267 LOperand* object = UseFixed(instr->object(), x1); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2440 | 2561 |
| 2441 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 2562 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
| 2442 LOperand* receiver = UseRegister(instr->receiver()); | 2563 LOperand* receiver = UseRegister(instr->receiver()); |
| 2443 LOperand* function = UseRegister(instr->function()); | 2564 LOperand* function = UseRegister(instr->function()); |
| 2444 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); | 2565 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); |
| 2445 return AssignEnvironment(DefineAsRegister(result)); | 2566 return AssignEnvironment(DefineAsRegister(result)); |
| 2446 } | 2567 } |
| 2447 | 2568 |
| 2448 | 2569 |
| 2449 } } // namespace v8::internal | 2570 } } // namespace v8::internal |
| OLD | NEW |