Reland "Correctly OOM in the CEntryStub after retries."
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 27 Mar 2014 10:41:45 +0000 (10:41 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 27 Mar 2014 10:41:45 +0000 (10:41 +0000)
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

src/arm/code-stubs-arm.cc
src/arm64/code-stubs-arm64.cc
src/assembler.cc
src/assembler.h
src/ia32/code-stubs-ia32.cc
src/mips/code-stubs-mips.cc
src/runtime.cc
src/runtime.h
src/serialize.cc
src/x64/code-stubs-x64.cc
test/cctest/test-heap.cc

index fe2095a..832296b 100644 (file)
@@ -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);
 
index b6411d9..b097fc5 100644 (file)
@@ -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.
index e53ca7c..772b6d6 100644 (file)
@@ -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(
index b0eff94..0349b06 100644 (file)
@@ -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);
index 44f2472..ab29167 100644 (file)
@@ -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);
 
index c119c8e..332ed4b 100644 (file)
@@ -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);
 
index 41c91c5..8f4c4ca 100644 (file)
@@ -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
index 407bf6f..58cd525 100644 (file)
@@ -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(
index 45bc8f2..4048886 100644 (file)
@@ -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,
index cfb7f75..c949a42 100644 (file)
@@ -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);
 
index 55bb466..c1f20f1 100644 (file)
@@ -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