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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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; |
58 } | 58 } |
59 if (code->ContainsCall()) { | |
60 frame->MarkNeedsFrame(); | |
61 } | |
62 } | 59 } |
63 | 60 |
64 | |
65 Handle<Code> CodeGenerator::GenerateCode() { | 61 Handle<Code> CodeGenerator::GenerateCode() { |
66 CompilationInfo* info = this->info(); | 62 CompilationInfo* info = this->info(); |
67 | 63 |
68 // Open a frame scope to indicate that there is a frame on the stack. The | 64 // Open a frame scope to indicate that there is a frame on the stack. The |
69 // MANUAL indicates that the scope shouldn't actually generate code to set up | 65 // MANUAL indicates that the scope shouldn't actually generate code to set up |
70 // the frame (that is done in AssemblePrologue). | 66 // the frame (that is done in AssemblePrologue). |
71 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 67 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
72 | 68 |
73 // Emit a code line info recording start event. | 69 // Emit a code line info recording start event. |
74 PositionsRecorder* recorder = masm()->positions_recorder(); | 70 PositionsRecorder* recorder = masm()->positions_recorder(); |
75 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); | 71 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); |
76 | 72 |
77 // Place function entry hook if requested to do so. | 73 // Place function entry hook if requested to do so. |
78 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { | 74 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { |
79 ProfileEntryHookStub::MaybeCallEntryHook(masm()); | 75 ProfileEntryHookStub::MaybeCallEntryHook(masm()); |
80 } | 76 } |
81 // Architecture-specific, linkage-specific prologue. | 77 // Architecture-specific, linkage-specific prologue. |
82 info->set_prologue_offset(masm()->pc_offset()); | 78 info->set_prologue_offset(masm()->pc_offset()); |
83 AssemblePrologue(); | |
84 if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) { | |
85 masm()->InitializeRootRegister(); | |
86 } | |
87 | 79 |
88 // Define deoptimization literals for all inlined functions. | 80 // Define deoptimization literals for all inlined functions. |
89 DCHECK_EQ(0u, deoptimization_literals_.size()); | 81 DCHECK_EQ(0u, deoptimization_literals_.size()); |
90 for (const CompilationInfo::InlinedFunctionHolder& inlined : | 82 for (const CompilationInfo::InlinedFunctionHolder& inlined : |
91 info->inlined_functions()) { | 83 info->inlined_functions()) { |
92 if (!inlined.shared_info.is_identical_to(info->shared_info())) { | 84 if (!inlined.shared_info.is_identical_to(info->shared_info())) { |
93 DefineDeoptimizationLiteral(inlined.shared_info); | 85 DefineDeoptimizationLiteral(inlined.shared_info); |
94 } | 86 } |
95 } | 87 } |
96 inlined_function_count_ = deoptimization_literals_.size(); | 88 inlined_function_count_ = deoptimization_literals_.size(); |
97 | 89 |
98 // Define deoptimization literals for all unoptimized code objects of inlined | 90 // Define deoptimization literals for all unoptimized code objects of inlined |
99 // functions. This ensures unoptimized code is kept alive by optimized code. | 91 // functions. This ensures unoptimized code is kept alive by optimized code. |
100 for (const CompilationInfo::InlinedFunctionHolder& inlined : | 92 for (const CompilationInfo::InlinedFunctionHolder& inlined : |
101 info->inlined_functions()) { | 93 info->inlined_functions()) { |
102 if (!inlined.shared_info.is_identical_to(info->shared_info())) { | 94 if (!inlined.shared_info.is_identical_to(info->shared_info())) { |
103 DefineDeoptimizationLiteral(inlined.inlined_code_object_root); | 95 DefineDeoptimizationLiteral(inlined.inlined_code_object_root); |
104 } | 96 } |
105 } | 97 } |
106 | 98 // Finish the Frame |
99 frame()->AlignFrame(kFrameAlignmentInBytes); | |
100 AssembleSetupStackPointer(); | |
107 // Assemble all non-deferred blocks, followed by deferred ones. | 101 // Assemble all non-deferred blocks, followed by deferred ones. |
108 for (int deferred = 0; deferred < 2; ++deferred) { | 102 for (int deferred = 0; deferred < 2; ++deferred) { |
109 for (const InstructionBlock* block : code()->instruction_blocks()) { | 103 for (const InstructionBlock* block : code()->instruction_blocks()) { |
110 if (block->IsDeferred() == (deferred == 0)) { | 104 if (block->IsDeferred() == (deferred == 0)) { |
111 continue; | 105 continue; |
112 } | 106 } |
113 // Align loop headers on 16-byte boundaries. | 107 // Align loop headers on 16-byte boundaries. |
114 if (block->IsLoopHeader()) masm()->Align(16); | 108 if (block->IsLoopHeader()) masm()->Align(16); |
115 // Ensure lazy deopt doesn't patch handler entry points. | 109 // Ensure lazy deopt doesn't patch handler entry points. |
116 if (block->IsHandler()) EnsureSpaceForLazyDeopt(); | 110 if (block->IsHandler()) EnsureSpaceForLazyDeopt(); |
(...skipping 19 matching lines...) Expand all Loading... | |
136 buffer = buffer.SubVector(next, buffer.length()); | 130 buffer = buffer.SubVector(next, buffer.length()); |
137 } | 131 } |
138 if (block->loop_header().IsValid()) { | 132 if (block->loop_header().IsValid()) { |
139 next = | 133 next = |
140 SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt()); | 134 SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt()); |
141 buffer = buffer.SubVector(next, buffer.length()); | 135 buffer = buffer.SubVector(next, buffer.length()); |
142 } | 136 } |
143 SNPrintF(buffer, " --"); | 137 SNPrintF(buffer, " --"); |
144 masm()->RecordComment(buffer_start); | 138 masm()->RecordComment(buffer_start); |
145 } | 139 } |
140 | |
141 frame_access_state()->MarkHasFrame(block->needs_frame()); | |
142 | |
146 masm()->bind(GetLabel(current_block_)); | 143 masm()->bind(GetLabel(current_block_)); |
144 if (block->must_construct_frame()) { | |
145 AssemblePrologue(); | |
146 // TODO(mtrofin): investigate why moving this back to function | |
147 // prologue upsets the ARM simulator. | |
148 if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) { | |
149 masm()->InitializeRootRegister(); | |
danno
2016/03/29 15:04:28
I'd really like to know why this doesn't work when
| |
150 } | |
151 } | |
152 | |
147 for (int i = block->code_start(); i < block->code_end(); ++i) { | 153 for (int i = block->code_start(); i < block->code_end(); ++i) { |
148 AssembleInstruction(code()->InstructionAt(i)); | 154 Instruction* instr = code()->InstructionAt(i); |
155 AssembleGaps(instr); | |
156 if (block->must_deconstruct_frame() && | |
danno
2016/03/29 15:04:28
Can you add a predicate to block called MustDecons
Mircea Trofin
2016/03/30 04:13:27
I think the main problem here is this !instr->IsRe
| |
157 i == block->last_instruction_index() && !instr->IsRet()) { | |
158 DCHECK(instr->IsJump()); | |
159 AssembleDeconstructFrame(); | |
160 } | |
161 AssembleInstruction(instr); | |
149 } | 162 } |
150 } | 163 } |
151 } | 164 } |
152 | 165 |
153 // Assemble all out-of-line code. | 166 // Assemble all out-of-line code. |
154 if (ools_) { | 167 if (ools_) { |
155 masm()->RecordComment("-- Out of line code --"); | 168 masm()->RecordComment("-- Out of line code --"); |
156 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { | 169 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { |
157 masm()->bind(ool->entry()); | 170 masm()->bind(ool->entry()); |
158 ool->Generate(); | 171 ool->Generate(); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 RootIndexMap map(isolate()); | 296 RootIndexMap map(isolate()); |
284 int root_index = map.Lookup(*object); | 297 int root_index = map.Lookup(*object); |
285 if (root_index != RootIndexMap::kInvalidRootIndex) { | 298 if (root_index != RootIndexMap::kInvalidRootIndex) { |
286 *index_return = static_cast<Heap::RootListIndex>(root_index); | 299 *index_return = static_cast<Heap::RootListIndex>(root_index); |
287 return true; | 300 return true; |
288 } | 301 } |
289 } | 302 } |
290 return false; | 303 return false; |
291 } | 304 } |
292 | 305 |
293 | |
294 void CodeGenerator::AssembleInstruction(Instruction* instr) { | 306 void CodeGenerator::AssembleInstruction(Instruction* instr) { |
295 AssembleGaps(instr); | |
296 AssembleSourcePosition(instr); | 307 AssembleSourcePosition(instr); |
297 // Assemble architecture-specific code for the instruction. | 308 // Assemble architecture-specific code for the instruction. |
298 AssembleArchInstruction(instr); | 309 AssembleArchInstruction(instr); |
299 | 310 |
300 FlagsMode mode = FlagsModeField::decode(instr->opcode()); | 311 FlagsMode mode = FlagsModeField::decode(instr->opcode()); |
301 FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); | 312 FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); |
302 switch (mode) { | 313 switch (mode) { |
303 case kFlags_branch: { | 314 case kFlags_branch: { |
304 // Assemble a branch after this instruction. | 315 // Assemble a branch after this instruction. |
305 InstructionOperandConverter i(this, instr); | 316 InstructionOperandConverter i(this, instr); |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 Instruction* instr, size_t frame_state_offset) { | 765 Instruction* instr, size_t frame_state_offset) { |
755 int const deoptimization_id = BuildTranslation( | 766 int const deoptimization_id = BuildTranslation( |
756 instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); | 767 instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); |
757 DeoptimizationExit* const exit = | 768 DeoptimizationExit* const exit = |
758 new (zone()) DeoptimizationExit(deoptimization_id); | 769 new (zone()) DeoptimizationExit(deoptimization_id); |
759 deoptimization_exits_.push_back(exit); | 770 deoptimization_exits_.push_back(exit); |
760 return exit; | 771 return exit; |
761 } | 772 } |
762 | 773 |
763 int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { | 774 int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { |
764 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | |
765 int spill_slots = frame()->GetSpillSlotCount(); | |
766 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; | |
767 // Leave the PC on the stack on platforms that have that as part of their ABI | 775 // Leave the PC on the stack on platforms that have that as part of their ABI |
768 int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; | 776 int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0; |
769 int sp_slot_delta = | 777 int sp_slot_delta = frame_access_state()->has_frame() |
770 has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; | 778 ? (frame()->GetTotalFrameSlotCount() - pc_slots) |
779 : 0; | |
771 // Discard only slots that won't be used by new parameters. | 780 // Discard only slots that won't be used by new parameters. |
772 sp_slot_delta += stack_param_delta; | 781 sp_slot_delta += stack_param_delta; |
773 return sp_slot_delta; | 782 return sp_slot_delta; |
774 } | 783 } |
775 | 784 |
776 | |
777 OutOfLineCode::OutOfLineCode(CodeGenerator* gen) | 785 OutOfLineCode::OutOfLineCode(CodeGenerator* gen) |
778 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { | 786 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { |
779 gen->ools_ = this; | 787 gen->ools_ = this; |
780 } | 788 } |
781 | 789 |
782 | 790 |
783 OutOfLineCode::~OutOfLineCode() {} | 791 OutOfLineCode::~OutOfLineCode() {} |
784 | 792 |
785 } // namespace compiler | 793 } // namespace compiler |
786 } // namespace internal | 794 } // namespace internal |
787 } // namespace v8 | 795 } // namespace v8 |
OLD | NEW |