OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 443 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
444 __ SmiUntag(caller_args_count_reg); | 444 __ SmiUntag(caller_args_count_reg); |
445 | 445 |
446 ParameterCount callee_args_count(args_reg); | 446 ParameterCount callee_args_count(args_reg); |
447 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, | 447 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, |
448 scratch3); | 448 scratch3); |
449 __ bind(&done); | 449 __ bind(&done); |
450 } | 450 } |
451 | 451 |
452 // Assembles an instruction after register allocation, producing machine code. | 452 // Assembles an instruction after register allocation, producing machine code. |
453 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 453 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| 454 Instruction* instr) { |
454 ArmOperandConverter i(this, instr); | 455 ArmOperandConverter i(this, instr); |
455 | 456 |
456 __ MaybeCheckConstPool(); | 457 __ MaybeCheckConstPool(); |
457 InstructionCode opcode = instr->opcode(); | 458 InstructionCode opcode = instr->opcode(); |
458 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); | 459 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); |
459 switch (arch_opcode) { | 460 switch (arch_opcode) { |
460 case kArchCallCodeObject: { | 461 case kArchCallCodeObject: { |
461 EnsureSpaceForLazyDeopt(); | 462 EnsureSpaceForLazyDeopt(); |
462 if (instr->InputAt(0)->IsImmediate()) { | 463 if (instr->InputAt(0)->IsImmediate()) { |
463 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), | 464 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 case kArchNop: | 578 case kArchNop: |
578 case kArchThrowTerminator: | 579 case kArchThrowTerminator: |
579 // don't emit code for nops. | 580 // don't emit code for nops. |
580 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 581 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
581 break; | 582 break; |
582 case kArchDeoptimize: { | 583 case kArchDeoptimize: { |
583 int deopt_state_id = | 584 int deopt_state_id = |
584 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 585 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
585 Deoptimizer::BailoutType bailout_type = | 586 Deoptimizer::BailoutType bailout_type = |
586 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); | 587 Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); |
587 AssembleDeoptimizerCall(deopt_state_id, bailout_type); | 588 CodeGenResult result = |
| 589 AssembleDeoptimizerCall(deopt_state_id, bailout_type); |
| 590 if (result != kSuccess) return result; |
588 break; | 591 break; |
589 } | 592 } |
590 case kArchRet: | 593 case kArchRet: |
591 AssembleReturn(); | 594 AssembleReturn(); |
592 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 595 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
593 break; | 596 break; |
594 case kArchStackPointer: | 597 case kArchStackPointer: |
595 __ mov(i.OutputRegister(), sp); | 598 __ mov(i.OutputRegister(), sp); |
596 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 599 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
597 break; | 600 break; |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 case kAtomicLoadInt16: | 1268 case kAtomicLoadInt16: |
1266 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrsh); | 1269 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrsh); |
1267 break; | 1270 break; |
1268 case kAtomicLoadUint16: | 1271 case kAtomicLoadUint16: |
1269 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrh); | 1272 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldrh); |
1270 break; | 1273 break; |
1271 case kAtomicLoadWord32: | 1274 case kAtomicLoadWord32: |
1272 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldr); | 1275 ASSEMBLE_ATOMIC_LOAD_INTEGER(ldr); |
1273 break; | 1276 break; |
1274 } | 1277 } |
| 1278 return kSuccess; |
1275 } // NOLINT(readability/fn_size) | 1279 } // NOLINT(readability/fn_size) |
1276 | 1280 |
1277 | 1281 |
1278 // Assembles branches after an instruction. | 1282 // Assembles branches after an instruction. |
1279 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 1283 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
1280 ArmOperandConverter i(this, instr); | 1284 ArmOperandConverter i(this, instr); |
1281 Label* tlabel = branch->true_label; | 1285 Label* tlabel = branch->true_label; |
1282 Label* flabel = branch->false_label; | 1286 Label* flabel = branch->false_label; |
1283 Condition cc = FlagsConditionToCondition(branch->condition); | 1287 Condition cc = FlagsConditionToCondition(branch->condition); |
1284 __ b(cc, tlabel); | 1288 __ b(cc, tlabel); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 __ CheckConstPool(true, true); | 1329 __ CheckConstPool(true, true); |
1326 __ cmp(input, Operand(case_count)); | 1330 __ cmp(input, Operand(case_count)); |
1327 __ BlockConstPoolFor(case_count + 2); | 1331 __ BlockConstPoolFor(case_count + 2); |
1328 __ add(pc, pc, Operand(input, LSL, 2), LeaveCC, lo); | 1332 __ add(pc, pc, Operand(input, LSL, 2), LeaveCC, lo); |
1329 __ b(GetLabel(i.InputRpo(1))); | 1333 __ b(GetLabel(i.InputRpo(1))); |
1330 for (size_t index = 0; index < case_count; ++index) { | 1334 for (size_t index = 0; index < case_count; ++index) { |
1331 __ b(GetLabel(i.InputRpo(index + 2))); | 1335 __ b(GetLabel(i.InputRpo(index + 2))); |
1332 } | 1336 } |
1333 } | 1337 } |
1334 | 1338 |
1335 | 1339 CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( |
1336 void CodeGenerator::AssembleDeoptimizerCall( | |
1337 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { | 1340 int deoptimization_id, Deoptimizer::BailoutType bailout_type) { |
1338 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 1341 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
1339 isolate(), deoptimization_id, bailout_type); | 1342 isolate(), deoptimization_id, bailout_type); |
1340 // TODO(turbofan): We should be able to generate better code by sharing the | 1343 // TODO(turbofan): We should be able to generate better code by sharing the |
1341 // actual final call site and just bl'ing to it here, similar to what we do | 1344 // actual final call site and just bl'ing to it here, similar to what we do |
1342 // in the lithium backend. | 1345 // in the lithium backend. |
| 1346 if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; |
1343 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 1347 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
1344 __ CheckConstPool(false, false); | 1348 __ CheckConstPool(false, false); |
| 1349 return kSuccess; |
1345 } | 1350 } |
1346 | 1351 |
1347 void CodeGenerator::FinishFrame(Frame* frame) { | 1352 void CodeGenerator::FinishFrame(Frame* frame) { |
1348 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 1353 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
1349 | 1354 |
1350 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); | 1355 const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); |
1351 if (saves_fp != 0) { | 1356 if (saves_fp != 0) { |
1352 frame->AlignSavedCalleeRegisterSlots(); | 1357 frame->AlignSavedCalleeRegisterSlots(); |
1353 } | 1358 } |
1354 | 1359 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 padding_size -= v8::internal::Assembler::kInstrSize; | 1681 padding_size -= v8::internal::Assembler::kInstrSize; |
1677 } | 1682 } |
1678 } | 1683 } |
1679 } | 1684 } |
1680 | 1685 |
1681 #undef __ | 1686 #undef __ |
1682 | 1687 |
1683 } // namespace compiler | 1688 } // namespace compiler |
1684 } // namespace internal | 1689 } // namespace internal |
1685 } // namespace v8 | 1690 } // namespace v8 |
OLD | NEW |