| 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 |