From c0fa861726cee6e2c150532b27f615672b2b7968 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 31 Mar 2014 14:14:54 +0000 Subject: [PATCH] Do not check for interrupt when allocating stack locals. R=dcarney@chromium.org BUG=357137 LOG=N Review URL: https://codereview.chromium.org/219373004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20357 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/full-codegen-arm.cc | 6 +++- src/arm64/full-codegen-arm64.cc | 6 +++- src/ia32/full-codegen-ia32.cc | 6 ++-- src/mips/full-codegen-mips.cc | 6 +++- src/x64/full-codegen-x64.cc | 6 +++- test/cctest/test-heap.cc | 29 ++++++++++++++++++++ test/mjsunit/regress/regress-crbug-357137.js | 8 ++++++ 7 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-357137.js diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 2ca80166ec..3539bbc8df 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -118,10 +118,14 @@ static void EmitStackCheck(MacroAssembler* masm_, Isolate* isolate = masm_->isolate(); Label ok; ASSERT(scratch.is(sp) == (pointers == 0)); + Heap::RootListIndex index; if (pointers != 0) { __ sub(scratch, sp, Operand(pointers * kPointerSize)); + index = Heap::kRealStackLimitRootIndex; + } else { + index = Heap::kStackLimitRootIndex; } - __ LoadRoot(stack_limit_scratch, Heap::kStackLimitRootIndex); + __ LoadRoot(stack_limit_scratch, index); __ cmp(scratch, Operand(stack_limit_scratch)); __ b(hs, &ok); PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index ff638a4b45..46dabae35d 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -117,10 +117,14 @@ static void EmitStackCheck(MacroAssembler* masm_, Label ok; ASSERT(jssp.Is(__ StackPointer())); ASSERT(scratch.Is(jssp) == (pointers == 0)); + Heap::RootListIndex index; if (pointers != 0) { __ Sub(scratch, jssp, pointers * kPointerSize); + index = Heap::kRealStackLimitRootIndex; + } else { + index = Heap::kStackLimitRootIndex; } - __ CompareRoot(scratch, Heap::kStackLimitRootIndex); + __ CompareRoot(scratch, index); __ B(hs, &ok); PredictableCodeSizeScope predictable(masm_, Assembler::kCallSizeWithRelocation); diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 1a7d828c92..c3c1bda771 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -106,12 +106,14 @@ static void EmitStackCheck(MacroAssembler* masm_, Register scratch = esp) { Label ok; Isolate* isolate = masm_->isolate(); - ExternalReference stack_limit = - ExternalReference::address_of_stack_limit(isolate); ASSERT(scratch.is(esp) == (pointers == 0)); + ExternalReference stack_limit; if (pointers != 0) { __ mov(scratch, esp); __ sub(scratch, Immediate(pointers * kPointerSize)); + stack_limit = ExternalReference::address_of_real_stack_limit(isolate); + } else { + stack_limit = ExternalReference::address_of_stack_limit(isolate); } __ cmp(scratch, Operand::StaticVariable(stack_limit)); __ j(above_equal, &ok, Label::kNear); diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index a676fea898..8c92c94ea6 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -127,10 +127,14 @@ static void EmitStackCheck(MacroAssembler* masm_, Isolate* isolate = masm_->isolate(); Label ok; ASSERT(scratch.is(sp) == (pointers == 0)); + Heap::RootListIndex index; if (pointers != 0) { __ Subu(scratch, sp, Operand(pointers * kPointerSize)); + index = Heap::kRealStackLimitRootIndex; + } else { + index = Heap::kStackLimitRootIndex; } - __ LoadRoot(stack_limit_scratch, Heap::kStackLimitRootIndex); + __ LoadRoot(stack_limit_scratch, index); __ Branch(&ok, hs, scratch, Operand(stack_limit_scratch)); PredictableCodeSizeScope predictable(masm_, 4 * Assembler::kInstrSize); __ Call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET); diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 6d1e956aad..97cd460eeb 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -107,11 +107,15 @@ static void EmitStackCheck(MacroAssembler* masm_, Isolate* isolate = masm_->isolate(); Label ok; ASSERT(scratch.is(rsp) == (pointers == 0)); + Heap::RootListIndex index; if (pointers != 0) { __ movp(scratch, rsp); __ subp(scratch, Immediate(pointers * kPointerSize)); + index = Heap::kRealStackLimitRootIndex; + } else { + index = Heap::kStackLimitRootIndex; } - __ CompareRoot(scratch, Heap::kStackLimitRootIndex); + __ CompareRoot(scratch, index); __ j(above_equal, &ok, Label::kNear); __ call(isolate->builtins()->StackCheck(), RelocInfo::CODE_TARGET); __ bind(&ok); diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index c1f20f1f06..25d19af76c 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -3913,3 +3913,32 @@ TEST(CEntryStubOOM) { } #endif // DEBUG + + +static void InterruptCallback357137(v8::Isolate* isolate, void* data) { } + + +static void RequestInterrupt(const v8::FunctionCallbackInfo& args) { + CcTest::isolate()->RequestInterrupt(&InterruptCallback357137, NULL); +} + + +TEST(Regress357137) { + CcTest::InitializeVM(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope hscope(isolate); + v8::Handle global =v8::ObjectTemplate::New(isolate); + global->Set(v8::String::NewFromUtf8(isolate, "interrupt"), + v8::FunctionTemplate::New(isolate, RequestInterrupt)); + v8::Local context = v8::Context::New(isolate, NULL, global); + ASSERT(!context.IsEmpty()); + v8::Context::Scope cscope(context); + + v8::Local result = CompileRun( + "var locals = '';" + "for (var i = 0; i < 512; i++) locals += 'var v' + i + '= 42;';" + "eval('function f() {' + locals + 'return function() { return v0; }; }');" + "interrupt();" // This triggers a fake stack overflow in f. + "f()()"); + CHECK_EQ(42.0, result->ToNumber()->Value()); +} diff --git a/test/mjsunit/regress/regress-crbug-357137.js b/test/mjsunit/regress/regress-crbug-357137.js new file mode 100644 index 0000000000..a780426f01 --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-357137.js @@ -0,0 +1,8 @@ +// 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. + +var locals = ""; +for (var i = 0; i < 1024; i++) locals += "var v" + i + ";"; +eval("function f() {" + locals + "f();}"); +assertThrows("f()", RangeError);