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..c105528296d4fb179d7e20c30fb01b5c65ab2e25 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -101,6 +101,18 @@ class JumpPatchSite BASE_EMBEDDED { |
}; |
+static void EmitStackCheck(MacroAssembler* masm_) { |
+ Label ok; |
+ Isolate* isolate = masm_->isolate(); |
+ 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); |
+} |
+ |
+ |
// 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 |
@@ -172,7 +184,29 @@ void FullCodeGenerator::Generate() { |
__ push(Immediate(isolate()->factory()->undefined_value())); |
} else if (locals_count > 1) { |
__ mov(eax, Immediate(isolate()->factory()->undefined_value())); |
- for (int i = 0; i < locals_count; i++) { |
+ const int kTriggerStackLimitCheckCount = 128; |
+ // Create a loop that pushes kTriggerStackLimitCheckCount undefines |
+ // and performs a stack check. |
+ if (locals_count >= kTriggerStackLimitCheckCount) { |
+ PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
dcarney
2014/03/21 09:43:28
no idea what this does, whether it's the right bai
Yang
2014/03/21 09:52:22
I don't think we need this. I don't expect optimiz
|
+ int loop_iterations = locals_count / kTriggerStackLimitCheckCount; |
+ __ mov(ecx, loop_iterations); |
+ Label loop_header; |
+ __ bind(&loop_header); |
+ // Do pushes. |
+ for (int i = 0; i < kTriggerStackLimitCheckCount; i++) { |
+ __ push(eax); |
+ } |
+ // Do stack check. |
+ EmitStackCheck(masm_); |
+ // Continue loop if not done. |
+ __ dec(ecx); |
+ __ cmp(ecx, Immediate(Smi::FromInt(0))); |
Yang
2014/03/21 09:52:22
No need for this cmp. dec also sets the flags. Jus
|
+ __ j(not_equal, &loop_header, Label::kNear); |
+ } |
+ int remaining = locals_count % kTriggerStackLimitCheckCount; |
+ // Emit the remaining pushes. |
+ for (int i = 0; i < remaining; i++) { |
__ push(eax); |
} |
} |
@@ -285,13 +319,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"); |