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

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 804463002: Stack-allocate block variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: moar progress Created 6 years 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/hydrogen.cc ('k') | src/scopes.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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 FrameScope frame_scope(masm_, StackFrame::MANUAL); 137 FrameScope frame_scope(masm_, StackFrame::MANUAL);
138 138
139 info->set_prologue_offset(masm_->pc_offset()); 139 info->set_prologue_offset(masm_->pc_offset());
140 __ Prologue(info->IsCodePreAgingActive()); 140 __ Prologue(info->IsCodePreAgingActive());
141 info->AddNoFrameRange(0, masm_->pc_offset()); 141 info->AddNoFrameRange(0, masm_->pc_offset());
142 142
143 { Comment cmnt(masm_, "[ Allocate locals"); 143 { Comment cmnt(masm_, "[ Allocate locals");
144 int locals_count = info->scope()->num_stack_slots(); 144 int locals_count = info->scope()->num_stack_slots();
145 // Generators allocate locals, if any, in context slots. 145 // Generators allocate locals, if any, in context slots.
146 DCHECK(!info->function()->is_generator() || locals_count == 0); 146 DCHECK(!info->function()->is_generator() || locals_count == 0);
147 if (locals_count == 1) { 147 AllocateLocals(locals_count);
148 __ push(Immediate(isolate()->factory()->undefined_value()));
149 } else if (locals_count > 1) {
150 if (locals_count >= 128) {
151 Label ok;
152 __ mov(ecx, esp);
153 __ sub(ecx, Immediate(locals_count * kPointerSize));
154 ExternalReference stack_limit =
155 ExternalReference::address_of_real_stack_limit(isolate());
156 __ cmp(ecx, Operand::StaticVariable(stack_limit));
157 __ j(above_equal, &ok, Label::kNear);
158 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
159 __ bind(&ok);
160 }
161 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
162 const int kMaxPushes = 32;
163 if (locals_count >= kMaxPushes) {
164 int loop_iterations = locals_count / kMaxPushes;
165 __ mov(ecx, loop_iterations);
166 Label loop_header;
167 __ bind(&loop_header);
168 // Do pushes.
169 for (int i = 0; i < kMaxPushes; i++) {
170 __ push(eax);
171 }
172 __ dec(ecx);
173 __ j(not_zero, &loop_header, Label::kNear);
174 }
175 int remaining = locals_count % kMaxPushes;
176 // Emit the remaining pushes.
177 for (int i = 0; i < remaining; i++) {
178 __ push(eax);
179 }
180 }
181 } 148 }
182 149
183 bool function_in_register = true; 150 bool function_in_register = true;
184 151
185 // Possibly allocate a local context. 152 // Possibly allocate a local context.
186 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 153 int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
187 if (heap_slots > 0) { 154 if (heap_slots > 0) {
188 Comment cmnt(masm_, "[ Allocate context"); 155 Comment cmnt(masm_, "[ Allocate context");
189 bool need_write_barrier = true; 156 bool need_write_barrier = true;
190 // Argument to NewContext is the function, which is still in edi. 157 // Argument to NewContext is the function, which is still in edi.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 282
316 // Always emit a 'return undefined' in case control fell off the end of 283 // Always emit a 'return undefined' in case control fell off the end of
317 // the body. 284 // the body.
318 { Comment cmnt(masm_, "[ return <undefined>;"); 285 { Comment cmnt(masm_, "[ return <undefined>;");
319 __ mov(eax, isolate()->factory()->undefined_value()); 286 __ mov(eax, isolate()->factory()->undefined_value());
320 EmitReturnSequence(); 287 EmitReturnSequence();
321 } 288 }
322 } 289 }
323 290
324 291
292 void FullCodeGenerator::AllocateLocals(int locals_count) {
293 if (locals_count == 1) {
294 __ push(Immediate(isolate()->factory()->undefined_value()));
295 } else if (locals_count > 1) {
296 if (locals_count >= 128) {
297 Label ok;
298 __ mov(ecx, esp);
299 __ sub(ecx, Immediate(locals_count * kPointerSize));
300 ExternalReference stack_limit =
301 ExternalReference::address_of_real_stack_limit(isolate());
302 __ cmp(ecx, Operand::StaticVariable(stack_limit));
303 __ j(above_equal, &ok, Label::kNear);
304 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
305 __ bind(&ok);
306 }
307 __ mov(eax, Immediate(isolate()->factory()->undefined_value()));
308 const int kMaxPushes = 32;
309 if (locals_count >= kMaxPushes) {
310 int loop_iterations = locals_count / kMaxPushes;
311 __ mov(ecx, loop_iterations);
312 Label loop_header;
313 __ bind(&loop_header);
314 // Do pushes.
315 for (int i = 0; i < kMaxPushes; i++) {
316 __ push(eax);
317 }
318 __ dec(ecx);
319 __ j(not_zero, &loop_header, Label::kNear);
320 }
321 int remaining = locals_count % kMaxPushes;
322 // Emit the remaining pushes.
323 for (int i = 0; i < remaining; i++) {
324 __ push(eax);
325 }
326 }
327 }
328
329
330 void FullCodeGenerator::DeallocateLocals(int local_count) {
331 if (local_count > 0) {
332 __ add(esp, Immediate(local_count * kPointerSize));
333 }
334 }
335
336
325 void FullCodeGenerator::ClearAccumulator() { 337 void FullCodeGenerator::ClearAccumulator() {
326 __ Move(eax, Immediate(Smi::FromInt(0))); 338 __ Move(eax, Immediate(Smi::FromInt(0)));
327 } 339 }
328 340
329 341
330 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 342 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
331 __ mov(ebx, Immediate(profiling_counter_)); 343 __ mov(ebx, Immediate(profiling_counter_));
332 __ sub(FieldOperand(ebx, Cell::kValueOffset), 344 __ sub(FieldOperand(ebx, Cell::kValueOffset),
333 Immediate(Smi::FromInt(delta))); 345 Immediate(Smi::FromInt(delta)));
334 } 346 }
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 __ j(cc, if_true); 670 __ j(cc, if_true);
659 __ jmp(if_false); 671 __ jmp(if_false);
660 } 672 }
661 } 673 }
662 674
663 675
664 MemOperand FullCodeGenerator::StackOperand(Variable* var) { 676 MemOperand FullCodeGenerator::StackOperand(Variable* var) {
665 DCHECK(var->IsStackAllocated()); 677 DCHECK(var->IsStackAllocated());
666 // Offset is negative because higher indexes are at lower addresses. 678 // Offset is negative because higher indexes are at lower addresses.
667 int offset = -var->index() * kPointerSize; 679 int offset = -var->index() * kPointerSize;
680 Scope* var_scope = var->scope();
681 while (!var_scope->is_function_scope() && !var_scope->is_script_scope()) {
682 var_scope = var_scope->outer_scope();
683 offset -= var_scope->num_stack_slots() * kPointerSize;
684 }
668 // Adjust by a (parameter or local) base offset. 685 // Adjust by a (parameter or local) base offset.
669 if (var->IsParameter()) { 686 if (var->IsParameter()) {
670 offset += (info_->scope()->num_parameters() + 1) * kPointerSize; 687 offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
671 } else { 688 } else {
672 offset += JavaScriptFrameConstants::kLocal0Offset; 689 offset += JavaScriptFrameConstants::kLocal0Offset;
673 } 690 }
674 return Operand(ebp, offset); 691 return Operand(ebp, offset);
675 } 692 }
676 693
677 694
(...skipping 4498 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 5193 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
5177 Assembler::target_address_at(call_target_address, 5194 Assembler::target_address_at(call_target_address,
5178 unoptimized_code)); 5195 unoptimized_code));
5179 return OSR_AFTER_STACK_CHECK; 5196 return OSR_AFTER_STACK_CHECK;
5180 } 5197 }
5181 5198
5182 5199
5183 } } // namespace v8::internal 5200 } } // namespace v8::internal
5184 5201
5185 #endif // V8_TARGET_ARCH_IA32 5202 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698