| Index: src/ia32/full-codegen-ia32.cc
|
| diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
|
| index 7bb4cffad0bb0bc30b6e99b867600fde694f9122..859b6af7745ddf82a2f663c57ba2c04abdf7afff 100644
|
| --- a/src/ia32/full-codegen-ia32.cc
|
| +++ b/src/ia32/full-codegen-ia32.cc
|
| @@ -119,6 +119,8 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
| scope_ = info->scope();
|
| handler_table_ =
|
| isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
|
| + profiling_counter_ = isolate()->factory()->NewJSGlobalPropertyCell(
|
| + Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget)));
|
| SetFunctionPosition(function());
|
| Comment cmnt(masm_, "[ function compiled by full code generator");
|
|
|
| @@ -323,15 +325,36 @@ void FullCodeGenerator::ClearAccumulator() {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
|
| +void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
|
| + Label* back_edge_target) {
|
| Comment cmnt(masm_, "[ Stack check");
|
| Label ok;
|
| - ExternalReference stack_limit =
|
| - ExternalReference::address_of_stack_limit(isolate());
|
| - __ cmp(esp, Operand::StaticVariable(stack_limit));
|
| - __ j(above_equal, &ok, Label::kNear);
|
| - StackCheckStub stub;
|
| - __ CallStub(&stub);
|
| +
|
| + if (FLAG_count_based_interrupts) {
|
| + __ mov(ebx, Immediate(profiling_counter_));
|
| + if (FLAG_weighted_back_edges) {
|
| + ASSERT(back_edge_target->is_bound());
|
| + int distance = masm_->pc_offset() - back_edge_target->pos();
|
| + __ sub(Operand::Cell(profiling_counter_),
|
| + // weight: ceil(distance/100).
|
| + // The immediate must be a single (signed) byte to satisfy
|
| + // assumptions made in Builtins::Generate_OnStackReplacement().
|
| + Immediate(Smi::FromInt(Min(127, (distance + 99) / 100))));
|
| + } else {
|
| + __ sub(Operand::Cell(profiling_counter_), Immediate(Smi::FromInt(1)));
|
| + }
|
| + __ j(positive, &ok, Label::kNear);
|
| + InterruptStub stub;
|
| + __ CallStub(&stub);
|
| + } else {
|
| + ExternalReference stack_limit =
|
| + ExternalReference::address_of_stack_limit(isolate());
|
| + __ cmp(esp, Operand::StaticVariable(stack_limit));
|
| + __ j(above_equal, &ok, Label::kNear);
|
| + StackCheckStub stub;
|
| + __ CallStub(&stub);
|
| + }
|
| +
|
| // Record a mapping of this PC offset to the OSR id. This is used to find
|
| // the AST id from the unoptimized code in order to use it as a key into
|
| // the deoptimization input data found in the optimized code.
|
| @@ -344,6 +367,12 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
|
| ASSERT(loop_depth() > 0);
|
| __ test(eax, Immediate(Min(loop_depth(), Code::kMaxLoopNestingMarker)));
|
|
|
| + if (FLAG_count_based_interrupts) {
|
| + // Reset the countdown.
|
| + __ mov(Operand::Cell(profiling_counter_),
|
| + Immediate(Smi::FromInt(FLAG_interrupt_budget)));
|
| + }
|
| +
|
| __ bind(&ok);
|
| PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
|
| // Record a mapping of the OSR id to this PC. This is used if the OSR
|
| @@ -1061,7 +1090,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
| __ bind(loop_statement.continue_label());
|
| __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1)));
|
|
|
| - EmitStackCheck(stmt);
|
| + EmitStackCheck(stmt, &loop);
|
| __ jmp(&loop);
|
|
|
| // Remove the pointers stored on the stack.
|
|
|