From: yangguo@chromium.org Date: Thu, 27 Mar 2014 09:26:47 +0000 (+0000) Subject: Correctly OOM in the CEntryStub after retries. X-Git-Tag: upstream/4.7.83~9980 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ee078368657b9444a914eb187bded1a1f2622a6;p=platform%2Fupstream%2Fv8.git Correctly OOM in the CEntryStub after retries. This fixes a bug introduced in r20179. R=jkummerow@chromium.org BUG=356211 LOG=N Review URL: https://codereview.chromium.org/213193011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20292 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index fe2095a..832296b 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -1685,6 +1685,12 @@ void CEntryStub::Generate(MacroAssembler* masm) { true, true); + { FrameScope scope(masm, StackFrame::MANUAL); + __ PrepareCallCFunction(0, r0); + __ CallCFunction( + ExternalReference::out_of_memory_function(masm->isolate()), 0, 0); + } + __ bind(&throw_termination_exception); __ ThrowUncatchable(r0); diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index b6411d9..5b4c3c4 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -1764,6 +1764,11 @@ void CEntryStub::Generate(MacroAssembler* masm) { } __ SetStackPointer(jssp); + { FrameScope scope(masm, StackFrame::MANUAL); + __ CallCFunction( + ExternalReference::out_of_memory_function(masm->isolate()), 0, 0); + } + // Throw exceptions. // If we throw an exception, we can end up re-entering CEntryStub before we // pop the exit frame, so need to ensure that x21-x23 contain GC-safe values diff --git a/src/assembler.cc b/src/assembler.cc index e53ca7c..772b6d6 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -1059,6 +1059,12 @@ ExternalReference ExternalReference::perform_gc_function(Isolate* isolate) { } +ExternalReference ExternalReference::out_of_memory_function(Isolate* isolate) { + return + ExternalReference(Redirect(isolate, FUNCTION_ADDR(Runtime::OutOfMemory))); +} + + ExternalReference ExternalReference::delete_handle_scope_extensions( Isolate* isolate) { return ExternalReference(Redirect( diff --git a/src/assembler.h b/src/assembler.h index b0eff94..0349b06 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -748,6 +748,7 @@ class ExternalReference BASE_EMBEDDED { Isolate* isolate); static ExternalReference flush_icache_function(Isolate* isolate); static ExternalReference perform_gc_function(Isolate* isolate); + static ExternalReference out_of_memory_function(Isolate* isolate); static ExternalReference delete_handle_scope_extensions(Isolate* isolate); static ExternalReference get_date_field_function(Isolate* isolate); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 44f2472..ab29167 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -2751,6 +2751,12 @@ void CEntryStub::Generate(MacroAssembler* masm) { true, true); + { FrameScope scope(masm, StackFrame::MANUAL); + __ PrepareCallCFunction(0, eax); + __ CallCFunction( + ExternalReference::out_of_memory_function(masm->isolate()), 0); + } + __ bind(&throw_termination_exception); __ ThrowUncatchable(eax); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index c119c8e..332ed4b 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -1794,6 +1794,12 @@ void CEntryStub::Generate(MacroAssembler* masm) { true, true); + { FrameScope scope(masm, StackFrame::MANUAL); + __ PrepareCallCFunction(0, v0); + __ CallCFunction( + ExternalReference::out_of_memory_function(masm->isolate()), 0); + } + __ bind(&throw_termination_exception); __ ThrowUncatchable(v0); diff --git a/src/runtime.cc b/src/runtime.cc index 41c91c5..8f4c4ca 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -15175,4 +15175,9 @@ void Runtime::PerformGC(Object* result, Isolate* isolate) { } +void Runtime::OutOfMemory() { + Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); + UNREACHABLE(); +} + } } // namespace v8::internal diff --git a/src/runtime.h b/src/runtime.h index 407bf6f..58cd525 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -895,6 +895,7 @@ class Runtime : public AllStatic { // Helper functions used stubs. static void PerformGC(Object* result, Isolate* isolate); + static void OutOfMemory(); // Used in runtime.cc and hydrogen's VisitArrayLiteral. static Handle CreateArrayLiteralBoilerplate( diff --git a/src/serialize.cc b/src/serialize.cc index 45bc8f2..4048886 100644 --- a/src/serialize.cc +++ b/src/serialize.cc @@ -313,6 +313,11 @@ void ExternalReferenceTable::PopulateTable(Isolate* isolate) { RUNTIME_ENTRY, 1, "Runtime::PerformGC"); + // Runtime entries + Add(ExternalReference::out_of_memory_function(isolate).address(), + RUNTIME_ENTRY, + 2, + "Runtime::OutOfMemory"); Add(ExternalReference::delete_handle_scope_extensions(isolate).address(), RUNTIME_ENTRY, 4, diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index cfb7f75..c949a42 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -2603,6 +2603,12 @@ void CEntryStub::Generate(MacroAssembler* masm) { true, true); + { FrameScope scope(masm, StackFrame::MANUAL); + __ PrepareCallCFunction(0); + __ CallCFunction( + ExternalReference::out_of_memory_function(masm->isolate()), 0); + } + __ bind(&throw_termination_exception); __ ThrowUncatchable(rax); diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index 55bb466..3ccc3d7 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -3889,4 +3889,28 @@ TEST(AddInstructionChangesNewSpacePromotion) { g->Call(global, 1, args1); heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); } -#endif + + +void OnFatalErrorExpectOOM(const char* location, const char* message) { + // Exit with 0 if the location matches our expectation. + exit(strcmp(location, "CALL_AND_RETRY_LAST")); +} + + +TEST(CEntryStubOOM) { + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + v8::V8::SetFatalErrorHandler(OnFatalErrorExpectOOM); + + CompileRun( + "%SetFlags('--gc-interval=1');" + "var a = [];" + "a.__proto__ = [];" + "a.unshift(1)"); + + // We should have run into an out of memory. + UNREACHABLE(); +} + +#endif // DEBUG