OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "lithium-allocator-inl.h" | 7 #include "lithium-allocator-inl.h" |
8 #include "arm64/lithium-arm64.h" | 8 #include "arm64/lithium-arm64.h" |
9 #include "arm64/lithium-codegen-arm64.h" | 9 #include "arm64/lithium-codegen-arm64.h" |
10 #include "hydrogen-osr.h" | 10 #include "hydrogen-osr.h" |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 LDummyUse(UseAny(current->OperandAt(0)))); | 665 LDummyUse(UseAny(current->OperandAt(0)))); |
666 } | 666 } |
667 for (int i = 1; i < current->OperandCount(); ++i) { | 667 for (int i = 1; i < current->OperandCount(); ++i) { |
668 if (current->OperandAt(i)->IsControlInstruction()) continue; | 668 if (current->OperandAt(i)->IsControlInstruction()) continue; |
669 LInstruction* dummy = | 669 LInstruction* dummy = |
670 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 670 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
671 dummy->set_hydrogen_value(current); | 671 dummy->set_hydrogen_value(current); |
672 chunk_->AddInstruction(dummy, current_block_); | 672 chunk_->AddInstruction(dummy, current_block_); |
673 } | 673 } |
674 } else { | 674 } else { |
675 instr = current->CompileToLithium(this); | 675 HBasicBlock* successor; |
| 676 if (current->IsControlInstruction() && |
| 677 HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) && |
| 678 successor != NULL) { |
| 679 instr = new(zone()) LGoto(successor); |
| 680 } else { |
| 681 instr = current->CompileToLithium(this); |
| 682 } |
676 } | 683 } |
677 | 684 |
678 argument_count_ += current->argument_delta(); | 685 argument_count_ += current->argument_delta(); |
679 ASSERT(argument_count_ >= 0); | 686 ASSERT(argument_count_ >= 0); |
680 | 687 |
681 if (instr != NULL) { | 688 if (instr != NULL) { |
682 AddInstruction(instr, current); | 689 AddInstruction(instr, current); |
683 } | 690 } |
684 | 691 |
685 current_instruction_ = old_current; | 692 current_instruction_ = old_current; |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 : UseRegisterAtStart(instr->length()); | 972 : UseRegisterAtStart(instr->length()); |
966 LInstruction* result = new(zone()) LBoundsCheck(index, length); | 973 LInstruction* result = new(zone()) LBoundsCheck(index, length); |
967 if (!FLAG_debug_code || !instr->skip_check()) { | 974 if (!FLAG_debug_code || !instr->skip_check()) { |
968 result = AssignEnvironment(result); | 975 result = AssignEnvironment(result); |
969 } | 976 } |
970 return result; | 977 return result; |
971 } | 978 } |
972 | 979 |
973 | 980 |
974 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 981 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
975 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
976 if (goto_instr != NULL) return goto_instr; | |
977 | |
978 HValue* value = instr->value(); | 982 HValue* value = instr->value(); |
979 Representation r = value->representation(); | 983 Representation r = value->representation(); |
980 HType type = value->type(); | 984 HType type = value->type(); |
981 | 985 |
982 if (r.IsInteger32() || r.IsSmi() || r.IsDouble()) { | 986 if (r.IsInteger32() || r.IsSmi() || r.IsDouble()) { |
983 // These representations have simple checks that cannot deoptimize. | 987 // These representations have simple checks that cannot deoptimize. |
984 return new(zone()) LBranch(UseRegister(value), NULL, NULL); | 988 return new(zone()) LBranch(UseRegister(value), NULL, NULL); |
985 } else { | 989 } else { |
986 ASSERT(r.IsTagged()); | 990 ASSERT(r.IsTagged()); |
987 if (type.IsBoolean() || type.IsSmi() || type.IsJSArray() || | 991 if (type.IsBoolean() || type.IsSmi() || type.IsJSArray() || |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 ASSERT(instr->value()->representation().IsTagged()); | 1256 ASSERT(instr->value()->representation().IsTagged()); |
1253 LOperand* value = UseRegisterAtStart(instr->value()); | 1257 LOperand* value = UseRegisterAtStart(instr->value()); |
1254 return new(zone()) LClassOfTestAndBranch(value, | 1258 return new(zone()) LClassOfTestAndBranch(value, |
1255 TempRegister(), | 1259 TempRegister(), |
1256 TempRegister()); | 1260 TempRegister()); |
1257 } | 1261 } |
1258 | 1262 |
1259 | 1263 |
1260 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( | 1264 LInstruction* LChunkBuilder::DoCompareNumericAndBranch( |
1261 HCompareNumericAndBranch* instr) { | 1265 HCompareNumericAndBranch* instr) { |
1262 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1263 if (goto_instr != NULL) return goto_instr; | |
1264 Representation r = instr->representation(); | 1266 Representation r = instr->representation(); |
1265 if (r.IsSmiOrInteger32()) { | 1267 if (r.IsSmiOrInteger32()) { |
1266 ASSERT(instr->left()->representation().Equals(r)); | 1268 ASSERT(instr->left()->representation().Equals(r)); |
1267 ASSERT(instr->right()->representation().Equals(r)); | 1269 ASSERT(instr->right()->representation().Equals(r)); |
1268 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); | 1270 LOperand* left = UseRegisterOrConstantAtStart(instr->left()); |
1269 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); | 1271 LOperand* right = UseRegisterOrConstantAtStart(instr->right()); |
1270 return new(zone()) LCompareNumericAndBranch(left, right); | 1272 return new(zone()) LCompareNumericAndBranch(left, right); |
1271 } else { | 1273 } else { |
1272 ASSERT(r.IsDouble()); | 1274 ASSERT(r.IsDouble()); |
1273 ASSERT(instr->left()->representation().IsDouble()); | 1275 ASSERT(instr->left()->representation().IsDouble()); |
(...skipping 30 matching lines...) Expand all Loading... |
1304 return new(zone()) LCmpHoleAndBranchT(value); | 1306 return new(zone()) LCmpHoleAndBranchT(value); |
1305 } else { | 1307 } else { |
1306 LOperand* temp = TempRegister(); | 1308 LOperand* temp = TempRegister(); |
1307 return new(zone()) LCmpHoleAndBranchD(value, temp); | 1309 return new(zone()) LCmpHoleAndBranchD(value, temp); |
1308 } | 1310 } |
1309 } | 1311 } |
1310 | 1312 |
1311 | 1313 |
1312 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( | 1314 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( |
1313 HCompareObjectEqAndBranch* instr) { | 1315 HCompareObjectEqAndBranch* instr) { |
1314 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1315 if (goto_instr != NULL) return goto_instr; | |
1316 | |
1317 LOperand* left = UseRegisterAtStart(instr->left()); | 1316 LOperand* left = UseRegisterAtStart(instr->left()); |
1318 LOperand* right = UseRegisterAtStart(instr->right()); | 1317 LOperand* right = UseRegisterAtStart(instr->right()); |
1319 return new(zone()) LCmpObjectEqAndBranch(left, right); | 1318 return new(zone()) LCmpObjectEqAndBranch(left, right); |
1320 } | 1319 } |
1321 | 1320 |
1322 | 1321 |
1323 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1322 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
1324 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1325 if (goto_instr != NULL) return goto_instr; | |
1326 | |
1327 ASSERT(instr->value()->representation().IsTagged()); | 1323 ASSERT(instr->value()->representation().IsTagged()); |
1328 LOperand* value = UseRegisterAtStart(instr->value()); | 1324 LOperand* value = UseRegisterAtStart(instr->value()); |
1329 LOperand* temp = TempRegister(); | 1325 LOperand* temp = TempRegister(); |
1330 return new(zone()) LCmpMapAndBranch(value, temp); | 1326 return new(zone()) LCmpMapAndBranch(value, temp); |
1331 } | 1327 } |
1332 | 1328 |
1333 | 1329 |
1334 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1330 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1335 Representation r = instr->representation(); | 1331 Representation r = instr->representation(); |
1336 if (r.IsSmi()) { | 1332 if (r.IsSmi()) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1570 | 1566 |
1571 | 1567 |
1572 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 1568 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
1573 HIsConstructCallAndBranch* instr) { | 1569 HIsConstructCallAndBranch* instr) { |
1574 return new(zone()) LIsConstructCallAndBranch(TempRegister(), TempRegister()); | 1570 return new(zone()) LIsConstructCallAndBranch(TempRegister(), TempRegister()); |
1575 } | 1571 } |
1576 | 1572 |
1577 | 1573 |
1578 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( | 1574 LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch( |
1579 HCompareMinusZeroAndBranch* instr) { | 1575 HCompareMinusZeroAndBranch* instr) { |
1580 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
1581 if (goto_instr != NULL) return goto_instr; | |
1582 LOperand* value = UseRegister(instr->value()); | 1576 LOperand* value = UseRegister(instr->value()); |
1583 LOperand* scratch = TempRegister(); | 1577 LOperand* scratch = TempRegister(); |
1584 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); | 1578 return new(zone()) LCompareMinusZeroAndBranch(value, scratch); |
1585 } | 1579 } |
1586 | 1580 |
1587 | 1581 |
1588 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { | 1582 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) { |
1589 ASSERT(instr->value()->representation().IsTagged()); | 1583 ASSERT(instr->value()->representation().IsTagged()); |
1590 LOperand* value = UseRegisterAtStart(instr->value()); | 1584 LOperand* value = UseRegisterAtStart(instr->value()); |
1591 LOperand* temp1 = TempRegister(); | 1585 LOperand* temp1 = TempRegister(); |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2548 // However, LCodeGen::DoTypeof just pushes it to the stack (for CallRuntime) | 2542 // However, LCodeGen::DoTypeof just pushes it to the stack (for CallRuntime) |
2549 // anyway, so the input doesn't have to be in x0. We might be able to improve | 2543 // anyway, so the input doesn't have to be in x0. We might be able to improve |
2550 // the ARM back-end a little by relaxing this restriction. | 2544 // the ARM back-end a little by relaxing this restriction. |
2551 LTypeof* result = | 2545 LTypeof* result = |
2552 new(zone()) LTypeof(context, UseRegisterAtStart(instr->value())); | 2546 new(zone()) LTypeof(context, UseRegisterAtStart(instr->value())); |
2553 return MarkAsCall(DefineFixed(result, x0), instr); | 2547 return MarkAsCall(DefineFixed(result, x0), instr); |
2554 } | 2548 } |
2555 | 2549 |
2556 | 2550 |
2557 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { | 2551 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) { |
2558 LInstruction* goto_instr = CheckElideControlInstruction(instr); | |
2559 if (goto_instr != NULL) return goto_instr; | |
2560 | |
2561 // We only need temp registers in some cases, but we can't dereference the | 2552 // We only need temp registers in some cases, but we can't dereference the |
2562 // instr->type_literal() handle to test that here. | 2553 // instr->type_literal() handle to test that here. |
2563 LOperand* temp1 = TempRegister(); | 2554 LOperand* temp1 = TempRegister(); |
2564 LOperand* temp2 = TempRegister(); | 2555 LOperand* temp2 = TempRegister(); |
2565 | 2556 |
2566 return new(zone()) LTypeofIsAndBranch( | 2557 return new(zone()) LTypeofIsAndBranch( |
2567 UseRegister(instr->value()), temp1, temp2); | 2558 UseRegister(instr->value()), temp1, temp2); |
2568 } | 2559 } |
2569 | 2560 |
2570 | 2561 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2717 | 2708 |
2718 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 2709 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
2719 LOperand* receiver = UseRegister(instr->receiver()); | 2710 LOperand* receiver = UseRegister(instr->receiver()); |
2720 LOperand* function = UseRegister(instr->function()); | 2711 LOperand* function = UseRegister(instr->function()); |
2721 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); | 2712 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); |
2722 return AssignEnvironment(DefineAsRegister(result)); | 2713 return AssignEnvironment(DefineAsRegister(result)); |
2723 } | 2714 } |
2724 | 2715 |
2725 | 2716 |
2726 } } // namespace v8::internal | 2717 } } // namespace v8::internal |
OLD | NEW |