| Index: src/heap/spaces.h | 
| diff --git a/src/heap/spaces.h b/src/heap/spaces.h | 
| index 038cb1cc17a0f3645de3392ed4d557258acdfd4e..0720e9c30965e153c190bfe3e0ae5dd0217108f8 100644 | 
| --- a/src/heap/spaces.h | 
| +++ b/src/heap/spaces.h | 
| @@ -1454,8 +1454,9 @@ class AllocationStats BASE_EMBEDDED { | 
| // Zero out all the allocation statistics (i.e., no capacity). | 
| void Clear() { | 
| capacity_ = 0; | 
| -    max_capacity_ = 0; | 
| size_ = 0; | 
| +    committed_ = 0; | 
| +    max_committed_ = 0; | 
| } | 
|  | 
| void ClearSize() { size_ = capacity_; } | 
| @@ -1468,8 +1469,9 @@ class AllocationStats BASE_EMBEDDED { | 
|  | 
| // Accessors for the allocation statistics. | 
| intptr_t Capacity() { return capacity_; } | 
| -  intptr_t MaxCapacity() { return max_capacity_; } | 
| intptr_t Size() { return size_; } | 
| +  intptr_t Committed() { return committed_; } | 
| +  intptr_t MaxCommitted() { return max_committed_; } | 
|  | 
| // Grow the space by adding available bytes.  They are initially marked as | 
| // being in use (part of the size), but will normally be immediately freed, | 
| @@ -1477,9 +1479,6 @@ class AllocationStats BASE_EMBEDDED { | 
| void ExpandSpace(int size_in_bytes) { | 
| capacity_ += size_in_bytes; | 
| size_ += size_in_bytes; | 
| -    if (capacity_ > max_capacity_) { | 
| -      max_capacity_ = capacity_; | 
| -    } | 
| DCHECK(size_ >= 0); | 
| } | 
|  | 
| @@ -1501,35 +1500,56 @@ class AllocationStats BASE_EMBEDDED { | 
| // Free allocated bytes, making them available (size -> available). | 
| void DeallocateBytes(intptr_t size_in_bytes) { | 
| size_ -= size_in_bytes; | 
| -    DCHECK(size_ >= 0); | 
| +    DCHECK_GE(size_, 0); | 
| } | 
|  | 
| // Merge {other} into {this}. | 
| void Merge(const AllocationStats& other) { | 
| capacity_ += other.capacity_; | 
| size_ += other.size_; | 
| -    if (other.max_capacity_ > max_capacity_) { | 
| -      max_capacity_ = other.max_capacity_; | 
| +    committed_ += other.committed_; | 
| +    if (committed_ > max_committed_) { | 
| +      max_committed_ = committed_; | 
| } | 
| } | 
|  | 
| void DecreaseCapacity(intptr_t size_in_bytes) { | 
| capacity_ -= size_in_bytes; | 
| DCHECK_GE(capacity_, 0); | 
| +    DCHECK_GE(capacity_, size_); | 
| } | 
|  | 
| void IncreaseCapacity(intptr_t size_in_bytes) { capacity_ += size_in_bytes; } | 
|  | 
| +  void CommitMemory(intptr_t size_in_bytes) { | 
| +    DCHECK_GE(size_in_bytes, 0); | 
| +    committed_ += size_in_bytes; | 
| +    if (committed_ > max_committed_) { | 
| +      max_committed_ = committed_; | 
| +    } | 
| +  } | 
| + | 
| +  void UncommitMemory(intptr_t size_in_bytes) { | 
| +    DCHECK_GE(size_in_bytes, 0); | 
| +    DCHECK_GE(committed_, size_in_bytes); | 
| +    committed_ -= size_in_bytes; | 
| +  } | 
| + | 
| private: | 
| // |capacity_|: The number of object-area bytes (i.e., not including page | 
| -  // bookkeeping structures) currently in the space. | 
| +  //   bookkeeping structures) currently in the space. | 
| intptr_t capacity_; | 
|  | 
| -  // |max_capacity_|: The maximum capacity ever observed. | 
| -  intptr_t max_capacity_; | 
| - | 
| // |size_|: The number of allocated bytes. | 
| intptr_t size_; | 
| + | 
| +  // |committed_|: The number of bytes committed in the corresponding space, | 
| +  //   including page headers. Note that committed memory does not need to | 
| +  //   be larger than capacity/size, as memory can be moved to other spaces. | 
| +  intptr_t committed_; | 
| + | 
| +  // |max_committed_|: The maximum number of bytes committed ever observed. | 
| +  intptr_t max_committed_; | 
| }; | 
|  | 
|  | 
| @@ -1630,6 +1650,10 @@ class FreeList { | 
| public: | 
| explicit FreeList(PagedSpace* owner); | 
|  | 
| +  // The method concatenates {other} into {this} and returns the added bytes, | 
| +  // including waste. | 
| +  // | 
| +  // Can be used concurrently. | 
| intptr_t Concatenate(FreeList* other); | 
|  | 
| // Clear the free list. | 
| @@ -1808,12 +1832,11 @@ class PagedSpace : public Space { | 
| // Current capacity without growing (Size() + Available()). | 
| intptr_t Capacity() { return accounting_stats_.Capacity(); } | 
|  | 
| -  // Total amount of memory committed for this space.  For paged | 
| -  // spaces this equals the capacity. | 
| -  intptr_t CommittedMemory() override { return Capacity(); } | 
| +  // Total amount of memory committed for this space. | 
| +  intptr_t CommittedMemory() override { return accounting_stats_.Committed(); } | 
|  | 
| // The maximum amount of memory ever committed for this space. | 
| -  intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); } | 
| +  intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCommitted(); } | 
|  | 
| // Approximate amount of physical memory committed for this space. | 
| size_t CommittedPhysicalMemory() override; | 
| @@ -1955,22 +1978,6 @@ class PagedSpace : public Space { | 
| !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && !p->WasSwept(); | 
| } | 
|  | 
| -  void IncrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ += by; } | 
| - | 
| -  void IncreaseUnsweptFreeBytes(Page* p) { | 
| -    DCHECK(ShouldBeSweptBySweeperThreads(p)); | 
| -    unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); | 
| -  } | 
| - | 
| -  void DecrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ -= by; } | 
| - | 
| -  void DecreaseUnsweptFreeBytes(Page* p) { | 
| -    DCHECK(ShouldBeSweptBySweeperThreads(p)); | 
| -    unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); | 
| -  } | 
| - | 
| -  void ResetUnsweptFreeBytes() { unswept_free_bytes_ = 0; } | 
| - | 
| // This function tries to steal size_in_bytes memory from the sweeper threads | 
| // free-lists. If it does not succeed stealing enough memory, it will wait | 
| // for the sweeper threads to finish sweeping. | 
| @@ -2053,10 +2060,6 @@ class PagedSpace : public Space { | 
| // Normal allocation information. | 
| AllocationInfo allocation_info_; | 
|  | 
| -  // The number of free bytes which could be reclaimed by advancing the | 
| -  // concurrent sweeper threads. | 
| -  intptr_t unswept_free_bytes_; | 
| - | 
| // The sweeper threads iterate over the list of pointer and data space pages | 
| // and sweep these pages concurrently. They will stop sweeping after the | 
| // end_of_unswept_pages_ page. | 
|  |