Commit 8847b520 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Reland "Correctly OOM in the CEntryStub after retries."

R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/214473003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20297 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e510131d
......@@ -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);
......
......@@ -1755,13 +1755,15 @@ void CEntryStub::Generate(MacroAssembler* masm) {
true,
true);
{ FrameScope scope(masm, StackFrame::MANUAL);
__ CallCFunction(
ExternalReference::out_of_memory_function(masm->isolate()), 0);
}
// We didn't execute a return case, so the stack frame hasn't been updated
// (except for the return address slot). However, we don't need to initialize
// jssp because the throw method will immediately overwrite it when it
// unwinds the stack.
if (__ emit_debug_code()) {
__ Mov(jssp, kDebugZapValue);
}
__ SetStackPointer(jssp);
// Throw exceptions.
......
......@@ -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(
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......@@ -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<Object> CreateArrayLiteralBoilerplate(
......
......@@ -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,
......
......@@ -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);
......
......@@ -3889,4 +3889,27 @@ 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);
v8::Handle<v8::Value> result = CompileRun(
"%SetFlags('--gc-interval=1');"
"var a = [];"
"a.__proto__ = [];"
"a.unshift(1)");
CHECK(result->IsNumber());
}
#endif // DEBUG
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment