OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 } | 707 } |
708 | 708 |
709 | 709 |
710 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 710 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
711 return AssignEnvironment(new(zone()) LDeoptimize); | 711 return AssignEnvironment(new(zone()) LDeoptimize); |
712 } | 712 } |
713 | 713 |
714 | 714 |
715 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 715 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
716 HBitwiseBinaryOperation* instr) { | 716 HBitwiseBinaryOperation* instr) { |
717 if (instr->representation().IsTagged()) { | 717 if (instr->representation().IsSmiOrTagged()) { |
718 ASSERT(instr->left()->representation().IsTagged()); | 718 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
719 ASSERT(instr->right()->representation().IsTagged()); | 719 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
720 | 720 |
721 LOperand* left = UseFixed(instr->left(), a1); | 721 LOperand* left = UseFixed(instr->left(), a1); |
722 LOperand* right = UseFixed(instr->right(), a0); | 722 LOperand* right = UseFixed(instr->right(), a0); |
723 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); | 723 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
724 return MarkAsCall(DefineFixed(result, v0), instr); | 724 return MarkAsCall(DefineFixed(result, v0), instr); |
725 } | 725 } |
726 | 726 |
727 ASSERT(instr->representation().IsInteger32()); | 727 ASSERT(instr->representation().IsInteger32()); |
728 ASSERT(instr->left()->representation().IsInteger32()); | 728 ASSERT(instr->left()->representation().IsInteger32()); |
729 ASSERT(instr->right()->representation().IsInteger32()); | 729 ASSERT(instr->right()->representation().IsInteger32()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 | 777 |
778 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 778 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
779 HArithmeticBinaryOperation* instr) { | 779 HArithmeticBinaryOperation* instr) { |
780 ASSERT(op == Token::ADD || | 780 ASSERT(op == Token::ADD || |
781 op == Token::DIV || | 781 op == Token::DIV || |
782 op == Token::MOD || | 782 op == Token::MOD || |
783 op == Token::MUL || | 783 op == Token::MUL || |
784 op == Token::SUB); | 784 op == Token::SUB); |
785 HValue* left = instr->left(); | 785 HValue* left = instr->left(); |
786 HValue* right = instr->right(); | 786 HValue* right = instr->right(); |
787 ASSERT(left->representation().IsTagged()); | 787 ASSERT(left->representation().IsSmiOrTagged()); |
788 ASSERT(right->representation().IsTagged()); | 788 ASSERT(right->representation().IsSmiOrTagged()); |
789 LOperand* left_operand = UseFixed(left, a1); | 789 LOperand* left_operand = UseFixed(left, a1); |
790 LOperand* right_operand = UseFixed(right, a0); | 790 LOperand* right_operand = UseFixed(right, a0); |
791 LArithmeticT* result = | 791 LArithmeticT* result = |
792 new(zone()) LArithmeticT(op, left_operand, right_operand); | 792 new(zone()) LArithmeticT(op, left_operand, right_operand); |
793 return MarkAsCall(DefineFixed(result, v0), instr); | 793 return MarkAsCall(DefineFixed(result, v0), instr); |
794 } | 794 } |
795 | 795 |
796 | 796 |
797 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 797 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
798 ASSERT(is_building()); | 798 ASSERT(is_building()); |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 | 1297 |
1298 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1298 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
1299 if (instr->representation().IsInteger32()) { | 1299 if (instr->representation().IsInteger32()) { |
1300 ASSERT(instr->left()->representation().IsInteger32()); | 1300 ASSERT(instr->left()->representation().IsInteger32()); |
1301 ASSERT(instr->right()->representation().IsInteger32()); | 1301 ASSERT(instr->right()->representation().IsInteger32()); |
1302 | 1302 |
1303 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1303 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1304 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1304 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1305 return DefineAsRegister(new(zone()) LBitI(left, right)); | 1305 return DefineAsRegister(new(zone()) LBitI(left, right)); |
1306 } else { | 1306 } else { |
1307 ASSERT(instr->representation().IsTagged()); | 1307 ASSERT(instr->representation().IsSmiOrTagged()); |
1308 ASSERT(instr->left()->representation().IsTagged()); | 1308 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
1309 ASSERT(instr->right()->representation().IsTagged()); | 1309 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
1310 | 1310 |
1311 LOperand* left = UseFixed(instr->left(), a1); | 1311 LOperand* left = UseFixed(instr->left(), a1); |
1312 LOperand* right = UseFixed(instr->right(), a0); | 1312 LOperand* right = UseFixed(instr->right(), a0); |
1313 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); | 1313 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); |
1314 return MarkAsCall(DefineFixed(result, v0), instr); | 1314 return MarkAsCall(DefineFixed(result, v0), instr); |
1315 } | 1315 } |
1316 } | 1316 } |
1317 | 1317 |
1318 | 1318 |
1319 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { | 1319 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 FixedTemp(f22)); | 1370 FixedTemp(f22)); |
1371 } | 1371 } |
1372 | 1372 |
1373 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1373 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1374 instr->CheckFlag(HValue::kCanBeDivByZero) || | 1374 instr->CheckFlag(HValue::kCanBeDivByZero) || |
1375 instr->CheckFlag(HValue::kCanOverflow)) { | 1375 instr->CheckFlag(HValue::kCanOverflow)) { |
1376 return AssignEnvironment(DefineAsRegister(mod)); | 1376 return AssignEnvironment(DefineAsRegister(mod)); |
1377 } else { | 1377 } else { |
1378 return DefineAsRegister(mod); | 1378 return DefineAsRegister(mod); |
1379 } | 1379 } |
1380 } else if (instr->representation().IsTagged()) { | 1380 } else if (instr->representation().IsSmiOrTagged()) { |
1381 return DoArithmeticT(Token::MOD, instr); | 1381 return DoArithmeticT(Token::MOD, instr); |
1382 } else { | 1382 } else { |
1383 ASSERT(instr->representation().IsDouble()); | 1383 ASSERT(instr->representation().IsDouble()); |
1384 // We call a C function for double modulo. It can't trigger a GC. | 1384 // We call a C function for double modulo. It can't trigger a GC. |
1385 // We need to use fixed result register for the call. | 1385 // We need to use fixed result register for the call. |
1386 // TODO(fschneider): Allow any register as input registers. | 1386 // TODO(fschneider): Allow any register as input registers. |
1387 LOperand* left = UseFixedDouble(instr->left(), f2); | 1387 LOperand* left = UseFixedDouble(instr->left(), f2); |
1388 LOperand* right = UseFixedDouble(instr->right(), f4); | 1388 LOperand* right = UseFixedDouble(instr->right(), f4); |
1389 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1389 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); |
1390 return MarkAsCall(DefineFixedDouble(result, f2), instr); | 1390 return MarkAsCall(DefineFixedDouble(result, f2), instr); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 if (instr->left()->IsMul()) | 1483 if (instr->left()->IsMul()) |
1484 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); | 1484 return DoMultiplyAdd(HMul::cast(instr->left()), instr->right()); |
1485 | 1485 |
1486 if (instr->right()->IsMul()) { | 1486 if (instr->right()->IsMul()) { |
1487 ASSERT(!instr->left()->IsMul()); | 1487 ASSERT(!instr->left()->IsMul()); |
1488 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); | 1488 return DoMultiplyAdd(HMul::cast(instr->right()), instr->left()); |
1489 } | 1489 } |
1490 } | 1490 } |
1491 return DoArithmeticD(Token::ADD, instr); | 1491 return DoArithmeticD(Token::ADD, instr); |
1492 } else { | 1492 } else { |
1493 ASSERT(instr->representation().IsTagged()); | 1493 ASSERT(instr->representation().IsSmiOrTagged()); |
1494 return DoArithmeticT(Token::ADD, instr); | 1494 return DoArithmeticT(Token::ADD, instr); |
1495 } | 1495 } |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1499 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1500 LOperand* left = NULL; | 1500 LOperand* left = NULL; |
1501 LOperand* right = NULL; | 1501 LOperand* right = NULL; |
1502 if (instr->representation().IsInteger32()) { | 1502 if (instr->representation().IsInteger32()) { |
1503 ASSERT(instr->left()->representation().IsInteger32()); | 1503 ASSERT(instr->left()->representation().IsInteger32()); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1755 return NULL; | 1755 return NULL; |
1756 } | 1756 } |
1757 | 1757 |
1758 | 1758 |
1759 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1759 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
1760 Representation from = instr->from(); | 1760 Representation from = instr->from(); |
1761 Representation to = instr->to(); | 1761 Representation to = instr->to(); |
1762 if (from.IsSmi()) { | 1762 if (from.IsSmi()) { |
1763 if (to.IsTagged()) { | 1763 if (to.IsTagged()) { |
1764 LOperand* value = UseRegister(instr->value()); | 1764 LOperand* value = UseRegister(instr->value()); |
1765 // For now, always deopt on hole. | |
1766 if (instr->value()->IsLoadKeyed() && | |
1767 HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) { | |
1768 return AssignEnvironment( | |
1769 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); | |
1770 } | |
1771 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1765 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
1772 } | 1766 } |
1773 from = Representation::Tagged(); | 1767 from = Representation::Tagged(); |
1774 } | 1768 } |
1775 if (from.IsTagged()) { | 1769 if (from.IsTagged()) { |
1776 if (to.IsDouble()) { | 1770 if (to.IsDouble()) { |
1777 info()->MarkAsDeferredCalling(); | 1771 info()->MarkAsDeferredCalling(); |
1778 LOperand* value = UseRegister(instr->value()); | 1772 LOperand* value = UseRegister(instr->value()); |
1779 LNumberUntagD* res = new(zone()) LNumberUntagD(value); | 1773 LNumberUntagD* res = new(zone()) LNumberUntagD(value); |
1780 return AssignEnvironment(DefineAsRegister(res)); | 1774 return AssignEnvironment(DefineAsRegister(res)); |
1781 } else if (to.IsSmi()) { | 1775 } else if (to.IsSmi()) { |
1782 HValue* val = instr->value(); | 1776 HValue* val = instr->value(); |
1783 LOperand* value = UseRegister(val); | 1777 LOperand* value = UseRegister(val); |
1784 return AssignEnvironment( | 1778 return AssignEnvironment( |
1785 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); | 1779 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); |
1786 } else { | 1780 } else { |
1787 ASSERT(to.IsInteger32()); | 1781 ASSERT(to.IsInteger32()); |
1788 LOperand* value = NULL; | 1782 LOperand* value = NULL; |
1789 LInstruction* res = NULL; | 1783 LInstruction* res = NULL; |
1790 if (instr->value()->type().IsSmi()) { | 1784 if (instr->value()->type().IsSmi()) { |
1791 value = UseRegisterAtStart(instr->value()); | 1785 value = UseRegisterAtStart(instr->value()); |
1792 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); | 1786 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
1793 if (instr->value()->IsLoadKeyed()) { | |
1794 HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value()); | |
1795 if (load_keyed->UsesMustHandleHole() && | |
1796 load_keyed->hole_mode() == NEVER_RETURN_HOLE) { | |
1797 res = AssignEnvironment(res); | |
1798 } | |
1799 } | |
1800 } else { | 1787 } else { |
1801 value = UseRegister(instr->value()); | 1788 value = UseRegister(instr->value()); |
1802 LOperand* temp1 = TempRegister(); | 1789 LOperand* temp1 = TempRegister(); |
1803 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() | 1790 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() |
1804 : NULL; | 1791 : NULL; |
1805 LOperand* temp3 = FixedTemp(f22); | 1792 LOperand* temp3 = FixedTemp(f22); |
1806 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, | 1793 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, |
1807 temp1, | 1794 temp1, |
1808 temp2, | 1795 temp2, |
1809 temp3)); | 1796 temp3)); |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2521 | 2508 |
2522 | 2509 |
2523 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2510 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2524 LOperand* object = UseRegister(instr->object()); | 2511 LOperand* object = UseRegister(instr->object()); |
2525 LOperand* index = UseRegister(instr->index()); | 2512 LOperand* index = UseRegister(instr->index()); |
2526 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2513 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2527 } | 2514 } |
2528 | 2515 |
2529 | 2516 |
2530 } } // namespace v8::internal | 2517 } } // namespace v8::internal |
OLD | NEW |