| Index: src/heap/spaces.h
|
| diff --git a/src/heap/spaces.h b/src/heap/spaces.h
|
| index 5a57a30a30dd3a7d78fd3999d5a4556005725133..539df2543f56f6380583a2afd833f76110708cc0 100644
|
| --- a/src/heap/spaces.h
|
| +++ b/src/heap/spaces.h
|
| @@ -524,6 +524,8 @@ class MemoryChunk {
|
| !IsFlagSet(COMPACTION_WAS_ABORTED);
|
| }
|
|
|
| + bool CanUseForAllocation() { return CanAllocate() && !NeverEvacuate(); }
|
| +
|
| Executability executable() {
|
| return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
|
| }
|
| @@ -1610,28 +1612,28 @@ class AllocationStats BASE_EMBEDDED {
|
|
|
| // Zero out all the allocation statistics (i.e., no capacity).
|
| void Clear() {
|
| - capacity_ = 0;
|
| - max_capacity_ = 0;
|
| - size_ = 0;
|
| + capacity_.SetValue(0);
|
| + max_capacity_.SetValue(0);
|
| + size_.SetValue(0);
|
| }
|
|
|
| - void ClearSize() { size_ = capacity_; }
|
| + void ClearSize() { size_.SetValue(capacity_.Value()); }
|
|
|
| // Accessors for the allocation statistics.
|
| - size_t Capacity() { return capacity_; }
|
| - size_t MaxCapacity() { return max_capacity_; }
|
| - size_t Size() { return size_; }
|
| + size_t Capacity() { return capacity_.Value(); }
|
| + size_t MaxCapacity() { return max_capacity_.Value(); }
|
| + size_t Size() { return size_.Value(); }
|
|
|
| // 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,
|
| // putting them on the free list and removing them from size_.
|
| void ExpandSpace(size_t bytes) {
|
| - DCHECK_GE(size_ + bytes, size_);
|
| - DCHECK_GE(capacity_ + bytes, capacity_);
|
| - capacity_ += bytes;
|
| - size_ += bytes;
|
| - if (capacity_ > max_capacity_) {
|
| - max_capacity_ = capacity_;
|
| + DCHECK_GE(size_.Value() + bytes, size_.Value());
|
| + DCHECK_GE(capacity_.Value() + bytes, capacity_.Value());
|
| + capacity_.Increment(bytes);
|
| + size_.Increment(bytes);
|
| + if (capacity_.Value() > max_capacity_.Value()) {
|
| + max_capacity_.SetValue(capacity_.Value());
|
| }
|
| }
|
|
|
| @@ -1639,54 +1641,54 @@ class AllocationStats BASE_EMBEDDED {
|
| // during sweeping, bytes have been marked as being in use (part of the size)
|
| // and are hereby freed.
|
| void ShrinkSpace(size_t bytes) {
|
| - DCHECK_GE(capacity_, bytes);
|
| - DCHECK_GE(size_, bytes);
|
| - capacity_ -= bytes;
|
| - size_ -= bytes;
|
| + DCHECK_GE(capacity_.Value(), bytes);
|
| + DCHECK_GE(size_.Value(), bytes);
|
| + capacity_.Decrement(bytes);
|
| + size_.Decrement(bytes);
|
| }
|
|
|
| void AllocateBytes(size_t bytes) {
|
| - DCHECK_GE(size_ + bytes, size_);
|
| - size_ += bytes;
|
| + DCHECK_GE(size_.Value() + bytes, size_.Value());
|
| + size_.Increment(bytes);
|
| }
|
|
|
| void DeallocateBytes(size_t bytes) {
|
| - DCHECK_GE(size_, bytes);
|
| - size_ -= bytes;
|
| + DCHECK_GE(size_.Value(), bytes);
|
| + size_.Decrement(bytes);
|
| }
|
|
|
| void DecreaseCapacity(size_t bytes) {
|
| - DCHECK_GE(capacity_, bytes);
|
| - DCHECK_GE(capacity_ - bytes, size_);
|
| - capacity_ -= bytes;
|
| + DCHECK_GE(capacity_.Value(), bytes);
|
| + DCHECK_GE(capacity_.Value() - bytes, size_.Value());
|
| + capacity_.Decrement(bytes);
|
| }
|
|
|
| void IncreaseCapacity(size_t bytes) {
|
| - DCHECK_GE(capacity_ + bytes, capacity_);
|
| - capacity_ += bytes;
|
| + DCHECK_GE(capacity_.Value() + bytes, capacity_.Value());
|
| + capacity_.Increment(bytes);
|
| }
|
|
|
| // Merge |other| into |this|.
|
| void Merge(const AllocationStats& other) {
|
| - DCHECK_GE(capacity_ + other.capacity_, capacity_);
|
| - DCHECK_GE(size_ + other.size_, size_);
|
| - capacity_ += other.capacity_;
|
| - size_ += other.size_;
|
| - if (other.max_capacity_ > max_capacity_) {
|
| - max_capacity_ = other.max_capacity_;
|
| + DCHECK_GE(capacity_.Value() + other.capacity_.Value(), capacity_.Value());
|
| + DCHECK_GE(size_.Value() + other.size_.Value(), size_.Value());
|
| + capacity_.Increment(other.capacity_.Value());
|
| + size_.Increment(other.size_.Value());
|
| + if (other.max_capacity_.Value() > max_capacity_.Value()) {
|
| + max_capacity_.SetValue(other.max_capacity_.Value());
|
| }
|
| }
|
|
|
| private:
|
| // |capacity_|: The number of object-area bytes (i.e., not including page
|
| // bookkeeping structures) currently in the space.
|
| - size_t capacity_;
|
| + base::AtomicNumber<size_t> capacity_;
|
|
|
| // |max_capacity_|: The maximum capacity ever observed.
|
| - size_t max_capacity_;
|
| + base::AtomicNumber<size_t> max_capacity_;
|
|
|
| // |size_|: The number of allocated bytes.
|
| - size_t size_;
|
| + base::AtomicNumber<size_t> size_;
|
| };
|
|
|
| // A free list maintaining free blocks of memory. The free list is organized in
|
| @@ -1952,6 +1954,10 @@ class V8_EXPORT_PRIVATE PagedSpace : NON_EXPORTED_BASE(public Space) {
|
| public:
|
| typedef PageIterator iterator;
|
|
|
| + // Reuse a page for allocation only if it has at least {kPageReuseThreshold}
|
| + // memory available in its FreeList.
|
| + static const size_t kPageReuseThreshold = 4 * KB;
|
| +
|
| static const intptr_t kCompactionMemoryWanted = 500 * KB;
|
|
|
| // Creates a space with an id.
|
| @@ -2158,6 +2164,9 @@ class V8_EXPORT_PRIVATE PagedSpace : NON_EXPORTED_BASE(public Space) {
|
|
|
| std::unique_ptr<ObjectIterator> GetObjectIterator() override;
|
|
|
| + Page* RemovePageSafe();
|
| + void AddPage(Page* page);
|
| +
|
| protected:
|
| // PagedSpaces that should be included in snapshots have different, i.e.,
|
| // smaller, initial pages.
|
|
|