Revision: 20692
Author:   [email protected]
Date:     Fri Apr 11 13:39:19 2014 UTC
Log:      Check stack limit in ArgumentAdaptorTrampoline.
BUG=353058
LOG=N
TEST=mjsunit/regress/regress-353058
[email protected]

Review URL: https://codereview.chromium.org/215853005
http://code.google.com/p/v8/source/detail?r=20692

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-353058.js
Modified:
 /branches/bleeding_edge/src/arm/builtins-arm.cc
 /branches/bleeding_edge/src/arm64/builtins-arm64.cc
 /branches/bleeding_edge/src/builtins.h
 /branches/bleeding_edge/src/ia32/builtins-ia32.cc
 /branches/bleeding_edge/src/mips/builtins-mips.cc
 /branches/bleeding_edge/src/runtime.js
 /branches/bleeding_edge/src/x64/builtins-x64.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-353058.js Fri Apr 11 13:39:19 2014 UTC
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --stack-size=150
+// Requries ASAN.
+
+function runNearStackLimit(f) { function t() { try { t(); } catch(e) { f(); } }; try { t(); } catch(e) {} }
+function __f_0(
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
+  x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
+) { }
+runNearStackLimit(__f_0);
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Fri Apr 4 16:18:59 2014 UTC +++ /branches/bleeding_edge/src/arm/builtins-arm.cc Fri Apr 11 13:39:19 2014 UTC
@@ -1284,7 +1284,7 @@
     // Out of stack space.
     __ ldr(r1, MemOperand(fp, kFunctionOffset));
     __ Push(r1, r0);
-    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     // End of stack check.

     // Push current limit and index.
@@ -1405,6 +1405,26 @@
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Jump(lr);
 }
+
+
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+                                      Label* stack_overflow) {
+  // ----------- S t a t e -------------
+  //  -- r0 : actual number of arguments
+  //  -- r1 : function (passed through to callee)
+  //  -- r2 : expected number of arguments
+  // -----------------------------------
+  // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+  // limit" is checked.
+  __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
+  // Make r5 the space we have left. The stack might already be overflowed
+  // here which will cause r5 to become negative.
+  __ sub(r5, sp, r5);
+  // Check if the arguments will overflow the stack.
+  __ cmp(r5, Operand(r2, LSL, kPointerSizeLog2));
+  __ b(le, stack_overflow);  // Signed comparison.
+}


 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
@@ -1446,6 +1466,8 @@
   //  -- r2 : expected number of arguments
   // -----------------------------------

+  Label stack_overflow;
+  ArgumentAdaptorStackCheck(masm, &stack_overflow);
   Label invoke, dont_adapt_arguments;

   Label enough, too_few;
@@ -1545,6 +1567,11 @@
   // -------------------------------------------
   __ bind(&dont_adapt_arguments);
   __ Jump(r3);
+
+  __ bind(&stack_overflow);
+  EnterArgumentsAdaptorFrame(masm);
+  __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
+  __ bkpt(0);
 }


=======================================
--- /branches/bleeding_edge/src/arm64/builtins-arm64.cc Fri Apr 4 16:18:59 2014 UTC +++ /branches/bleeding_edge/src/arm64/builtins-arm64.cc Fri Apr 11 13:39:19 2014 UTC
@@ -1280,7 +1280,7 @@
// There is not enough stack space, so use a builtin to throw an appropriate
     // error.
     __ Push(function, argc);
-    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     // We should never return from the APPLY_OVERFLOW builtin.
     if (__ emit_debug_code()) {
       __ Unreachable();
@@ -1398,6 +1398,28 @@
   __ Drop(3);
   __ Ret();
 }
+
+
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+                                      Label* stack_overflow) {
+  // ----------- S t a t e -------------
+  //  -- x0 : actual number of arguments
+  //  -- x1 : function (passed through to callee)
+  //  -- x2 : expected number of arguments
+  // -----------------------------------
+  // Check the stack for overflow.
+  // We are not trying to catch interruptions (e.g. debug break and
+  // preemption) here, so the "real stack limit" is checked.
+  Label enough_stack_space;
+  __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
+  // Make x10 the space we have left. The stack might already be overflowed
+  // here which will cause x10 to become negative.
+  __ Sub(x10, jssp, x10);
+  __ Mov(x11, jssp);
+  // Check if the arguments will overflow the stack.
+  __ Cmp(x10, Operand(x2, LSL, kPointerSizeLog2));
+  __ B(le, stack_overflow);
+}


 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
@@ -1433,6 +1455,9 @@
   //  -- x2 : expected number of arguments
   // -----------------------------------

+  Label stack_overflow;
+  ArgumentAdaptorStackCheck(masm, &stack_overflow);
+
   Register argc_actual = x0;  // Excluding the receiver.
   Register argc_expected = x2;  // Excluding the receiver.
   Register function = x1;
@@ -1552,6 +1577,11 @@
   // Call the entry point without adapting the arguments.
   __ Bind(&dont_adapt_arguments);
   __ Jump(code_entry);
+
+  __ Bind(&stack_overflow);
+  EnterArgumentsAdaptorFrame(masm);
+  __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
+  __ Brk(0);
 }


=======================================
--- /branches/bleeding_edge/src/builtins.h      Fri Apr  4 16:18:59 2014 UTC
+++ /branches/bleeding_edge/src/builtins.h      Fri Apr 11 13:39:19 2014 UTC
@@ -260,7 +260,7 @@
   V(STRING_ADD_LEFT, 1)                  \
   V(STRING_ADD_RIGHT, 1)                 \
   V(APPLY_PREPARE, 1)                    \
-  V(APPLY_OVERFLOW, 1)
+  V(STACK_OVERFLOW, 1)

 class BuiltinFunctionTable;
 class ObjectVisitor;
=======================================
--- /branches/bleeding_edge/src/ia32/builtins-ia32.cc Fri Apr 4 16:18:59 2014 UTC +++ /branches/bleeding_edge/src/ia32/builtins-ia32.cc Fri Apr 11 13:39:19 2014 UTC
@@ -949,7 +949,7 @@
     // Out of stack space.
     __ push(Operand(ebp, 4 * kPointerSize));  // push this
     __ push(eax);
-    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     __ bind(&okay);
     // End of stack check.

@@ -1250,6 +1250,33 @@
   }
   __ ret(0);
 }
+
+
+static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
+                                       Label* stack_overflow) {
+  // ----------- S t a t e -------------
+  //  -- eax : actual number of arguments
+  //  -- ebx : expected number of arguments
+  //  -- edi : function (passed through to callee)
+  // -----------------------------------
+  // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+  // limit" is checked.
+  ExternalReference real_stack_limit =
+      ExternalReference::address_of_real_stack_limit(masm->isolate());
+  __ mov(edx, Operand::StaticVariable(real_stack_limit));
+  // Make ecx the space we have left. The stack might already be overflowed
+  // here which will cause ecx to become negative.
+  __ mov(ecx, esp);
+  __ sub(ecx, edx);
+  // Make edx the space we need for the array when it is unrolled onto the
+  // stack.
+  __ mov(edx, ebx);
+  __ shl(edx, kPointerSizeLog2);
+  // Check if the arguments will overflow the stack.
+  __ cmp(ecx, edx);
+  __ j(less_equal, stack_overflow);  // Signed comparison.
+}


 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
@@ -1296,6 +1323,9 @@
   Label invoke, dont_adapt_arguments;
__ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);

+  Label stack_overflow;
+  ArgumentsAdaptorStackCheck(masm, &stack_overflow);
+
   Label enough, too_few;
   __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
   __ cmp(eax, ebx);
@@ -1370,6 +1400,11 @@
   // -------------------------------------------
   __ bind(&dont_adapt_arguments);
   __ jmp(edx);
+
+  __ bind(&stack_overflow);
+  EnterArgumentsAdaptorFrame(masm);
+  __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
+  __ int3();
 }


=======================================
--- /branches/bleeding_edge/src/mips/builtins-mips.cc Wed Mar 26 15:51:48 2014 UTC +++ /branches/bleeding_edge/src/mips/builtins-mips.cc Fri Apr 11 13:39:19 2014 UTC
@@ -1305,7 +1305,7 @@
     // Out of stack space.
     __ lw(a1, MemOperand(fp, kFunctionOffset));
     __ Push(a1, v0);
-    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     // End of stack check.

     // Push current limit and index.
=======================================
--- /branches/bleeding_edge/src/runtime.js      Wed Feb 19 14:19:42 2014 UTC
+++ /branches/bleeding_edge/src/runtime.js      Fri Apr 11 13:39:19 2014 UTC
@@ -464,7 +464,7 @@
 }


-function APPLY_OVERFLOW(length) {
+function STACK_OVERFLOW(length) {
   throw %MakeRangeError('stack_overflow', []);
 }

=======================================
--- /branches/bleeding_edge/src/x64/builtins-x64.cc Thu Apr 10 02:11:43 2014 UTC +++ /branches/bleeding_edge/src/x64/builtins-x64.cc Fri Apr 11 13:39:19 2014 UTC
@@ -1017,7 +1017,7 @@
     // Out of stack space.
     __ Push(Operand(rbp, kFunctionOffset));
     __ Push(rax);
-    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     __ bind(&okay);
     // End of stack check.

@@ -1320,6 +1320,31 @@
   }
   __ ret(0);
 }
+
+
+static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
+                                       Label* stack_overflow) {
+  // ----------- S t a t e -------------
+  //  -- rax : actual number of arguments
+  //  -- rbx : expected number of arguments
+  //  -- rdi: function (passed through to callee)
+  // -----------------------------------
+  // Check the stack for overflow. We are not trying to catch
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
+  // limit" is checked.
+  Label okay;
+  __ LoadRoot(rdx, Heap::kRealStackLimitRootIndex);
+  __ movp(rcx, rsp);
+  // Make rcx the space we have left. The stack might already be overflowed
+  // here which will cause rcx to become negative.
+  __ subp(rcx, rdx);
+  // Make rdx the space we need for the array when it is unrolled onto the
+  // stack.
+  __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2);
+  // Check if the arguments will overflow the stack.
+  __ cmpp(rcx, rdx);
+  __ j(less_equal, stack_overflow);  // Signed comparison.
+}


 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
@@ -1367,6 +1392,9 @@
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->arguments_adaptors(), 1);

+  Label stack_overflow;
+  ArgumentsAdaptorStackCheck(masm, &stack_overflow);
+
   Label enough, too_few;
   __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
   __ cmpp(rax, rbx);
@@ -1439,6 +1467,11 @@
   // -------------------------------------------
   __ bind(&dont_adapt_arguments);
   __ jmp(rdx);
+
+  __ bind(&stack_overflow);
+  EnterArgumentsAdaptorFrame(masm);
+  __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
+  __ int3();
 }


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to