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 "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/address-map.h" | 7 #include "src/address-map.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 Label** targets() const { return targets_; } | 24 Label** targets() const { return targets_; } |
25 size_t target_count() const { return target_count_; } | 25 size_t target_count() const { return target_count_; } |
26 | 26 |
27 private: | 27 private: |
28 Label label_; | 28 Label label_; |
29 JumpTable* const next_; | 29 JumpTable* const next_; |
30 Label** const targets_; | 30 Label** const targets_; |
31 size_t const target_count_; | 31 size_t const target_count_; |
32 }; | 32 }; |
33 | 33 |
34 | |
35 CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, | 34 CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, |
36 InstructionSequence* code, CompilationInfo* info) | 35 InstructionSequence* code, CompilationInfo* info) |
37 : frame_access_state_(new (code->zone()) FrameAccessState(frame)), | 36 : frame_access_state_(new (code->zone()) FrameAccessState(frame)), |
38 linkage_(linkage), | 37 linkage_(linkage), |
39 code_(code), | 38 code_(code), |
40 info_(info), | 39 info_(info), |
41 labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), | 40 labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), |
42 current_block_(RpoNumber::Invalid()), | 41 current_block_(RpoNumber::Invalid()), |
43 current_source_position_(SourcePosition::Unknown()), | 42 current_source_position_(SourcePosition::Unknown()), |
44 masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes), | 43 masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes), |
45 resolver_(this), | 44 resolver_(this), |
46 safepoints_(code->zone()), | 45 safepoints_(code->zone()), |
47 handlers_(code->zone()), | 46 handlers_(code->zone()), |
| 47 deoptimization_exits_(code->zone()), |
48 deoptimization_states_(code->zone()), | 48 deoptimization_states_(code->zone()), |
49 deoptimization_literals_(code->zone()), | 49 deoptimization_literals_(code->zone()), |
50 inlined_function_count_(0), | 50 inlined_function_count_(0), |
51 translations_(code->zone()), | 51 translations_(code->zone()), |
52 last_lazy_deopt_pc_(0), | 52 last_lazy_deopt_pc_(0), |
53 jump_tables_(nullptr), | 53 jump_tables_(nullptr), |
54 ools_(nullptr), | 54 ools_(nullptr), |
55 osr_pc_offset_(-1) { | 55 osr_pc_offset_(-1) { |
56 for (int i = 0; i < code->InstructionBlockCount(); ++i) { | 56 for (int i = 0; i < code->InstructionBlockCount(); ++i) { |
57 new (&labels_[i]) Label; | 57 new (&labels_[i]) Label; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 // Assemble all out-of-line code. | 151 // Assemble all out-of-line code. |
152 if (ools_) { | 152 if (ools_) { |
153 masm()->RecordComment("-- Out of line code --"); | 153 masm()->RecordComment("-- Out of line code --"); |
154 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { | 154 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { |
155 masm()->bind(ool->entry()); | 155 masm()->bind(ool->entry()); |
156 ool->Generate(); | 156 ool->Generate(); |
157 if (ool->exit()->is_bound()) masm()->jmp(ool->exit()); | 157 if (ool->exit()->is_bound()) masm()->jmp(ool->exit()); |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
| 161 // Assemble all eager deoptimization exits. |
| 162 for (DeoptimizationExit* exit : deoptimization_exits_) { |
| 163 masm()->bind(exit->label()); |
| 164 AssembleDeoptimizerCall(exit->deoptimization_id(), Deoptimizer::EAGER); |
| 165 } |
| 166 |
161 // Ensure there is space for lazy deoptimization in the code. | 167 // Ensure there is space for lazy deoptimization in the code. |
162 if (info->ShouldEnsureSpaceForLazyDeopt()) { | 168 if (info->ShouldEnsureSpaceForLazyDeopt()) { |
163 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); | 169 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); |
164 while (masm()->pc_offset() < target_offset) { | 170 while (masm()->pc_offset() < target_offset) { |
165 masm()->nop(); | 171 masm()->nop(); |
166 } | 172 } |
167 } | 173 } |
168 | 174 |
169 FinishCode(masm()); | 175 FinishCode(masm()); |
170 | 176 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 290 |
285 | 291 |
286 void CodeGenerator::AssembleInstruction(Instruction* instr) { | 292 void CodeGenerator::AssembleInstruction(Instruction* instr) { |
287 AssembleGaps(instr); | 293 AssembleGaps(instr); |
288 AssembleSourcePosition(instr); | 294 AssembleSourcePosition(instr); |
289 // Assemble architecture-specific code for the instruction. | 295 // Assemble architecture-specific code for the instruction. |
290 AssembleArchInstruction(instr); | 296 AssembleArchInstruction(instr); |
291 | 297 |
292 FlagsMode mode = FlagsModeField::decode(instr->opcode()); | 298 FlagsMode mode = FlagsModeField::decode(instr->opcode()); |
293 FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); | 299 FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); |
294 if (mode == kFlags_branch) { | 300 switch (mode) { |
295 // Assemble a branch after this instruction. | 301 case kFlags_branch: { |
296 InstructionOperandConverter i(this, instr); | 302 // Assemble a branch after this instruction. |
297 RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2); | 303 InstructionOperandConverter i(this, instr); |
298 RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1); | 304 RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2); |
| 305 RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1); |
299 | 306 |
300 if (true_rpo == false_rpo) { | 307 if (true_rpo == false_rpo) { |
301 // redundant branch. | 308 // redundant branch. |
302 if (!IsNextInAssemblyOrder(true_rpo)) { | 309 if (!IsNextInAssemblyOrder(true_rpo)) { |
303 AssembleArchJump(true_rpo); | 310 AssembleArchJump(true_rpo); |
| 311 } |
| 312 return; |
304 } | 313 } |
305 return; | 314 if (IsNextInAssemblyOrder(true_rpo)) { |
| 315 // true block is next, can fall through if condition negated. |
| 316 std::swap(true_rpo, false_rpo); |
| 317 condition = NegateFlagsCondition(condition); |
| 318 } |
| 319 BranchInfo branch; |
| 320 branch.condition = condition; |
| 321 branch.true_label = GetLabel(true_rpo); |
| 322 branch.false_label = GetLabel(false_rpo); |
| 323 branch.fallthru = IsNextInAssemblyOrder(false_rpo); |
| 324 // Assemble architecture-specific branch. |
| 325 AssembleArchBranch(instr, &branch); |
| 326 break; |
306 } | 327 } |
307 if (IsNextInAssemblyOrder(true_rpo)) { | 328 case kFlags_deoptimize: { |
308 // true block is next, can fall through if condition negated. | 329 // Assemble a conditional eager deoptimization after this instruction. |
309 std::swap(true_rpo, false_rpo); | 330 InstructionOperandConverter i(this, instr); |
310 condition = NegateFlagsCondition(condition); | 331 size_t frame_state_offset = MiscField::decode(instr->opcode()); |
| 332 DeoptimizationExit* const exit = |
| 333 AddDeoptimizationExit(instr, frame_state_offset); |
| 334 Label continue_label; |
| 335 BranchInfo branch; |
| 336 branch.condition = condition; |
| 337 branch.true_label = exit->label(); |
| 338 branch.false_label = &continue_label; |
| 339 branch.fallthru = true; |
| 340 // Assemble architecture-specific branch. |
| 341 AssembleArchBranch(instr, &branch); |
| 342 masm()->bind(&continue_label); |
| 343 break; |
311 } | 344 } |
312 BranchInfo branch; | 345 case kFlags_set: { |
313 branch.condition = condition; | 346 // Assemble a boolean materialization after this instruction. |
314 branch.true_label = GetLabel(true_rpo); | 347 AssembleArchBoolean(instr, condition); |
315 branch.false_label = GetLabel(false_rpo); | 348 break; |
316 branch.fallthru = IsNextInAssemblyOrder(false_rpo); | 349 } |
317 // Assemble architecture-specific branch. | 350 case kFlags_none: { |
318 AssembleArchBranch(instr, &branch); | 351 break; |
319 } else if (mode == kFlags_set) { | 352 } |
320 // Assemble a boolean materialization after this instruction. | |
321 AssembleArchBoolean(instr, condition); | |
322 } | 353 } |
323 } | 354 } |
324 | 355 |
325 | 356 |
326 void CodeGenerator::AssembleSourcePosition(Instruction* instr) { | 357 void CodeGenerator::AssembleSourcePosition(Instruction* instr) { |
327 SourcePosition source_position; | 358 SourcePosition source_position; |
328 if (!code()->GetSourcePosition(instr, &source_position)) return; | 359 if (!code()->GetSourcePosition(instr, &source_position)) return; |
329 if (source_position == current_source_position_) return; | 360 if (source_position == current_source_position_) return; |
330 current_source_position_ = source_position; | 361 current_source_position_ = source_position; |
331 if (source_position.IsUnknown()) return; | 362 if (source_position.IsUnknown()) return; |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 } else { | 738 } else { |
708 CHECK(false); | 739 CHECK(false); |
709 } | 740 } |
710 } | 741 } |
711 | 742 |
712 | 743 |
713 void CodeGenerator::MarkLazyDeoptSite() { | 744 void CodeGenerator::MarkLazyDeoptSite() { |
714 last_lazy_deopt_pc_ = masm()->pc_offset(); | 745 last_lazy_deopt_pc_ = masm()->pc_offset(); |
715 } | 746 } |
716 | 747 |
| 748 DeoptimizationExit* CodeGenerator::AddDeoptimizationExit( |
| 749 Instruction* instr, size_t frame_state_offset) { |
| 750 int const deoptimization_id = BuildTranslation( |
| 751 instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); |
| 752 DeoptimizationExit* const exit = |
| 753 new (zone()) DeoptimizationExit(deoptimization_id); |
| 754 deoptimization_exits_.push_back(exit); |
| 755 return exit; |
| 756 } |
717 | 757 |
718 int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { | 758 int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { |
719 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 759 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
720 int spill_slots = frame()->GetSpillSlotCount(); | 760 int spill_slots = frame()->GetSpillSlotCount(); |
721 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; | 761 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
722 // Leave the PC on the stack on platforms that have that as part of their ABI | 762 // Leave the PC on the stack on platforms that have that as part of their ABI |
723 int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; | 763 int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; |
724 int sp_slot_delta = | 764 int sp_slot_delta = |
725 has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; | 765 has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; |
726 // Discard only slots that won't be used by new parameters. | 766 // Discard only slots that won't be used by new parameters. |
727 sp_slot_delta += stack_param_delta; | 767 sp_slot_delta += stack_param_delta; |
728 return sp_slot_delta; | 768 return sp_slot_delta; |
729 } | 769 } |
730 | 770 |
731 | 771 |
732 OutOfLineCode::OutOfLineCode(CodeGenerator* gen) | 772 OutOfLineCode::OutOfLineCode(CodeGenerator* gen) |
733 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { | 773 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { |
734 gen->ools_ = this; | 774 gen->ools_ = this; |
735 } | 775 } |
736 | 776 |
737 | 777 |
738 OutOfLineCode::~OutOfLineCode() {} | 778 OutOfLineCode::~OutOfLineCode() {} |
739 | 779 |
740 } // namespace compiler | 780 } // namespace compiler |
741 } // namespace internal | 781 } // namespace internal |
742 } // namespace v8 | 782 } // namespace v8 |
OLD | NEW |