Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 16c32949146ff60ad01df880ee22ebda4a41cb6b..7764ecebc678dbb0f5ee571f94dcf577c174f1a0 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -101,6 +101,25 @@ class JumpPatchSite BASE_EMBEDDED { |
}; |
+static void EmitStackCheck(MacroAssembler* masm_, |
+ int pointers = 0, |
+ Register scratch = esp) { |
+ Label ok; |
+ Isolate* isolate = masm_->isolate(); |
+ ExternalReference stack_limit = |
+ ExternalReference::address_of_stack_limit(isolate); |
+ ASSERT(scratch.is(esp) == (pointers == 0)); |
+ if (pointers != 0) { |
+ __ mov(scratch, esp); |
+ __ sub(scratch, Immediate(pointers * kPointerSize)); |
+ } |
+ __ cmp(scratch, Operand::StaticVariable(stack_limit)); |
+ __ j(above_equal, &ok, Label::kNear); |
+ __ call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET); |
+ __ bind(&ok); |
+} |
+ |
+ |
// Generate code for a JS function. On entry to the function the receiver |
// and arguments have been pushed on the stack left to right, with the |
// return address on top of them. The actual argument count matches the |
@@ -171,8 +190,26 @@ void FullCodeGenerator::Generate() { |
if (locals_count == 1) { |
__ push(Immediate(isolate()->factory()->undefined_value())); |
} else if (locals_count > 1) { |
+ if (locals_count >= 128) { |
+ EmitStackCheck(masm_, locals_count, ecx); |
+ } |
__ mov(eax, Immediate(isolate()->factory()->undefined_value())); |
- for (int i = 0; i < locals_count; i++) { |
+ const int kMaxPushes = 32; |
+ if (locals_count >= kMaxPushes) { |
+ int loop_iterations = locals_count / kMaxPushes; |
+ __ mov(ecx, loop_iterations); |
+ Label loop_header; |
+ __ bind(&loop_header); |
+ // Do pushes. |
+ for (int i = 0; i < kMaxPushes; i++) { |
+ __ push(eax); |
+ } |
+ __ dec(ecx); |
+ __ j(not_zero, &loop_header, Label::kNear); |
+ } |
+ int remaining = locals_count % kMaxPushes; |
+ // Emit the remaining pushes. |
+ for (int i = 0; i < remaining; i++) { |
__ push(eax); |
} |
} |
@@ -285,13 +322,7 @@ void FullCodeGenerator::Generate() { |
{ Comment cmnt(masm_, "[ Stack check"); |
PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
- Label ok; |
- ExternalReference stack_limit = |
- ExternalReference::address_of_stack_limit(isolate()); |
- __ cmp(esp, Operand::StaticVariable(stack_limit)); |
- __ j(above_equal, &ok, Label::kNear); |
- __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); |
- __ bind(&ok); |
+ EmitStackCheck(masm_); |
} |
{ Comment cmnt(masm_, "[ Body"); |