Reviewers: Sven Panne,

Message:
Second patch set is the fix.

It turns out that the test case does not always succeed in triggering an OOM, in
which case we should have a check that does not assume OOM.

Also, on ARM64 we were clobbering the JSSP even though we need it for
CallCFunction.

Description:
Reland "Correctly OOM in the CEntryStub after retries."

Please review this at https://codereview.chromium.org/214473003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+71, -4 lines):
  M src/arm/code-stubs-arm.cc
  M src/arm64/code-stubs-arm64.cc
  M src/assembler.h
  M src/assembler.cc
  M src/ia32/code-stubs-ia32.cc
  M src/mips/code-stubs-mips.cc
  M src/runtime.h
  M src/runtime.cc
  M src/serialize.cc
  M src/x64/code-stubs-x64.cc
  M test/cctest/test-heap.cc


Index: src/arm/code-stubs-arm.cc
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index fe2095a074a79bbc3954f3a4803bb033d903e378..832296b2738f935d33ea1cd6d43b6ad9bc870b0b 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);

Index: src/arm64/code-stubs-arm64.cc
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index b6411d950ee0c77893db422b4cf93bc7d2227ddf..b097fc52ed4135bc1e50964da12dc02f0c807ce6 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -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: src/assembler.cc
diff --git a/src/assembler.cc b/src/assembler.cc
index e53ca7c83a131ed1b3de13f6a9ba815c1024ded5..772b6d69631cd2fc063196373087cd1bba911c14 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(
Index: src/assembler.h
diff --git a/src/assembler.h b/src/assembler.h
index b0eff949792fd9322193037bdf58e7a1478184b7..0349b065821b57f1ad282ec0f58959261e6e575e 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);
Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 44f2472b1e1039e84b9edd7d7f06af965c1b8776..ab29167e9ade141c3d816254fd337d5f9966cb4f 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);

Index: src/mips/code-stubs-mips.cc
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index c119c8e17bc5944380ec60291373e0cd75fd3d41..332ed4b6ab5c7367c45fb56e04bc37e938aa4950 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);

Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 41c91c5785e9b55eedb6edc4f8aee848f04b3bba..8f4c4ca7373a817753168bcba05f316ba8b6daef 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
Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index 407bf6f4f0f14dbbb8474f3936305c2bd0ef5d46..58cd5259c9b89ff1160f1043fcaa5398e6526a67 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<Object> CreateArrayLiteralBoilerplate(
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index 45bc8f22c7953cb62c1fb1d0b1f88790174b1f14..4048886fdb76b5a499a4fb83670924fc998c4b2e 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,
Index: src/x64/code-stubs-x64.cc
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index cfb7f75423319a32351beb0f250c79718dd62060..c949a423a2e189ecc725427c86d42f74111da7fc 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);

Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 55bb466416fa352a6785cd79c757f272be04d0d1..c1f20f1f06eb185ab91fd521589832304e0b9d57 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -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


--
--
v8-dev mailing list
v8-dev@googlegroups.com
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 v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to