Reviewers: danno, Michael Starzinger,
Message:
Danno, Michael, does this look good to you?
Feel free to suggest another reviewer if you know somebody who is more
familiar
with argument adaptors.
Description:
Check stack limit in ArgumentAdaptorTrampoline.
BUG=353058
LOG=N
TEST=mjsunit/regress/regress-353058
Please review this at https://codereview.chromium.org/215853005/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+90, -1 lines):
M src/arm/builtins-arm.cc
M src/builtins.h
M src/ia32/builtins-ia32.cc
M src/runtime.js
A test/mjsunit/regress/regress-353058.js
Index: src/arm/builtins-arm.cc
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index
f138146417410c185ddeb44d72d001fc25a5a4fa..b11b49bcec84a79a0fe115f27d3ad395c2e142a9
100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -1407,6 +1407,22 @@ void
Builtins::Generate_FunctionApply(MacroAssembler* masm) {
}
+
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+ Label* stack_overflow) {
+ // 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) {
__ SmiTag(r0);
__ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
@@ -1446,6 +1462,8 @@ void
Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -- r2 : expected number of arguments
// -----------------------------------
+ Label stack_overflow;
+ ArgumentAdaptorStackCheck(masm, &stack_overflow);
Label invoke, dont_adapt_arguments;
Label enough, too_few;
@@ -1545,6 +1563,10 @@ void
Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ Jump(r3);
+
+ __ bind(&stack_overflow);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
}
Index: src/builtins.h
diff --git a/src/builtins.h b/src/builtins.h
index
88cfd53f48d96fedcda3ecca50282376e85eca0e..fc653334ed8237d1e7c536b5081dafb6843d1073
100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -260,7 +260,8 @@ enum BuiltinExtraArguments {
V(STRING_ADD_LEFT, 1) \
V(STRING_ADD_RIGHT, 1) \
V(APPLY_PREPARE, 1) \
- V(APPLY_OVERFLOW, 1)
+ V(APPLY_OVERFLOW, 1) \
+ V(STACK_OVERFLOW, 0)
class BuiltinFunctionTable;
class ObjectVisitor;
Index: src/ia32/builtins-ia32.cc
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index
785c5fd61c219e1d87555f21c0d084e4f9d3a7a6..61c3f23cb0a14079491cae93ae02e86e858bbc14
100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -1252,6 +1252,33 @@ void
Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
}
+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) {
__ push(ebp);
__ mov(ebp, esp);
@@ -1296,6 +1323,9 @@ void
Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
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,10 @@ void
Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// -------------------------------------------
__ bind(&dont_adapt_arguments);
__ jmp(edx);
+
+ __ bind(&stack_overflow);
+ EnterArgumentsAdaptorFrame(masm);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, JUMP_FUNCTION);
}
Index: src/runtime.js
diff --git a/src/runtime.js b/src/runtime.js
index
a49bc8448dfa52022880ef78e4e10eff632b7a12..89dea0fd08842015070d2abd58470e488b6bc093
100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -469,6 +469,11 @@ function APPLY_OVERFLOW(length) {
}
+function STACK_OVERFLOW(length) {
+ throw %MakeRangeError('stack_overflow', []);
+}
+
+
// Convert the receiver to an object - forward to ToObject.
function TO_OBJECT() {
return %ToObject(this);
Index: test/mjsunit/regress/regress-353058.js
diff --git a/test/mjsunit/regress/regress-353058.js
b/test/mjsunit/regress/regress-353058.js
new file mode 100644
index
0000000000000000000000000000000000000000..0fef24624713edb92e303ce4fbeab0e45e0edfed
--- /dev/null
+++ b/test/mjsunit/regress/regress-353058.js
@@ -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);
--
--
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.