Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: src/compiler/code-generator.cc

Issue 1775323002: [turbofan] Frame elision for code stubs (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: MOVED InitializeRootRegister call Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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()) { 79 if (linkage()->GetIncomingDescriptor()->InitializeRootRegister()) {
85 masm()->InitializeRootRegister(); 80 masm()->InitializeRootRegister();
86 } 81 }
87 82
88 // Define deoptimization literals for all inlined functions. 83 // Define deoptimization literals for all inlined functions.
89 DCHECK_EQ(0u, deoptimization_literals_.size()); 84 DCHECK_EQ(0u, deoptimization_literals_.size());
90 for (const CompilationInfo::InlinedFunctionHolder& inlined : 85 for (const CompilationInfo::InlinedFunctionHolder& inlined :
91 info->inlined_functions()) { 86 info->inlined_functions()) {
92 if (!inlined.shared_info.is_identical_to(info->shared_info())) { 87 if (!inlined.shared_info.is_identical_to(info->shared_info())) {
93 DefineDeoptimizationLiteral(inlined.shared_info); 88 DefineDeoptimizationLiteral(inlined.shared_info);
94 } 89 }
95 } 90 }
96 inlined_function_count_ = deoptimization_literals_.size(); 91 inlined_function_count_ = deoptimization_literals_.size();
97 92
98 // Define deoptimization literals for all unoptimized code objects of inlined 93 // Define deoptimization literals for all unoptimized code objects of inlined
99 // functions. This ensures unoptimized code is kept alive by optimized code. 94 // functions. This ensures unoptimized code is kept alive by optimized code.
100 for (const CompilationInfo::InlinedFunctionHolder& inlined : 95 for (const CompilationInfo::InlinedFunctionHolder& inlined :
101 info->inlined_functions()) { 96 info->inlined_functions()) {
102 if (!inlined.shared_info.is_identical_to(info->shared_info())) { 97 if (!inlined.shared_info.is_identical_to(info->shared_info())) {
103 DefineDeoptimizationLiteral(inlined.inlined_code_object_root); 98 DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
104 } 99 }
105 } 100 }
106 101
102 // Finish the Frame
103 frame()->AlignFrame(kFrameAlignmentInBytes);
104 AssembleSetupStackPointer();
107 // Assemble all non-deferred blocks, followed by deferred ones. 105 // Assemble all non-deferred blocks, followed by deferred ones.
108 for (int deferred = 0; deferred < 2; ++deferred) { 106 for (int deferred = 0; deferred < 2; ++deferred) {
109 for (const InstructionBlock* block : code()->instruction_blocks()) { 107 for (const InstructionBlock* block : code()->instruction_blocks()) {
110 if (block->IsDeferred() == (deferred == 0)) { 108 if (block->IsDeferred() == (deferred == 0)) {
111 continue; 109 continue;
112 } 110 }
113 // Align loop headers on 16-byte boundaries. 111 // Align loop headers on 16-byte boundaries.
114 if (block->IsLoopHeader()) masm()->Align(16); 112 if (block->IsLoopHeader()) masm()->Align(16);
115 // Ensure lazy deopt doesn't patch handler entry points. 113 // Ensure lazy deopt doesn't patch handler entry points.
116 if (block->IsHandler()) EnsureSpaceForLazyDeopt(); 114 if (block->IsHandler()) EnsureSpaceForLazyDeopt();
(...skipping 19 matching lines...) Expand all
136 buffer = buffer.SubVector(next, buffer.length()); 134 buffer = buffer.SubVector(next, buffer.length());
137 } 135 }
138 if (block->loop_header().IsValid()) { 136 if (block->loop_header().IsValid()) {
139 next = 137 next =
140 SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt()); 138 SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt());
141 buffer = buffer.SubVector(next, buffer.length()); 139 buffer = buffer.SubVector(next, buffer.length());
142 } 140 }
143 SNPrintF(buffer, " --"); 141 SNPrintF(buffer, " --");
144 masm()->RecordComment(buffer_start); 142 masm()->RecordComment(buffer_start);
145 } 143 }
144
145 frame_access_state()->MarkHasFrame(block->needs_frame());
146
146 masm()->bind(GetLabel(current_block_)); 147 masm()->bind(GetLabel(current_block_));
148 if (block->must_construct_frame()) {
149 AssemblePrologue();
Benedikt Meurer 2016/03/30 04:00:25 Maybe we should rename AssemblePrologue to Assembl
Mircea Trofin 2016/03/30 04:13:27 I want to do that, but together with separating fr
Benedikt Meurer 2016/03/30 04:34:08 Acknowledged.
150 }
151
147 for (int i = block->code_start(); i < block->code_end(); ++i) { 152 for (int i = block->code_start(); i < block->code_end(); ++i) {
148 AssembleInstruction(code()->InstructionAt(i)); 153 Instruction* instr = code()->InstructionAt(i);
Benedikt Meurer 2016/03/30 04:00:25 Please put all of this into AssembleInstruction be
Mircea Trofin 2016/03/30 04:13:27 We need the operands involved in the gap to be emi
Benedikt Meurer 2016/03/30 04:34:08 Sure, but that can all be done inside AssembleInst
Mircea Trofin 2016/03/30 05:58:20 Done.
154 AssembleGaps(instr);
155 if (block->must_deconstruct_frame() &&
Benedikt Meurer 2016/03/30 04:00:25 This condition looks unnecessarily complex. Isn't
Mircea Trofin 2016/03/30 04:13:27 That's true for ret, and I plan to address that se
Benedikt Meurer 2016/03/30 04:34:08 Acknowledged.
156 i == block->last_instruction_index() && !instr->IsRet()) {
157 DCHECK(instr->IsJump());
158 AssembleDeconstructFrame();
159 }
160 AssembleInstruction(instr);
149 } 161 }
150 } 162 }
151 } 163 }
152 164
153 // Assemble all out-of-line code. 165 // Assemble all out-of-line code.
154 if (ools_) { 166 if (ools_) {
155 masm()->RecordComment("-- Out of line code --"); 167 masm()->RecordComment("-- Out of line code --");
156 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) { 168 for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) {
157 masm()->bind(ool->entry()); 169 masm()->bind(ool->entry());
158 ool->Generate(); 170 ool->Generate();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 RootIndexMap map(isolate()); 295 RootIndexMap map(isolate());
284 int root_index = map.Lookup(*object); 296 int root_index = map.Lookup(*object);
285 if (root_index != RootIndexMap::kInvalidRootIndex) { 297 if (root_index != RootIndexMap::kInvalidRootIndex) {
286 *index_return = static_cast<Heap::RootListIndex>(root_index); 298 *index_return = static_cast<Heap::RootListIndex>(root_index);
287 return true; 299 return true;
288 } 300 }
289 } 301 }
290 return false; 302 return false;
291 } 303 }
292 304
293
294 void CodeGenerator::AssembleInstruction(Instruction* instr) { 305 void CodeGenerator::AssembleInstruction(Instruction* instr) {
295 AssembleGaps(instr);
296 AssembleSourcePosition(instr); 306 AssembleSourcePosition(instr);
297 // Assemble architecture-specific code for the instruction. 307 // Assemble architecture-specific code for the instruction.
298 AssembleArchInstruction(instr); 308 AssembleArchInstruction(instr);
299 309
300 FlagsMode mode = FlagsModeField::decode(instr->opcode()); 310 FlagsMode mode = FlagsModeField::decode(instr->opcode());
301 FlagsCondition condition = FlagsConditionField::decode(instr->opcode()); 311 FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
302 switch (mode) { 312 switch (mode) {
303 case kFlags_branch: { 313 case kFlags_branch: {
304 // Assemble a branch after this instruction. 314 // Assemble a branch after this instruction.
305 InstructionOperandConverter i(this, instr); 315 InstructionOperandConverter i(this, instr);
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 Instruction* instr, size_t frame_state_offset) { 764 Instruction* instr, size_t frame_state_offset) {
755 int const deoptimization_id = BuildTranslation( 765 int const deoptimization_id = BuildTranslation(
756 instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore()); 766 instr, -1, frame_state_offset, OutputFrameStateCombine::Ignore());
757 DeoptimizationExit* const exit = 767 DeoptimizationExit* const exit =
758 new (zone()) DeoptimizationExit(deoptimization_id); 768 new (zone()) DeoptimizationExit(deoptimization_id);
759 deoptimization_exits_.push_back(exit); 769 deoptimization_exits_.push_back(exit);
760 return exit; 770 return exit;
761 } 771 }
762 772
763 int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) { 773 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 774 // 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; 775 int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
769 int sp_slot_delta = 776 int sp_slot_delta = frame_access_state()->has_frame()
770 has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0; 777 ? (frame()->GetTotalFrameSlotCount() - pc_slots)
778 : 0;
771 // Discard only slots that won't be used by new parameters. 779 // Discard only slots that won't be used by new parameters.
772 sp_slot_delta += stack_param_delta; 780 sp_slot_delta += stack_param_delta;
773 return sp_slot_delta; 781 return sp_slot_delta;
774 } 782 }
775 783
776
777 OutOfLineCode::OutOfLineCode(CodeGenerator* gen) 784 OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
778 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { 785 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) {
779 gen->ools_ = this; 786 gen->ools_ = this;
780 } 787 }
781 788
782 789
783 OutOfLineCode::~OutOfLineCode() {} 790 OutOfLineCode::~OutOfLineCode() {}
784 791
785 } // namespace compiler 792 } // namespace compiler
786 } // namespace internal 793 } // namespace internal
787 } // namespace v8 794 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698