Chromium Code Reviews| 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"); |