Index: src/spaces.h |
diff --git a/src/spaces.h b/src/spaces.h |
index e7b5a9bc45a1583c8272abacb53927ad2260b0b2..691e457b30265b1ce6ab4e5219c1d7753f39e88d 100644 |
--- a/src/spaces.h |
+++ b/src/spaces.h |
@@ -117,7 +117,7 @@ class PagedSpace; |
class MemoryAllocator; |
class AllocationInfo; |
class Space; |
-class OldSpaceFreeList; |
+class FreeList; |
// TODO(gc): Check that this all gets inlined and register allocated on |
@@ -390,6 +390,7 @@ class MemoryChunk { |
IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. |
IN_TO_SPACE, // All pages in new space has one of these two set. |
NEW_SPACE_BELOW_AGE_MARK, |
+ EVACUATION_CANDIDATE, |
NUM_MEMORY_CHUNK_FLAGS |
}; |
@@ -604,6 +605,19 @@ class Page : public MemoryChunk { |
void InitializeAsAnchor(PagedSpace* owner); |
+ bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } |
+ |
+ bool IsEvacuationCandidateOrNewSpace() { |
+ intptr_t mask = (1 << EVACUATION_CANDIDATE) | |
+ (1 << IN_FROM_SPACE) | |
+ (1 << IN_TO_SPACE); |
+ return (flags_ & mask) != 0; |
+ } |
+ |
+ void MarkEvacuationCandidate() { SetFlag(EVACUATION_CANDIDATE); } |
+ |
+ void ClearEvacuationCandidate() { ClearFlag(EVACUATION_CANDIDATE); } |
+ |
friend class MemoryAllocator; |
}; |
@@ -1172,9 +1186,9 @@ class FreeListNode: public HeapObject { |
// These spaces are call large. |
// At least 16384 words. This list is for objects of 2048 words or larger. |
// Empty pages are added to this list. These spaces are called huge. |
-class OldSpaceFreeList BASE_EMBEDDED { |
+class FreeList BASE_EMBEDDED { |
public: |
- explicit OldSpaceFreeList(PagedSpace* owner); |
+ explicit FreeList(PagedSpace* owner); |
// Clear the free list. |
void Reset(); |
@@ -1206,6 +1220,8 @@ class OldSpaceFreeList BASE_EMBEDDED { |
bool IsVeryLong(); |
#endif |
+ void CountFreeListItems(Page* p, intptr_t* sizes); |
+ |
private: |
// The size range of blocks, in bytes. |
static const int kMinBlockSize = 3 * kPointerSize; |
@@ -1229,7 +1245,7 @@ class OldSpaceFreeList BASE_EMBEDDED { |
FreeListNode* large_list_; |
FreeListNode* huge_list_; |
- DISALLOW_IMPLICIT_CONSTRUCTORS(OldSpaceFreeList); |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); |
}; |
@@ -1268,7 +1284,7 @@ class PagedSpace : public Space { |
MUST_USE_RESULT MaybeObject* FindObject(Address addr); |
// Prepares for a mark-compact GC. |
- virtual void PrepareForMarkCompact(bool will_compact); |
+ virtual void PrepareForMarkCompact(); |
// Current capacity without growing (Size() + Available()). |
intptr_t Capacity() { return accounting_stats_.Capacity(); } |
@@ -1402,6 +1418,31 @@ class PagedSpace : public Space { |
Page* FirstPage() { return anchor_.next_page(); } |
Page* LastPage() { return anchor_.prev_page(); } |
+ |
+ bool IsFragmented(Page* p) { |
+ intptr_t sizes[4]; |
+ free_list_.CountFreeListItems(p, sizes); |
+ |
+ intptr_t ratio = |
+ (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; |
+ |
+ if (FLAG_trace_fragmentation) { |
+ PrintF("%p: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", |
+ (void*) p, |
+ sizes[0], |
+ static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, |
+ sizes[1], |
+ static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, |
+ sizes[2], |
+ static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, |
+ sizes[3], |
+ static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, |
+ (ratio > 15) ? "[fragmented]" : ""); |
+ } |
+ |
+ return ratio > 15; |
+ } |
+ |
protected: |
// Maximum capacity of this space. |
intptr_t max_capacity_; |
@@ -1413,7 +1454,7 @@ class PagedSpace : public Space { |
Page anchor_; |
// The space's free list. |
- OldSpaceFreeList free_list_; |
+ FreeList free_list_; |
// Normal allocation information. |
AllocationInfo allocation_info_; |
@@ -2154,7 +2195,7 @@ class OldSpace : public PagedSpace { |
// Prepare for full garbage collection. Resets the relocation pointer and |
// clears the free list. |
- virtual void PrepareForMarkCompact(bool will_compact); |
+ virtual void PrepareForMarkCompact(); |
public: |
TRACK_MEMORY("OldSpace") |
@@ -2193,7 +2234,7 @@ class FixedSpace : public PagedSpace { |
int object_size_in_bytes() { return object_size_in_bytes_; } |
// Prepares for a mark-compact GC. |
- virtual void PrepareForMarkCompact(bool will_compact); |
+ virtual void PrepareForMarkCompact(); |
void MarkFreeListNodes() { free_list_.MarkNodes(); } |
@@ -2225,9 +2266,6 @@ class MapSpace : public FixedSpace { |
max_map_space_pages_(max_map_space_pages) { |
} |
- // Prepares for a mark-compact GC. |
- virtual void PrepareForMarkCompact(bool will_compact); |
- |
// Given an index, returns the page address. |
// TODO(gc): this limit is artifical just to keep code compilable |
static const int kMaxMapPageIndex = 1 << 16; |