| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 9f568c67807a345025cd3a20e185cd71e4b6022b..6fb50a51c3b53fc986b7e678e43b5476fb688a57 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -28,6 +28,7 @@
|
| #include "src/natives.h"
|
| #include "src/runtime-profiler.h"
|
| #include "src/scopeinfo.h"
|
| +#include "src/serialize.h"
|
| #include "src/snapshot.h"
|
| #include "src/utils.h"
|
| #include "src/v8threads.h"
|
| @@ -918,33 +919,41 @@ static bool AbortIncrementalMarkingAndCollectGarbage(
|
| }
|
|
|
|
|
| -void Heap::ReserveSpace(int* sizes, Address* locations_out) {
|
| +bool Heap::ReserveSpace(Reservation* reservations) {
|
| bool gc_performed = true;
|
| int counter = 0;
|
| static const int kThreshold = 20;
|
| while (gc_performed && counter++ < kThreshold) {
|
| gc_performed = false;
|
| for (int space = NEW_SPACE; space < Serializer::kNumberOfSpaces; space++) {
|
| - if (sizes[space] == 0) continue;
|
| + Reservation* reservation = &reservations[space];
|
| + DCHECK_LE(1, reservation->length());
|
| + if (reservation->at(0).size == 0) continue;
|
| bool perform_gc = false;
|
| if (space == LO_SPACE) {
|
| - perform_gc = !lo_space()->CanAllocateSize(sizes[space]);
|
| + DCHECK_EQ(1, reservation->length());
|
| + perform_gc = !lo_space()->CanAllocateSize(reservation->at(0).size);
|
| } else {
|
| - AllocationResult allocation;
|
| - if (space == NEW_SPACE) {
|
| - allocation = new_space()->AllocateRaw(sizes[space]);
|
| - } else {
|
| - allocation = paged_space(space)->AllocateRaw(sizes[space]);
|
| - }
|
| - FreeListNode* node;
|
| - if (allocation.To(&node)) {
|
| - // Mark with a free list node, in case we have a GC before
|
| - // deserializing.
|
| - node->set_size(this, sizes[space]);
|
| - DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
|
| - locations_out[space] = node->address();
|
| - } else {
|
| - perform_gc = true;
|
| + for (auto& chunk : *reservation) {
|
| + AllocationResult allocation;
|
| + int size = chunk.size;
|
| + if (space == NEW_SPACE) {
|
| + allocation = new_space()->AllocateRaw(size);
|
| + } else {
|
| + allocation = paged_space(space)->AllocateRaw(size);
|
| + }
|
| + FreeListNode* node;
|
| + if (allocation.To(&node)) {
|
| + // Mark with a free list node, in case we have a GC before
|
| + // deserializing.
|
| + node->set_size(this, size);
|
| + DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
|
| + chunk.start = node->address();
|
| + chunk.end = node->address() + size;
|
| + } else {
|
| + perform_gc = true;
|
| + break;
|
| + }
|
| }
|
| }
|
| if (perform_gc) {
|
| @@ -962,10 +971,7 @@ void Heap::ReserveSpace(int* sizes, Address* locations_out) {
|
| }
|
| }
|
|
|
| - if (gc_performed) {
|
| - // Failed to reserve the space after several attempts.
|
| - V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
|
| - }
|
| + return !gc_performed;
|
| }
|
|
|
|
|
|
|