Commit df7df4df authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[heap] Move CALL_HEAP_FUNCTION macro into factory.cc file.

R=hpayer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30985}
parent 2786ceec
......@@ -15,6 +15,44 @@ namespace v8 {
namespace internal {
// Calls the FUNCTION_CALL function and retries it up to three times
// to guarantee that any allocations performed during the call will
// succeed if there's enough memory.
//
// Warning: Do not use the identifiers __object__, __maybe_object__,
// __allocation__ or __scope__ in a call to this macro.
#define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
if (__allocation__.To(&__object__)) { \
DCHECK(__object__ != (ISOLATE)->heap()->exception()); \
return Handle<TYPE>(TYPE::cast(__object__), ISOLATE); \
}
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \
do { \
AllocationResult __allocation__ = FUNCTION_CALL; \
Object* __object__ = NULL; \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
/* Two GCs before panicking. In newspace will almost always succeed. */ \
for (int __i__ = 0; __i__ < 2; __i__++) { \
(ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \
"allocation failure"); \
__allocation__ = FUNCTION_CALL; \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
} \
(ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \
(ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \
{ \
AlwaysAllocateScope __scope__(ISOLATE); \
__allocation__ = FUNCTION_CALL; \
} \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
/* TODO(1181417): Fix this. */ \
v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
return Handle<TYPE>(); \
} while (false)
template<typename T>
Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) {
CALL_HEAP_FUNCTION(
......
......@@ -537,44 +537,6 @@ Isolate* Heap::isolate() {
}
// Calls the FUNCTION_CALL function and retries it up to three times
// to guarantee that any allocations performed during the call will
// succeed if there's enough memory.
//
// Warning: Do not use the identifiers __object__, __maybe_object__,
// __allocation__ or __scope__ in a call to this macro.
#define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
if (__allocation__.To(&__object__)) { \
DCHECK(__object__ != (ISOLATE)->heap()->exception()); \
return Handle<TYPE>(TYPE::cast(__object__), ISOLATE); \
}
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \
do { \
AllocationResult __allocation__ = FUNCTION_CALL; \
Object* __object__ = NULL; \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
/* Two GCs before panicking. In newspace will almost always succeed. */ \
for (int __i__ = 0; __i__ < 2; __i__++) { \
(ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \
"allocation failure"); \
__allocation__ = FUNCTION_CALL; \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
} \
(ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \
(ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \
{ \
AlwaysAllocateScope __scope__(ISOLATE); \
__allocation__ = FUNCTION_CALL; \
} \
RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \
/* TODO(1181417): Fix this. */ \
v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
return Handle<TYPE>(); \
} while (false)
void Heap::ExternalStringTable::AddString(String* string) {
DCHECK(string->IsExternalString());
if (heap_->InNewSpace(string)) {
......
......@@ -37,18 +37,8 @@ using namespace v8::internal;
AllocationResult v8::internal::HeapTester::AllocateAfterFailures() {
static int attempts = 0;
// The first 4 times we simulate a full heap, by returning retry.
if (++attempts < 4) return AllocationResult::Retry();
// Expose some private stuff on Heap.
Heap* heap = CcTest::heap();
// Now that we have returned 'retry' 4 times, we are in a last-chance
// scenario, with always_allocate. See CALL_AND_RETRY. Test that all
// allocations succeed.
// New space.
heap->AllocateByteArray(100).ToObjectChecked();
heap->AllocateFixedArray(100, NOT_TENURED).ToObjectChecked();
......@@ -98,7 +88,12 @@ AllocationResult v8::internal::HeapTester::AllocateAfterFailures() {
Handle<Object> v8::internal::HeapTester::TestAllocateAfterFailures() {
CALL_HEAP_FUNCTION(CcTest::i_isolate(), AllocateAfterFailures(), Object);
// Similar to what the CALL_AND_RETRY macro does in the last-resort case, we
// are wrapping the allocator function in an AlwaysAllocateScope. Test that
// all allocations succeed immediately without any retry.
CcTest::heap()->CollectAllAvailableGarbage("panic");
AlwaysAllocateScope scope(CcTest::i_isolate());
return handle(AllocateAfterFailures().ToObjectChecked(), CcTest::i_isolate());
}
......
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