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 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 } | 864 } |
865 | 865 |
866 | 866 |
867 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 867 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
868 HInstruction* old_current = current_instruction_; | 868 HInstruction* old_current = current_instruction_; |
869 current_instruction_ = current; | 869 current_instruction_ = current; |
870 if (current->has_position()) position_ = current->position(); | 870 if (current->has_position()) position_ = current->position(); |
871 LInstruction* instr = current->CompileToLithium(this); | 871 LInstruction* instr = current->CompileToLithium(this); |
872 | 872 |
873 if (instr != NULL) { | 873 if (instr != NULL) { |
| 874 #if DEBUG |
| 875 // Make sure that the lithium instruction has either no fixed register |
| 876 // constraints in temps or the result OR no uses that are only used at |
| 877 // start. If this invariant doesn't hold, the register allocator can decide |
| 878 // to insert a split of a range immediately before the instruction due to an |
| 879 // already allocated register needing to be used for the instruction's fixed |
| 880 // register constraint. In this case, The register allocator won't see an |
| 881 // interference between the split child and the use-at-start (it would if |
| 882 // the it was just a plain use), so it is free to move the split child into |
| 883 // the same register that is used for the use-at-start. |
| 884 // See https://code.google.com/p/chromium/issues/detail?id=201590 |
| 885 if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { |
| 886 int fixed = 0; |
| 887 int used_at_start = 0; |
| 888 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
| 889 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 890 if (operand->IsUsedAtStart()) ++used_at_start; |
| 891 } |
| 892 if (instr->Output() != NULL) { |
| 893 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 894 } |
| 895 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 896 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 897 if (operand->HasFixedPolicy()) ++fixed; |
| 898 } |
| 899 ASSERT(fixed == 0 || used_at_start == 0); |
| 900 } |
| 901 #endif |
| 902 |
874 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 903 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
875 instr = AssignPointerMap(instr); | 904 instr = AssignPointerMap(instr); |
876 } | 905 } |
877 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 906 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
878 instr = AssignEnvironment(instr); | 907 instr = AssignEnvironment(instr); |
879 } | 908 } |
880 instr->set_hydrogen_value(current); | 909 instr->set_hydrogen_value(current); |
881 chunk_->AddInstruction(instr, current_block_); | 910 chunk_->AddInstruction(instr, current_block_); |
882 } | 911 } |
883 current_instruction_ = old_current; | 912 current_instruction_ = old_current; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 LOperand* temp2 = TempRegister(); | 1137 LOperand* temp2 = TempRegister(); |
1109 LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. | 1138 LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. |
1110 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); | 1139 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); |
1111 return DefineAsRegister(result); | 1140 return DefineAsRegister(result); |
1112 } else if (op == kMathPowHalf) { | 1141 } else if (op == kMathPowHalf) { |
1113 LOperand* input = UseFixedDouble(instr->value(), d2); | 1142 LOperand* input = UseFixedDouble(instr->value(), d2); |
1114 LOperand* temp = FixedTemp(d3); | 1143 LOperand* temp = FixedTemp(d3); |
1115 LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); | 1144 LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); |
1116 return DefineFixedDouble(result, d2); | 1145 return DefineFixedDouble(result, d2); |
1117 } else { | 1146 } else { |
1118 LOperand* input = UseRegisterAtStart(instr->value()); | 1147 LOperand* input = UseRegister(instr->value()); |
1119 | 1148 |
1120 LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL; | 1149 LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL; |
1121 LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); | 1150 LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, temp); |
1122 switch (op) { | 1151 switch (op) { |
1123 case kMathAbs: | 1152 case kMathAbs: |
1124 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1153 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
1125 case kMathFloor: | 1154 case kMathFloor: |
1126 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1155 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
1127 case kMathSqrt: | 1156 case kMathSqrt: |
1128 return DefineAsRegister(result); | 1157 return DefineAsRegister(result); |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 Representation from = instr->from(); | 1845 Representation from = instr->from(); |
1817 Representation to = instr->to(); | 1846 Representation to = instr->to(); |
1818 if (from.IsTagged()) { | 1847 if (from.IsTagged()) { |
1819 if (to.IsDouble()) { | 1848 if (to.IsDouble()) { |
1820 info()->MarkAsDeferredCalling(); | 1849 info()->MarkAsDeferredCalling(); |
1821 LOperand* value = UseRegister(instr->value()); | 1850 LOperand* value = UseRegister(instr->value()); |
1822 LNumberUntagD* res = new(zone()) LNumberUntagD(value); | 1851 LNumberUntagD* res = new(zone()) LNumberUntagD(value); |
1823 return AssignEnvironment(DefineAsRegister(res)); | 1852 return AssignEnvironment(DefineAsRegister(res)); |
1824 } else { | 1853 } else { |
1825 ASSERT(to.IsInteger32()); | 1854 ASSERT(to.IsInteger32()); |
1826 LOperand* value = UseRegisterAtStart(instr->value()); | 1855 LOperand* value = NULL; |
1827 LInstruction* res = NULL; | 1856 LInstruction* res = NULL; |
1828 if (instr->value()->type().IsSmi()) { | 1857 if (instr->value()->type().IsSmi()) { |
| 1858 value = UseRegisterAtStart(instr->value()); |
1829 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); | 1859 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); |
1830 } else { | 1860 } else { |
| 1861 value = UseRegister(instr->value()); |
1831 LOperand* temp1 = TempRegister(); | 1862 LOperand* temp1 = TempRegister(); |
1832 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() | 1863 LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister() |
1833 : NULL; | 1864 : NULL; |
1834 LOperand* temp3 = FixedTemp(d11); | 1865 LOperand* temp3 = FixedTemp(d11); |
1835 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, | 1866 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, |
1836 temp1, | 1867 temp1, |
1837 temp2, | 1868 temp2, |
1838 temp3)); | 1869 temp3)); |
1839 res = AssignEnvironment(res); | 1870 res = AssignEnvironment(res); |
1840 } | 1871 } |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 | 2571 |
2541 | 2572 |
2542 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2573 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2543 LOperand* object = UseRegister(instr->object()); | 2574 LOperand* object = UseRegister(instr->object()); |
2544 LOperand* index = UseRegister(instr->index()); | 2575 LOperand* index = UseRegister(instr->index()); |
2545 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2576 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2546 } | 2577 } |
2547 | 2578 |
2548 | 2579 |
2549 } } // namespace v8::internal | 2580 } } // namespace v8::internal |
OLD | NEW |