Index: src/ia32/builtins-ia32.cc |
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc |
index efa3456d8e0698de66e0e5d58eddd3452ca2d62e..531d1779bf1c213f3167aed13e7a36701c65f98f 100644 |
--- a/src/ia32/builtins-ia32.cc |
+++ b/src/ia32/builtins-ia32.cc |
@@ -1663,12 +1663,34 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
// stack guard check to enable interrupts. |
Erik Corry
2012/02/10 13:01:42
This should read "to trigger any pending interrupt
Jakob Kummerow
2012/02/10 13:59:20
Done.
|
__ bind(&stack_check); |
Label ok; |
- ExternalReference stack_limit = |
- ExternalReference::address_of_stack_limit(masm->isolate()); |
- __ cmp(esp, Operand::StaticVariable(stack_limit)); |
- __ j(above_equal, &ok, Label::kNear); |
- StackCheckStub stub; |
- __ TailCallStub(&stub); |
+ if (FLAG_count_based_interrupts) { |
Erik Corry
2012/02/10 13:01:42
Don't think we need this complexity.
Jakob Kummerow
2012/02/10 13:59:20
Done.
|
+ // Fetch the function's profiling counter cell from the code surrounding |
+ // the call site. |
+ __ mov(ebx, Operand(esp, 0)); // return address |
+ // These offsets are only correct if the 'weight' immediate in the |
+ // 'sub' instruction fits into a single byte. |
+ static const int kCellOffset = -12; |
+ static const int kWeightOffset = -8; |
+ if (FLAG_debug_code) { |
+ static const uint8_t kSubImm8Byte = 0x83; // "sub ..., <imm8>" |
+ __ cmpb(Operand(ebx, kCellOffset - 2), kSubImm8Byte); |
+ __ Assert(equal, "sub <imm8> instruction not found before cell offset"); |
+ STATIC_ASSERT(kCellOffset - 2 == kWeightOffset - 6); |
+ } |
+ __ movsx_b(ecx, Operand(ebx, kWeightOffset)); |
+ __ mov(ebx, Operand(ebx, kCellOffset)); |
+ __ sub(Operand(ebx, 0), ecx); |
+ __ j(positive, &ok, Label::kNear); |
+ InterruptStub stub; |
+ __ TailCallStub(&stub); |
+ } else { |
+ ExternalReference stack_limit = |
+ ExternalReference::address_of_stack_limit(masm->isolate()); |
+ __ cmp(esp, Operand::StaticVariable(stack_limit)); |
+ __ j(above_equal, &ok, Label::kNear); |
+ StackCheckStub stub; |
+ __ TailCallStub(&stub); |
+ } |
if (FLAG_debug_code) { |
__ Abort("Unreachable code: returned from tail call."); |
} |