From dcb3c6301bb1e4f9a25a730dc9191755f2813438 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Fri, 19 Apr 2013 15:55:34 +0000 Subject: [PATCH] Propagate OOM exception instead of crashing in CALL_HEAP_FUNCTION_PASS_EXCEPTION macro. R=jkummerow@chromium.org BUG=webkit/fast/js/concat-large-strings-crash.html Review URL: https://chromiumcodereview.appspot.com/14365017 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14358 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap-inl.h | 89 +++++++++++++++++++++++++++++++++------------------------- src/objects.cc | 8 +++--- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/heap-inl.h b/src/heap-inl.h index 43d4a99..ab1fdb4 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -577,56 +577,67 @@ Isolate* Heap::isolate() { // Warning: Do not use the identifiers __object__, __maybe_object__ or // __scope__ in a call to this macro. -#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY)\ - do { \ - GC_GREEDY_CHECK(); \ - MaybeObject* __maybe_object__ = FUNCTION_CALL; \ - Object* __object__ = NULL; \ - if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory()) { \ - v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\ - } \ - if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ - ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ - allocation_space(), \ - "allocation failure"); \ - __maybe_object__ = FUNCTION_CALL; \ - if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory()) { \ - v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\ - } \ - if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ - ISOLATE->counters()->gc_last_resort_from_handles()->Increment(); \ - ISOLATE->heap()->CollectAllAvailableGarbage("last resort gc"); \ - { \ - AlwaysAllocateScope __scope__; \ - __maybe_object__ = FUNCTION_CALL; \ - } \ - if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ - if (__maybe_object__->IsOutOfMemory() || \ - __maybe_object__->IsRetryAfterGC()) { \ - /* TODO(1181417): Fix this. */ \ - v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\ - } \ - RETURN_EMPTY; \ +#define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY, OOM)\ + do { \ + GC_GREEDY_CHECK(); \ + MaybeObject* __maybe_object__ = FUNCTION_CALL; \ + Object* __object__ = NULL; \ + if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ + if (__maybe_object__->IsOutOfMemory()) { \ + OOM; \ + } \ + if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ + ISOLATE->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \ + allocation_space(), \ + "allocation failure"); \ + __maybe_object__ = FUNCTION_CALL; \ + if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ + if (__maybe_object__->IsOutOfMemory()) { \ + OOM; \ + } \ + if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY; \ + ISOLATE->counters()->gc_last_resort_from_handles()->Increment(); \ + ISOLATE->heap()->CollectAllAvailableGarbage("last resort gc"); \ + { \ + AlwaysAllocateScope __scope__; \ + __maybe_object__ = FUNCTION_CALL; \ + } \ + if (__maybe_object__->ToObject(&__object__)) RETURN_VALUE; \ + if (__maybe_object__->IsOutOfMemory()) { \ + OOM; \ + } \ + if (__maybe_object__->IsRetryAfterGC()) { \ + /* TODO(1181417): Fix this. */ \ + v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \ + } \ + RETURN_EMPTY; \ } while (false) +#define CALL_AND_RETRY_OR_DIE( \ + ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \ + CALL_AND_RETRY( \ + ISOLATE, \ + FUNCTION_CALL, \ + RETURN_VALUE, \ + RETURN_EMPTY, \ + v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY", true)) -#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ - CALL_AND_RETRY(ISOLATE, \ - FUNCTION_CALL, \ - return Handle(TYPE::cast(__object__), ISOLATE), \ - return Handle()) +#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ + CALL_AND_RETRY_OR_DIE(ISOLATE, \ + FUNCTION_CALL, \ + return Handle(TYPE::cast(__object__), ISOLATE), \ + return Handle()) \ -#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ - CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, return, return) +#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL) \ + CALL_AND_RETRY_OR_DIE(ISOLATE, FUNCTION_CALL, return, return) #define CALL_HEAP_FUNCTION_PASS_EXCEPTION(ISOLATE, FUNCTION_CALL) \ CALL_AND_RETRY(ISOLATE, \ FUNCTION_CALL, \ return __object__, \ + return __maybe_object__, \ return __maybe_object__) diff --git a/src/objects.cc b/src/objects.cc index 1da76c6..17c648a 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -4027,10 +4027,10 @@ MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) { int JSObject::GetIdentityHash(Handle obj) { - CALL_AND_RETRY(obj->GetIsolate(), - obj->GetIdentityHash(ALLOW_CREATION), - return Smi::cast(__object__)->value(), - return 0); + CALL_AND_RETRY_OR_DIE(obj->GetIsolate(), + obj->GetIdentityHash(ALLOW_CREATION), + return Smi::cast(__object__)->value(), + return 0); } -- 2.7.4