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

Side by Side Diff: src/crankshaft/ia32/lithium-codegen-ia32.cc

Issue 1731273003: [crankshaft] [ia32] Remove dynamic frame alignment optimization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « src/crankshaft/ia32/lithium-codegen-ia32.h ('k') | src/crankshaft/ia32/lithium-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" 7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h"
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 bool LCodeGen::GenerateCode() { 50 bool LCodeGen::GenerateCode() {
51 LPhase phase("Z_Code generation", chunk()); 51 LPhase phase("Z_Code generation", chunk());
52 DCHECK(is_unused()); 52 DCHECK(is_unused());
53 status_ = GENERATING; 53 status_ = GENERATING;
54 54
55 // Open a frame scope to indicate that there is a frame on the stack. The 55 // Open a frame scope to indicate that there is a frame on the stack. The
56 // MANUAL indicates that the scope shouldn't actually generate code to set up 56 // MANUAL indicates that the scope shouldn't actually generate code to set up
57 // the frame (that is done in GeneratePrologue). 57 // the frame (that is done in GeneratePrologue).
58 FrameScope frame_scope(masm_, StackFrame::MANUAL); 58 FrameScope frame_scope(masm_, StackFrame::MANUAL);
59 59
60 support_aligned_spilled_doubles_ = info()->IsOptimizing();
61
62 dynamic_frame_alignment_ = info()->IsOptimizing() &&
63 ((chunk()->num_double_slots() > 2 &&
64 !chunk()->graph()->is_recursive()) ||
65 !info()->osr_ast_id().IsNone());
66
67 return GeneratePrologue() && 60 return GeneratePrologue() &&
68 GenerateBody() && 61 GenerateBody() &&
69 GenerateDeferredCode() && 62 GenerateDeferredCode() &&
70 GenerateJumpTable() && 63 GenerateJumpTable() &&
71 GenerateSafepointTable(); 64 GenerateSafepointTable();
72 } 65 }
73 66
74 67
75 void LCodeGen::FinishCode(Handle<Code> code) { 68 void LCodeGen::FinishCode(Handle<Code> code) {
76 DCHECK(is_done()); 69 DCHECK(is_done());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 count++; 116 count++;
124 } 117 }
125 } 118 }
126 119
127 120
128 bool LCodeGen::GeneratePrologue() { 121 bool LCodeGen::GeneratePrologue() {
129 DCHECK(is_generating()); 122 DCHECK(is_generating());
130 123
131 if (info()->IsOptimizing()) { 124 if (info()->IsOptimizing()) {
132 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 125 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
133
134 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
135 // Move state of dynamic frame alignment into edx.
136 __ Move(edx, Immediate(kNoAlignmentPadding));
137
138 Label do_not_pad, align_loop;
139 STATIC_ASSERT(kDoubleSize == 2 * kPointerSize);
140 // Align esp + 4 to a multiple of 2 * kPointerSize.
141 __ test(esp, Immediate(kPointerSize));
142 __ j(not_zero, &do_not_pad, Label::kNear);
143 __ push(Immediate(0));
144 __ mov(ebx, esp);
145 __ mov(edx, Immediate(kAlignmentPaddingPushed));
146 // Copy arguments, receiver, and return address.
147 __ mov(ecx, Immediate(scope()->num_parameters() + 2));
148
149 __ bind(&align_loop);
150 __ mov(eax, Operand(ebx, 1 * kPointerSize));
151 __ mov(Operand(ebx, 0), eax);
152 __ add(Operand(ebx), Immediate(kPointerSize));
153 __ dec(ecx);
154 __ j(not_zero, &align_loop, Label::kNear);
155 __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
156 __ bind(&do_not_pad);
157 }
158 } 126 }
159 127
160 info()->set_prologue_offset(masm_->pc_offset()); 128 info()->set_prologue_offset(masm_->pc_offset());
161 if (NeedsEagerFrame()) { 129 if (NeedsEagerFrame()) {
162 DCHECK(!frame_is_built_); 130 DCHECK(!frame_is_built_);
163 frame_is_built_ = true; 131 frame_is_built_ = true;
164 if (info()->IsStub()) { 132 if (info()->IsStub()) {
165 __ StubPrologue(); 133 __ StubPrologue();
166 } else { 134 } else {
167 __ Prologue(info()->GeneratePreagedPrologue()); 135 __ Prologue(info()->GeneratePreagedPrologue());
168 } 136 }
169 } 137 }
170 138
171 if (info()->IsOptimizing() &&
172 dynamic_frame_alignment_ &&
173 FLAG_debug_code) {
174 __ test(esp, Immediate(kPointerSize));
175 __ Assert(zero, kFrameIsExpectedToBeAligned);
176 }
177
178 // Reserve space for the stack slots needed by the code. 139 // Reserve space for the stack slots needed by the code.
179 int slots = GetStackSlotCount(); 140 int slots = GetStackSlotCount();
180 DCHECK(slots != 0 || !info()->IsOptimizing()); 141 DCHECK(slots != 0 || !info()->IsOptimizing());
181 if (slots > 0) { 142 if (slots > 0) {
182 if (slots == 1) { 143 __ sub(Operand(esp), Immediate(slots * kPointerSize));
183 if (dynamic_frame_alignment_) {
184 __ push(edx);
185 } else {
186 __ push(Immediate(kNoAlignmentPadding));
187 }
188 } else {
189 if (FLAG_debug_code) {
190 __ sub(Operand(esp), Immediate(slots * kPointerSize));
191 #ifdef _MSC_VER 144 #ifdef _MSC_VER
192 MakeSureStackPagesMapped(slots * kPointerSize); 145 MakeSureStackPagesMapped(slots * kPointerSize);
193 #endif 146 #endif
194 __ push(eax); 147 if (FLAG_debug_code) {
195 __ mov(Operand(eax), Immediate(slots)); 148 __ push(eax);
196 Label loop; 149 __ mov(Operand(eax), Immediate(slots));
197 __ bind(&loop); 150 Label loop;
198 __ mov(MemOperand(esp, eax, times_4, 0), 151 __ bind(&loop);
199 Immediate(kSlotsZapValue)); 152 __ mov(MemOperand(esp, eax, times_4, 0), Immediate(kSlotsZapValue));
200 __ dec(eax); 153 __ dec(eax);
201 __ j(not_zero, &loop); 154 __ j(not_zero, &loop);
202 __ pop(eax); 155 __ pop(eax);
203 } else {
204 __ sub(Operand(esp), Immediate(slots * kPointerSize));
205 #ifdef _MSC_VER
206 MakeSureStackPagesMapped(slots * kPointerSize);
207 #endif
208 }
209
210 if (support_aligned_spilled_doubles_) {
211 Comment(";;; Store dynamic frame alignment tag for spilled doubles");
212 // Store dynamic frame alignment state in the first local.
213 int offset = JavaScriptFrameConstants::kDynamicAlignmentStateOffset;
214 if (dynamic_frame_alignment_) {
215 __ mov(Operand(ebp, offset), edx);
216 } else {
217 __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding));
218 }
219 }
220 } 156 }
221 157
222 if (info()->saves_caller_doubles()) SaveCallerDoubles(); 158 if (info()->saves_caller_doubles()) SaveCallerDoubles();
223 } 159 }
224 return !is_aborted(); 160 return !is_aborted();
225 } 161 }
226 162
227 163
228 void LCodeGen::DoPrologue(LPrologue* instr) { 164 void LCodeGen::DoPrologue(LPrologue* instr) {
229 Comment(";;; Prologue begin"); 165 Comment(";;; Prologue begin");
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } 227 }
292 228
293 229
294 void LCodeGen::GenerateOsrPrologue() { 230 void LCodeGen::GenerateOsrPrologue() {
295 // Generate the OSR entry prologue at the first unknown OSR value, or if there 231 // Generate the OSR entry prologue at the first unknown OSR value, or if there
296 // are none, at the OSR entrypoint instruction. 232 // are none, at the OSR entrypoint instruction.
297 if (osr_pc_offset_ >= 0) return; 233 if (osr_pc_offset_ >= 0) return;
298 234
299 osr_pc_offset_ = masm()->pc_offset(); 235 osr_pc_offset_ = masm()->pc_offset();
300 236
301 // Move state of dynamic frame alignment into edx.
302 __ Move(edx, Immediate(kNoAlignmentPadding));
303
304 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
305 Label do_not_pad, align_loop;
306 // Align ebp + 4 to a multiple of 2 * kPointerSize.
307 __ test(ebp, Immediate(kPointerSize));
308 __ j(zero, &do_not_pad, Label::kNear);
309 __ push(Immediate(0));
310 __ mov(ebx, esp);
311 __ mov(edx, Immediate(kAlignmentPaddingPushed));
312
313 // Move all parts of the frame over one word. The frame consists of:
314 // unoptimized frame slots, alignment state, context, frame pointer, return
315 // address, receiver, and the arguments.
316 __ mov(ecx, Immediate(scope()->num_parameters() +
317 5 + graph()->osr()->UnoptimizedFrameSlots()));
318
319 __ bind(&align_loop);
320 __ mov(eax, Operand(ebx, 1 * kPointerSize));
321 __ mov(Operand(ebx, 0), eax);
322 __ add(Operand(ebx), Immediate(kPointerSize));
323 __ dec(ecx);
324 __ j(not_zero, &align_loop, Label::kNear);
325 __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
326 __ sub(Operand(ebp), Immediate(kPointerSize));
327 __ bind(&do_not_pad);
328 }
329
330 // Save the first local, which is overwritten by the alignment state.
331 Operand alignment_loc = MemOperand(ebp, -3 * kPointerSize);
332 __ push(alignment_loc);
333
334 // Set the dynamic frame alignment state.
335 __ mov(alignment_loc, edx);
336
337 // Adjust the frame size, subsuming the unoptimized frame into the 237 // Adjust the frame size, subsuming the unoptimized frame into the
338 // optimized frame. 238 // optimized frame.
339 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 239 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
340 DCHECK(slots >= 1); 240 DCHECK(slots >= 0);
341 __ sub(esp, Immediate((slots - 1) * kPointerSize)); 241 __ sub(esp, Immediate(slots * kPointerSize));
342 } 242 }
343 243
344 244
345 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { 245 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
346 if (instr->IsCall()) { 246 if (instr->IsCall()) {
347 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 247 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
348 } 248 }
349 if (!instr->IsLazyBailout() && !instr->IsGap()) { 249 if (!instr->IsLazyBailout() && !instr->IsGap()) {
350 safepoints_.BumpLastLazySafepointIndex(); 250 safepoints_.BumpLastLazySafepointIndex();
351 } 251 }
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2455 Label true_value, done; 2355 Label true_value, done;
2456 __ test(eax, Operand(eax)); 2356 __ test(eax, Operand(eax));
2457 __ j(condition, &true_value, Label::kNear); 2357 __ j(condition, &true_value, Label::kNear);
2458 __ mov(ToRegister(instr->result()), factory()->false_value()); 2358 __ mov(ToRegister(instr->result()), factory()->false_value());
2459 __ jmp(&done, Label::kNear); 2359 __ jmp(&done, Label::kNear);
2460 __ bind(&true_value); 2360 __ bind(&true_value);
2461 __ mov(ToRegister(instr->result()), factory()->true_value()); 2361 __ mov(ToRegister(instr->result()), factory()->true_value());
2462 __ bind(&done); 2362 __ bind(&done);
2463 } 2363 }
2464 2364
2465 2365 void LCodeGen::EmitReturn(LReturn* instr) {
2466 void LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) { 2366 int extra_value_count = 1;
2467 int extra_value_count = dynamic_frame_alignment ? 2 : 1;
2468 2367
2469 if (instr->has_constant_parameter_count()) { 2368 if (instr->has_constant_parameter_count()) {
2470 int parameter_count = ToInteger32(instr->constant_parameter_count()); 2369 int parameter_count = ToInteger32(instr->constant_parameter_count());
2471 if (dynamic_frame_alignment && FLAG_debug_code) {
2472 __ cmp(Operand(esp,
2473 (parameter_count + extra_value_count) * kPointerSize),
2474 Immediate(kAlignmentZapValue));
2475 __ Assert(equal, kExpectedAlignmentMarker);
2476 }
2477 __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx); 2370 __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
2478 } else { 2371 } else {
2479 DCHECK(info()->IsStub()); // Functions would need to drop one more value. 2372 DCHECK(info()->IsStub()); // Functions would need to drop one more value.
2480 Register reg = ToRegister(instr->parameter_count()); 2373 Register reg = ToRegister(instr->parameter_count());
2481 // The argument count parameter is a smi 2374 // The argument count parameter is a smi
2482 __ SmiUntag(reg); 2375 __ SmiUntag(reg);
2483 Register return_addr_reg = reg.is(ecx) ? ebx : ecx; 2376 Register return_addr_reg = reg.is(ecx) ? ebx : ecx;
2484 if (dynamic_frame_alignment && FLAG_debug_code) {
2485 DCHECK(extra_value_count == 2);
2486 __ cmp(Operand(esp, reg, times_pointer_size,
2487 extra_value_count * kPointerSize),
2488 Immediate(kAlignmentZapValue));
2489 __ Assert(equal, kExpectedAlignmentMarker);
2490 }
2491 2377
2492 // emit code to restore stack based on instr->parameter_count() 2378 // emit code to restore stack based on instr->parameter_count()
2493 __ pop(return_addr_reg); // save return address 2379 __ pop(return_addr_reg); // save return address
2494 if (dynamic_frame_alignment) {
2495 __ inc(reg); // 1 more for alignment
2496 }
2497
2498 __ shl(reg, kPointerSizeLog2); 2380 __ shl(reg, kPointerSizeLog2);
2499 __ add(esp, reg); 2381 __ add(esp, reg);
2500 __ jmp(return_addr_reg); 2382 __ jmp(return_addr_reg);
2501 } 2383 }
2502 } 2384 }
2503 2385
2504 2386
2505 void LCodeGen::DoReturn(LReturn* instr) { 2387 void LCodeGen::DoReturn(LReturn* instr) {
2506 if (FLAG_trace && info()->IsOptimizing()) { 2388 if (FLAG_trace && info()->IsOptimizing()) {
2507 // Preserve the return value on the stack and rely on the runtime call 2389 // Preserve the return value on the stack and rely on the runtime call
2508 // to return the value in the same register. We're leaving the code 2390 // to return the value in the same register. We're leaving the code
2509 // managed by the register allocator and tearing down the frame, it's 2391 // managed by the register allocator and tearing down the frame, it's
2510 // safe to write to the context register. 2392 // safe to write to the context register.
2511 __ push(eax); 2393 __ push(eax);
2512 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2394 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2513 __ CallRuntime(Runtime::kTraceExit); 2395 __ CallRuntime(Runtime::kTraceExit);
2514 } 2396 }
2515 if (info()->saves_caller_doubles()) RestoreCallerDoubles(); 2397 if (info()->saves_caller_doubles()) RestoreCallerDoubles();
2516 if (dynamic_frame_alignment_) {
2517 // Fetch the state of the dynamic frame alignment.
2518 __ mov(edx, Operand(ebp,
2519 JavaScriptFrameConstants::kDynamicAlignmentStateOffset));
2520 }
2521 if (NeedsEagerFrame()) { 2398 if (NeedsEagerFrame()) {
2522 __ mov(esp, ebp); 2399 __ mov(esp, ebp);
2523 __ pop(ebp); 2400 __ pop(ebp);
2524 } 2401 }
2525 if (dynamic_frame_alignment_) {
2526 Label no_padding;
2527 __ cmp(edx, Immediate(kNoAlignmentPadding));
2528 __ j(equal, &no_padding, Label::kNear);
2529 2402
2530 EmitReturn(instr, true); 2403 EmitReturn(instr);
2531 __ bind(&no_padding);
2532 }
2533
2534 EmitReturn(instr, false);
2535 } 2404 }
2536 2405
2537 2406
2538 template <class T> 2407 template <class T>
2539 void LCodeGen::EmitVectorLoadICRegisters(T* instr) { 2408 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
2540 Register vector_register = ToRegister(instr->temp_vector()); 2409 Register vector_register = ToRegister(instr->temp_vector());
2541 Register slot_register = LoadWithVectorDescriptor::SlotRegister(); 2410 Register slot_register = LoadWithVectorDescriptor::SlotRegister();
2542 DCHECK(vector_register.is(LoadWithVectorDescriptor::VectorRegister())); 2411 DCHECK(vector_register.is(LoadWithVectorDescriptor::VectorRegister()));
2543 DCHECK(slot_register.is(eax)); 2412 DCHECK(slot_register.is(eax));
2544 2413
(...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after
5356 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), context); 5225 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), context);
5357 } 5226 }
5358 5227
5359 5228
5360 #undef __ 5229 #undef __
5361 5230
5362 } // namespace internal 5231 } // namespace internal
5363 } // namespace v8 5232 } // namespace v8
5364 5233
5365 #endif // V8_TARGET_ARCH_IA32 5234 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/crankshaft/ia32/lithium-codegen-ia32.h ('k') | src/crankshaft/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698