Allow three runtime call attempts before throwing an out of
authorkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Oct 2008 12:16:34 +0000 (12:16 +0000)
committerkasperl@chromium.org <kasperl@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Oct 2008 12:16:34 +0000 (12:16 +0000)
memory exception. Still needs work in Runtime_PerformGC to
make sure we'll allow future allocations.
Review URL: http://codereview.chromium.org/8873

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@638 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/codegen-arm.cc
src/codegen-ia32.cc
src/handles.cc
src/runtime.cc

index 4b1ada1..256dec5 100644 (file)
@@ -3920,23 +3920,27 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
   Label throw_out_of_memory_exception;
   Label throw_normal_exception;
 
-#ifdef DEBUG
+  // Call into the runtime system. Collect garbage before the call if
+  // running with --gc-greedy set.
   if (FLAG_gc_greedy) {
     Failure* failure = Failure::RetryAfterGC(0);
     __ mov(r0, Operand(reinterpret_cast<intptr_t>(failure)));
   }
-  GenerateCore(masm,
-               &throw_normal_exception,
+  GenerateCore(masm, &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
                FLAG_gc_greedy);
-#else
+
+  // Do space-specific GC and retry runtime call.
   GenerateCore(masm,
                &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
-               false);
-#endif
+               true);
+
+  // Do full GC and retry runtime call one final time.
+  Failure* failure = Failure::InternalError();
+  __ mov(r0, Operand(reinterpret_cast<int32_t>(failure)));
   GenerateCore(masm,
                &throw_normal_exception,
                &throw_out_of_memory_exception,
index cf76fe9..582e430 100644 (file)
@@ -4955,7 +4955,8 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
   Label throw_out_of_memory_exception;
   Label throw_normal_exception;
 
-#ifdef DEBUG
+  // Call into the runtime system. Collect garbage before the call if
+  // running with --gc-greedy set.
   if (FLAG_gc_greedy) {
     Failure* failure = Failure::RetryAfterGC(0);
     __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(failure)));
@@ -4964,14 +4965,17 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
                &throw_out_of_memory_exception,
                frame_type,
                FLAG_gc_greedy);
-#else
+
+  // Do space-specific GC and retry runtime call.
   GenerateCore(masm,
                &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
-               false);
-#endif
+               true);
 
+  // Do full GC and retry runtime call one final time.
+  Failure* failure = Failure::InternalError();
+  __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(failure)));
   GenerateCore(masm,
                &throw_normal_exception,
                &throw_out_of_memory_exception,
index 1a600db..5b0e1ce 100644 (file)
 
 namespace v8 { namespace internal {
 
-#define CALL_GC(RESULT)                                             \
-  {                                                                 \
-    Failure* __failure__ = Failure::cast(RESULT);                   \
-    if (!Heap::CollectGarbage(__failure__->requested(),             \
-                              __failure__->allocation_space())) {   \
-       /* TODO(1181417): Fix this. */                               \
-       V8::FatalProcessOutOfMemory("Handles");                      \
-    }                                                               \
-  }
-
 
 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
                                       Handle<JSArray> array) {
@@ -283,10 +273,6 @@ Handle<JSValue> GetScriptWrapper(Handle<Script> script) {
 }
 
 
-#undef CALL_HEAP_FUNCTION
-#undef CALL_GC
-
-
 // Compute the property keys from the interceptor.
 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
                                                  Handle<JSObject> object) {
index d67db3d..821de5e 100644 (file)
@@ -5780,9 +5780,15 @@ Runtime::Function* Runtime::FunctionForName(const char* name) {
 
 void Runtime::PerformGC(Object* result) {
   Failure* failure = Failure::cast(result);
-  // Try to do a garbage collection; ignore it if it fails. The C
-  // entry stub will throw an out-of-memory exception in that case.
-  Heap::CollectGarbage(failure->requested(), failure->allocation_space());
+  if (failure->IsRetryAfterGC()) {
+    // Try to do a garbage collection; ignore it if it fails. The C
+    // entry stub will throw an out-of-memory exception in that case.
+    Heap::CollectGarbage(failure->requested(), failure->allocation_space());
+  } else {
+    // Handle last resort GC and make sure to allow future allocations
+    // to grow the heap without causing GCs (if possible).
+    Heap::CollectAllGarbage();
+  }
 }