Index: src/heap/spaces.h |
diff --git a/src/heap/spaces.h b/src/heap/spaces.h |
index 2cea06673abf136a0e3b013680e2cc6d59418e71..b4ead65b30008acdaebfcd58b3b637e6bad0fd5d 100644 |
--- a/src/heap/spaces.h |
+++ b/src/heap/spaces.h |
@@ -19,6 +19,7 @@ |
namespace v8 { |
namespace internal { |
+class CompactionSpaceCollection; |
class Isolate; |
// ----------------------------------------------------------------------------- |
@@ -1443,6 +1444,7 @@ class AllocationStats BASE_EMBEDDED { |
max_capacity_ = 0; |
size_ = 0; |
waste_ = 0; |
+ borrowed_ = 0; |
} |
void ClearSizeWaste() { |
@@ -1462,6 +1464,7 @@ class AllocationStats BASE_EMBEDDED { |
intptr_t MaxCapacity() { return max_capacity_; } |
intptr_t Size() { return size_; } |
intptr_t Waste() { return waste_; } |
+ intptr_t Borrowed() { return borrowed_; } |
// 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, |
@@ -1479,15 +1482,19 @@ class AllocationStats BASE_EMBEDDED { |
// during sweeping, bytes have been marked as being in use (part of the size) |
// and are hereby freed. |
void ShrinkSpace(int size_in_bytes) { |
+ DCHECK_GE(size_in_bytes, 0); |
capacity_ -= size_in_bytes; |
size_ -= size_in_bytes; |
- DCHECK(size_ >= 0); |
+ DCHECK_GE(size_, 0); |
+ DCHECK_GE(capacity_, 0); |
} |
// Allocate from available bytes (available -> size). |
void AllocateBytes(intptr_t size_in_bytes) { |
+ DCHECK_GE(size_in_bytes, 0); |
size_ += size_in_bytes; |
- DCHECK(size_ >= 0); |
+ DCHECK_GE(size_, 0); |
+ DCHECK_LE(size_, capacity_); |
} |
// Free allocated bytes, making them available (size -> available). |
@@ -1504,26 +1511,44 @@ class AllocationStats BASE_EMBEDDED { |
// Merge {other} into {this}. |
void Merge(const AllocationStats& other) { |
Hannes Payer (out of office)
2015/09/25 13:15:59
Why don't you reset the borrowed counter?
Michael Lippautz
2015/09/25 13:28:50
The caller needs to make sure that the counters ar
|
+ DCHECK_GE(other.capacity_, 0); |
+ DCHECK_GE(other.size_, 0); |
+ DCHECK_GE(other.waste_, 0); |
capacity_ += other.capacity_; |
size_ += other.size_; |
+ // Since borrowed memory is accounted as capacity by the space borrowing it, |
+ // we need to account for this when merging the stats. |
+ capacity_ -= other.borrowed_; |
Hannes Payer (out of office)
2015/09/25 13:15:59
Why do you subtract it from both? Can you explain
Michael Lippautz
2015/09/25 13:28:50
The reason is:
- The borrowed amount is accounted
Hannes Payer (out of office)
2015/09/25 14:11:07
This is really complicated. Can you make your comm
Michael Lippautz
2015/09/25 14:31:39
I added some more explanation to the actual member
|
+ size_ -= other.borrowed_; |
waste_ += other.waste_; |
- if (other.max_capacity_ > max_capacity_) { |
- max_capacity_ = other.max_capacity_; |
+ if (capacity_ > max_capacity_) { |
+ max_capacity_ = capacity_; |
} |
} |
void DecreaseCapacity(intptr_t size_in_bytes) { |
+ DCHECK_GE(size_in_bytes, 0); |
capacity_ -= size_in_bytes; |
DCHECK_GE(capacity_, 0); |
Hannes Payer (out of office)
2015/09/25 13:04:51
DCHECK_GE(capacity_, 0); is not needed.
Michael Lippautz
2015/09/25 13:28:50
Done.
|
+ DCHECK_GE(capacity_, size_); |
+ } |
+ |
+ void IncreaseCapacity(intptr_t size_in_bytes) { |
+ DCHECK_GE(size_in_bytes, 0); |
+ capacity_ += size_in_bytes; |
} |
- void IncreaseCapacity(intptr_t size_in_bytes) { capacity_ += size_in_bytes; } |
+ void BorrowMemory(intptr_t size_in_bytes) { |
+ DCHECK_GE(size_in_bytes, 0); |
+ borrowed_ += size_in_bytes; |
+ } |
private: |
intptr_t capacity_; |
Hannes Payer (out of office)
2015/09/25 13:04:51
Can you add comments that explain these variables?
Michael Lippautz
2015/09/25 13:28:50
The variables are explained on top of the class. S
Hannes Payer (out of office)
2015/09/25 14:11:07
No, that is fine. An explanation of borrowed_ is m
Michael Lippautz
2015/09/25 14:31:39
Changed my mind on this. I moved the descriptions
|
intptr_t max_capacity_; |
intptr_t size_; |
intptr_t waste_; |
+ intptr_t borrowed_; |
}; |
@@ -1682,6 +1707,8 @@ class FreeList { |
PagedSpace* owner() { return owner_; } |
private: |
+ enum FreeListCategoryType { kSmall, kMedium, kLarge, kHuge }; |
+ |
// The size range of blocks, in bytes. |
static const int kMinBlockSize = 3 * kPointerSize; |
static const int kMaxBlockSize = Page::kMaxRegularHeapObjectSize; |
@@ -1695,6 +1722,27 @@ class FreeList { |
static const int kLargeAllocationMax = kMediumListMax; |
FreeSpace* FindNodeFor(int size_in_bytes, int* node_size); |
+ FreeSpace* FindNodeIn(FreeListCategoryType category, int* node_size); |
+ |
+ FreeListCategory* GetFreeListCategory(FreeListCategoryType category) { |
+ switch (category) { |
+ case kSmall: |
+ return &small_list_; |
+ case kMedium: |
+ return &medium_list_; |
+ case kLarge: |
+ return &large_list_; |
+ case kHuge: |
+ return &huge_list_; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ UNREACHABLE(); |
+ return nullptr; |
+ } |
+ |
+ void UpdateFragmentationStats(FreeListCategoryType category, Address address, |
+ int size); |
PagedSpace* owner_; |
Heap* heap_; |
@@ -1703,6 +1751,8 @@ class FreeList { |
FreeListCategory large_list_; |
FreeListCategory huge_list_; |
+ friend class PagedSpace; |
+ |
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); |
}; |
@@ -1985,7 +2035,25 @@ class PagedSpace : public Space { |
virtual bool is_local() { return false; } |
+ // Divide {this} free lists up among {other} CompactionSpaceCollections |
+ // up to some certain {limit} of bytes. Note that this operation eventually |
+ // needs to iterate over nodes one-by-one, making it a potentially slow |
+ // operation. |
+ void DivideMemory(CompactionSpaceCollection** other, int num, intptr_t limit); |
+ |
protected: |
+ // Adds memory starting at {start} of {size_in_bytes} to the space. |
+ void AddMemory(Address start, int size_in_bytes) { |
+ IncreaseCapacity(size_in_bytes); |
+ accounting_stats_.BorrowMemory(size_in_bytes); |
+ Free(start, size_in_bytes); |
+ } |
+ |
+ // Tries to remove some memory from {this} free lists. We try to remove |
+ // as much memory as possible, i.e., we check the free lists from huge |
+ // to small. |
+ FreeSpace* TryRemoveMemory(); |
+ |
// PagedSpaces that should be included in snapshots have different, i.e., |
// smaller, initial pages. |
virtual bool snapshotable() { return true; } |
@@ -2741,12 +2809,6 @@ class CompactionSpace : public PagedSpace { |
CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) |
: PagedSpace(heap, id, executable) {} |
- // Adds external memory starting at {start} of {size_in_bytes} to the space. |
- void AddExternalMemory(Address start, int size_in_bytes) { |
- IncreaseCapacity(size_in_bytes); |
- Free(start, size_in_bytes); |
- } |
- |
virtual bool is_local() { return true; } |
protected: |