| Index: src/heap-inl.h
|
| diff --git a/src/heap-inl.h b/src/heap-inl.h
|
| index a728777df19b9b93d196320807fa56118d60991a..ab11b325c1e0bcbfbba63f71ee88ef9f87e77532 100644
|
| --- a/src/heap-inl.h
|
| +++ b/src/heap-inl.h
|
| @@ -76,7 +76,7 @@ bool inline Heap::IsOneByte(String* str, int chars) {
|
| }
|
|
|
|
|
| -MaybeObject* Heap::AllocateInternalizedStringFromUtf8(
|
| +AllocationResult Heap::AllocateInternalizedStringFromUtf8(
|
| Vector<const char> str, int chars, uint32_t hash_field) {
|
| if (IsOneByte(str, chars)) {
|
| return AllocateOneByteInternalizedString(
|
| @@ -87,7 +87,7 @@ MaybeObject* Heap::AllocateInternalizedStringFromUtf8(
|
|
|
|
|
| template<typename T>
|
| -MaybeObject* Heap::AllocateInternalizedStringImpl(
|
| +AllocationResult Heap::AllocateInternalizedStringImpl(
|
| T t, int chars, uint32_t hash_field) {
|
| if (IsOneByte(t, chars)) {
|
| return AllocateInternalizedStringImpl<true>(t, chars, hash_field);
|
| @@ -96,8 +96,9 @@ MaybeObject* Heap::AllocateInternalizedStringImpl(
|
| }
|
|
|
|
|
| -MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
|
| - uint32_t hash_field) {
|
| +AllocationResult Heap::AllocateOneByteInternalizedString(
|
| + Vector<const uint8_t> str,
|
| + uint32_t hash_field) {
|
| if (str.length() > String::kMaxLength) {
|
| return isolate()->ThrowInvalidStringLength();
|
| }
|
| @@ -107,13 +108,13 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
|
| AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
|
|
|
| // Allocate string.
|
| - Object* result;
|
| - { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + HeapObject* result;
|
| + { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| + if (!allocation.To(&result)) return allocation;
|
| }
|
|
|
| // String maps are all immortal immovable objects.
|
| - reinterpret_cast<HeapObject*>(result)->set_map_no_write_barrier(map);
|
| + result->set_map_no_write_barrier(map);
|
| // Set length and hash fields of the allocated string.
|
| String* answer = String::cast(result);
|
| answer->set_length(str.length());
|
| @@ -129,8 +130,8 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
|
| }
|
|
|
|
|
| -MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
|
| - uint32_t hash_field) {
|
| +AllocationResult Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
|
| + uint32_t hash_field) {
|
| if (str.length() > String::kMaxLength) {
|
| return isolate()->ThrowInvalidStringLength();
|
| }
|
| @@ -140,12 +141,12 @@ MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
|
| AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, TENURED);
|
|
|
| // Allocate string.
|
| - Object* result;
|
| - { MaybeObject* maybe_result = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + HeapObject* result;
|
| + { AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
|
| + if (!allocation.To(&result)) return allocation;
|
| }
|
|
|
| - reinterpret_cast<HeapObject*>(result)->set_map(map);
|
| + result->set_map(map);
|
| // Set length and hash fields of the allocated string.
|
| String* answer = String::cast(result);
|
| answer->set_length(str.length());
|
| @@ -160,27 +161,27 @@ MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
|
| return answer;
|
| }
|
|
|
| -MaybeObject* Heap::CopyFixedArray(FixedArray* src) {
|
| +AllocationResult Heap::CopyFixedArray(FixedArray* src) {
|
| if (src->length() == 0) return src;
|
| return CopyFixedArrayWithMap(src, src->map());
|
| }
|
|
|
|
|
| -MaybeObject* Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
|
| +AllocationResult Heap::CopyFixedDoubleArray(FixedDoubleArray* src) {
|
| if (src->length() == 0) return src;
|
| return CopyFixedDoubleArrayWithMap(src, src->map());
|
| }
|
|
|
|
|
| -MaybeObject* Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
|
| +AllocationResult Heap::CopyConstantPoolArray(ConstantPoolArray* src) {
|
| if (src->length() == 0) return src;
|
| return CopyConstantPoolArrayWithMap(src, src->map());
|
| }
|
|
|
|
|
| -MaybeObject* Heap::AllocateRaw(int size_in_bytes,
|
| - AllocationSpace space,
|
| - AllocationSpace retry_space) {
|
| +AllocationResult Heap::AllocateRaw(int size_in_bytes,
|
| + AllocationSpace space,
|
| + AllocationSpace retry_space) {
|
| ASSERT(AllowHandleAllocation::IsAllowed());
|
| ASSERT(AllowHeapAllocation::IsAllowed());
|
| ASSERT(gc_state_ == NOT_IN_GC);
|
| @@ -189,58 +190,49 @@ MaybeObject* Heap::AllocateRaw(int size_in_bytes,
|
| if (FLAG_gc_interval >= 0 &&
|
| AllowAllocationFailure::IsAllowed(isolate_) &&
|
| Heap::allocation_timeout_-- <= 0) {
|
| - return Failure::RetryAfterGC(space);
|
| + return AllocationResult::Retry(space);
|
| }
|
| isolate_->counters()->objs_since_last_full()->Increment();
|
| isolate_->counters()->objs_since_last_young()->Increment();
|
| #endif
|
|
|
| HeapObject* object;
|
| - MaybeObject* result;
|
| + AllocationResult allocation;
|
| if (NEW_SPACE == space) {
|
| - result = new_space_.AllocateRaw(size_in_bytes);
|
| - if (always_allocate() && result->IsFailure() && retry_space != NEW_SPACE) {
|
| + allocation = new_space_.AllocateRaw(size_in_bytes);
|
| + if (always_allocate() &&
|
| + allocation.IsRetry() &&
|
| + retry_space != NEW_SPACE) {
|
| space = retry_space;
|
| } else {
|
| - if (profiler->is_tracking_allocations() && result->To(&object)) {
|
| + if (profiler->is_tracking_allocations() && allocation.To(&object)) {
|
| profiler->AllocationEvent(object->address(), size_in_bytes);
|
| }
|
| - return result;
|
| + return allocation;
|
| }
|
| }
|
|
|
| if (OLD_POINTER_SPACE == space) {
|
| - result = old_pointer_space_->AllocateRaw(size_in_bytes);
|
| + allocation = old_pointer_space_->AllocateRaw(size_in_bytes);
|
| } else if (OLD_DATA_SPACE == space) {
|
| - result = old_data_space_->AllocateRaw(size_in_bytes);
|
| + allocation = old_data_space_->AllocateRaw(size_in_bytes);
|
| } else if (CODE_SPACE == space) {
|
| - result = code_space_->AllocateRaw(size_in_bytes);
|
| + allocation = code_space_->AllocateRaw(size_in_bytes);
|
| } else if (LO_SPACE == space) {
|
| - result = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
|
| + allocation = lo_space_->AllocateRaw(size_in_bytes, NOT_EXECUTABLE);
|
| } else if (CELL_SPACE == space) {
|
| - result = cell_space_->AllocateRaw(size_in_bytes);
|
| + allocation = cell_space_->AllocateRaw(size_in_bytes);
|
| } else if (PROPERTY_CELL_SPACE == space) {
|
| - result = property_cell_space_->AllocateRaw(size_in_bytes);
|
| + allocation = property_cell_space_->AllocateRaw(size_in_bytes);
|
| } else {
|
| ASSERT(MAP_SPACE == space);
|
| - result = map_space_->AllocateRaw(size_in_bytes);
|
| + allocation = map_space_->AllocateRaw(size_in_bytes);
|
| }
|
| - if (result->IsFailure()) old_gen_exhausted_ = true;
|
| - if (profiler->is_tracking_allocations() && result->To(&object)) {
|
| + if (allocation.IsRetry()) old_gen_exhausted_ = true;
|
| + if (profiler->is_tracking_allocations() && allocation.To(&object)) {
|
| profiler->AllocationEvent(object->address(), size_in_bytes);
|
| }
|
| - return result;
|
| -}
|
| -
|
| -
|
| -MaybeObject* Heap::NumberFromUint32(
|
| - uint32_t value, PretenureFlag pretenure) {
|
| - if (static_cast<int32_t>(value) >= 0 &&
|
| - Smi::IsValid(static_cast<int32_t>(value))) {
|
| - return Smi::FromInt(static_cast<int32_t>(value));
|
| - }
|
| - // Bypass NumberFromDouble to avoid various redundant checks.
|
| - return AllocateHeapNumber(FastUI2D(value), pretenure);
|
| + return allocation;
|
| }
|
|
|
|
|
| @@ -409,6 +401,8 @@ bool Heap::AllowedToBeMigrated(HeapObject* obj, AllocationSpace dst) {
|
| case PROPERTY_CELL_SPACE:
|
| case LO_SPACE:
|
| return false;
|
| + default:
|
| + break;
|
| }
|
| UNREACHABLE();
|
| return false;
|
| @@ -590,31 +584,28 @@ Isolate* Heap::isolate() {
|
| // __scope__ in a call to this macro.
|
|
|
| #define RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
|
| - if (__maybe_object__->ToObject(&__object__)) { \
|
| + if (!__allocation__.IsRetry()) { \
|
| + __object__ = __allocation__.ToObjectChecked(); \
|
| if (__object__ == (ISOLATE)->heap()->exception()) { RETURN_EMPTY; } \
|
| RETURN_VALUE; \
|
| }
|
|
|
| #define CALL_AND_RETRY(ISOLATE, FUNCTION_CALL, RETURN_VALUE, RETURN_EMPTY) \
|
| do { \
|
| - MaybeObject* __maybe_object__ = FUNCTION_CALL; \
|
| + AllocationResult __allocation__ = FUNCTION_CALL; \
|
| Object* __object__ = NULL; \
|
| RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
|
| - ASSERT(__maybe_object__->IsRetryAfterGC()); \
|
| - (ISOLATE)->heap()->CollectGarbage(Failure::cast(__maybe_object__)-> \
|
| - allocation_space(), \
|
| - "allocation failure"); \
|
| - __maybe_object__ = FUNCTION_CALL; \
|
| + (ISOLATE)->heap()->CollectGarbage(__allocation__.RetrySpace(), \
|
| + "allocation failure"); \
|
| + __allocation__ = FUNCTION_CALL; \
|
| RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
|
| - ASSERT(__maybe_object__->IsRetryAfterGC()); \
|
| (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \
|
| (ISOLATE)->heap()->CollectAllAvailableGarbage("last resort gc"); \
|
| { \
|
| AlwaysAllocateScope __scope__(ISOLATE); \
|
| - __maybe_object__ = FUNCTION_CALL; \
|
| + __allocation__ = FUNCTION_CALL; \
|
| } \
|
| RETURN_OBJECT_UNLESS_EXCEPTION(ISOLATE, RETURN_VALUE, RETURN_EMPTY) \
|
| - ASSERT(__maybe_object__->IsRetryAfterGC()); \
|
| /* TODO(1181417): Fix this. */ \
|
| v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \
|
| RETURN_EMPTY; \
|
|
|