| Index: src/heap/spaces.cc
|
| diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
|
| index c4219df48b7dbbac8a29e1d1d7e3728b16415397..af56ccc2bc64e9baf49d66286345d9bd69ed4268 100644
|
| --- a/src/heap/spaces.cc
|
| +++ b/src/heap/spaces.cc
|
| @@ -333,6 +333,10 @@ void MemoryAllocator::TearDown() {
|
| capacity_ = 0;
|
| capacity_executable_ = 0;
|
|
|
| + if (last_chunk_.IsReserved()) {
|
| + last_chunk_.Release();
|
| + }
|
| +
|
| delete code_range_;
|
| code_range_ = nullptr;
|
| }
|
| @@ -680,6 +684,23 @@ MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size,
|
| PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size);
|
| }
|
|
|
| + // We cannot use the last chunk in the address space because we would
|
| + // overflow when comparing top and limit if this chunk is used for a
|
| + // linear allocation area.
|
| + if ((reinterpret_cast<uintptr_t>(base) + chunk_size) == 0u) {
|
| + CHECK(!last_chunk_.IsReserved());
|
| + last_chunk_.TakeControl(&reservation);
|
| + UncommitBlock(reinterpret_cast<Address>(last_chunk_.address()),
|
| + last_chunk_.size());
|
| + size_.Increment(-static_cast<intptr_t>(chunk_size));
|
| + if (executable == EXECUTABLE) {
|
| + size_executable_.Increment(-static_cast<intptr_t>(chunk_size));
|
| + }
|
| + CHECK(last_chunk_.IsReserved());
|
| + return AllocateChunk(reserve_area_size, commit_area_size, executable,
|
| + owner);
|
| + }
|
| +
|
| return MemoryChunk::Initialize(heap, base, chunk_size, area_start, area_end,
|
| executable, owner, &reservation);
|
| }
|
|
|