diff options
Diffstat (limited to 'deps/v8/src/spaces.h')
-rw-r--r-- | deps/v8/src/spaces.h | 152 |
1 files changed, 115 insertions, 37 deletions
diff --git a/deps/v8/src/spaces.h b/deps/v8/src/spaces.h index 6602c899df..56f629e02f 100644 --- a/deps/v8/src/spaces.h +++ b/deps/v8/src/spaces.h @@ -100,9 +100,6 @@ class Isolate; #define ASSERT_OBJECT_ALIGNED(address) \ ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0) -#define ASSERT_MAP_ALIGNED(address) \ - ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0) - #define ASSERT_OBJECT_SIZE(size) \ ASSERT((0 < size) && (size <= Page::kMaxNonCodeHeapObjectSize)) @@ -284,7 +281,9 @@ class Bitmap { bool IsClean() { for (int i = 0; i < CellsCount(); i++) { - if (cells()[i] != 0) return false; + if (cells()[i] != 0) { + return false; + } } return true; } @@ -373,6 +372,11 @@ class MemoryChunk { return addr >= area_start() && addr <= area_end(); } + // Every n write barrier invocations we go to runtime even though + // we could have handled it in generated code. This lets us check + // whether we have hit the limit and should do some more marking. + static const int kWriteBarrierCounterGranularity = 500; + enum MemoryChunkFlags { IS_EXECUTABLE, ABOUT_TO_BE_FREED, @@ -393,6 +397,12 @@ class MemoryChunk { WAS_SWEPT_PRECISELY, WAS_SWEPT_CONSERVATIVELY, + // Large objects can have a progress bar in their page header. These object + // are scanned in increments and will be kept black while being scanned. + // Even if the mutator writes to them they will be kept black and a white + // to grey transition is performed in the value. + HAS_PROGRESS_BAR, + // Last flag, keep at bottom. NUM_MEMORY_CHUNK_FLAGS }; @@ -468,6 +478,38 @@ class MemoryChunk { return live_byte_count_; } + int write_barrier_counter() { + return static_cast<int>(write_barrier_counter_); + } + + void set_write_barrier_counter(int counter) { + write_barrier_counter_ = counter; + } + + int progress_bar() { + ASSERT(IsFlagSet(HAS_PROGRESS_BAR)); + return progress_bar_; + } + + void set_progress_bar(int progress_bar) { + ASSERT(IsFlagSet(HAS_PROGRESS_BAR)); + progress_bar_ = progress_bar; + } + + void ResetProgressBar() { + if (IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { + set_progress_bar(0); + ClearFlag(MemoryChunk::HAS_PROGRESS_BAR); + } + } + + bool IsLeftOfProgressBar(Object** slot) { + Address slot_address = reinterpret_cast<Address>(slot); + ASSERT(slot_address > this->address()); + return (slot_address - (this->address() + kObjectStartOffset)) < + progress_bar(); + } + static void IncrementLiveBytesFromGC(Address address, int by) { MemoryChunk::FromAddress(address)->IncrementLiveBytes(by); } @@ -488,11 +530,14 @@ class MemoryChunk { static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; - static const size_t kHeaderSize = + static const size_t kWriteBarrierCounterOffset = kSlotsBufferOffset + kPointerSize + kPointerSize; + static const size_t kHeaderSize = + kWriteBarrierCounterOffset + kPointerSize + kIntSize + kIntSize; + static const int kBodyOffset = - CODE_POINTER_ALIGN(MAP_POINTER_ALIGN(kHeaderSize + Bitmap::kSize)); + CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); // The start offset of the object area in a page. Aligned to both maps and // code alignment to be suitable for both. Also aligned to 32 words because @@ -601,6 +646,13 @@ class MemoryChunk { return static_cast<int>(area_end() - area_start()); } + // Approximate amount of physical memory committed for this chunk. + size_t CommittedPhysicalMemory() { + return high_water_mark_; + } + + static inline void UpdateHighWaterMark(Address mark); + protected: MemoryChunk* next_chunk_; MemoryChunk* prev_chunk_; @@ -625,6 +677,13 @@ class MemoryChunk { int live_byte_count_; SlotsBuffer* slots_buffer_; SkipList* skip_list_; + intptr_t write_barrier_counter_; + // Used by the incremental marker to keep track of the scanning progress in + // large objects that have a progress bar and are scanned in increments. + int progress_bar_; + // Assuming the initial allocation on a page is sequential, + // count highest number of bytes ever allocated on the page. + int high_water_mark_; static MemoryChunk* Initialize(Heap* heap, Address base, @@ -790,14 +849,6 @@ class Space : public Malloced { virtual void Print() = 0; #endif - // After calling this we can allocate a certain number of bytes using only - // linear allocation (with a LinearAllocationScope and an AlwaysAllocateScope) - // without using freelists or causing a GC. This is used by partial - // snapshots. It returns true of space was reserved or false if a GC is - // needed. For paged spaces the space requested must include the space wasted - // at the end of each when allocating linearly. - virtual bool ReserveSpace(int bytes) = 0; - private: Heap* heap_; AllocationSpace id_; @@ -1318,6 +1369,11 @@ class FreeListNode: public HeapObject { inline void Zap(); + static inline FreeListNode* cast(MaybeObject* maybe) { + ASSERT(!maybe->IsFailure()); + return reinterpret_cast<FreeListNode*>(maybe); + } + private: static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); @@ -1380,6 +1436,9 @@ class FreeList BASE_EMBEDDED { bool IsVeryLong(); #endif + // Used after booting the VM. + void RepairLists(Heap* heap); + struct SizeStats { intptr_t Total() { return small_size_ + medium_size_ + large_size_ + huge_size_; @@ -1460,6 +1519,10 @@ class PagedSpace : public Space { // linear in the number of objects in the page. It may be slow. MUST_USE_RESULT MaybeObject* FindObject(Address addr); + // During boot the free_space_map is created, and afterwards we may need + // to write it into the free list nodes that were already created. + virtual void RepairFreeListsAfterBoot(); + // Prepares for a mark-compact GC. virtual void PrepareForMarkCompact(); @@ -1470,6 +1533,9 @@ class PagedSpace : public Space { // spaces this equals the capacity. intptr_t CommittedMemory() { return Capacity(); } + // Approximate amount of physical memory committed for this space. + size_t CommittedPhysicalMemory(); + // Sets the capacity, the available space and the wasted space to zero. // The stats are rebuilt during sweeping by adding each page to the // capacity and the size when it is encountered. As free spaces are @@ -1530,6 +1596,7 @@ class PagedSpace : public Space { void SetTop(Address top, Address limit) { ASSERT(top == limit || Page::FromAddress(top) == Page::FromAddress(limit - 1)); + MemoryChunk::UpdateHighWaterMark(allocation_info_.top); allocation_info_.top = top; allocation_info_.limit = limit; } @@ -1551,19 +1618,21 @@ class PagedSpace : public Space { // The dummy page that anchors the linked list of pages. Page* anchor() { return &anchor_; } -#ifdef DEBUG - // Print meta info and objects in this space. - virtual void Print(); - +#ifdef VERIFY_HEAP // Verify integrity of this space. virtual void Verify(ObjectVisitor* visitor); - // Reports statistics for the space - void ReportStatistics(); - // Overridden by subclasses to verify space-specific object // properties (e.g., only maps or free-list nodes are in map space). virtual void VerifyObject(HeapObject* obj) {} +#endif + +#ifdef DEBUG + // Print meta info and objects in this space. + virtual void Print(); + + // Reports statistics for the space + void ReportStatistics(); // Report code object related statistics void CollectCodeStatistics(); @@ -1911,9 +1980,12 @@ class SemiSpace : public Space { NewSpacePage* first_page() { return anchor_.next_page(); } NewSpacePage* current_page() { return current_page_; } +#ifdef VERIFY_HEAP + virtual void Verify(); +#endif + #ifdef DEBUG virtual void Print(); - virtual void Verify(); // Validate a range of of addresses in a SemiSpace. // The "from" address must be on a page prior to the "to" address, // in the linked page order, or it must be earlier on the same page. @@ -1936,6 +2008,9 @@ class SemiSpace : public Space { static void Swap(SemiSpace* from, SemiSpace* to); + // Approximate amount of physical memory committed for this space. + size_t CommittedPhysicalMemory(); + private: // Flips the semispace between being from-space and to-space. // Copies the flags into the masked positions on all pages in the space. @@ -2133,6 +2208,9 @@ class NewSpace : public Space { return Capacity(); } + // Approximate amount of physical memory committed for this space. + size_t CommittedPhysicalMemory(); + // Return the available bytes without growing. intptr_t Available() { return Capacity() - Size(); @@ -2238,9 +2316,12 @@ class NewSpace : public Space { template <typename StringType> inline void ShrinkStringAtAllocationBoundary(String* string, int len); -#ifdef DEBUG +#ifdef VERIFY_HEAP // Verify the active semispace. virtual void Verify(); +#endif + +#ifdef DEBUG // Print the active semispace. virtual void Print() { to_space_.Print(); } #endif @@ -2359,11 +2440,9 @@ class FixedSpace : public PagedSpace { FixedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, - int object_size_in_bytes, - const char* name) + int object_size_in_bytes) : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), - object_size_in_bytes_(object_size_in_bytes), - name_(name) { + object_size_in_bytes_(object_size_in_bytes) { page_extra_ = Page::kNonCodeObjectAreaSize % object_size_in_bytes; } @@ -2380,9 +2459,6 @@ class FixedSpace : public PagedSpace { private: // The size of objects in this space. int object_size_in_bytes_; - - // The name of this space. - const char* name_; }; @@ -2393,7 +2469,7 @@ class MapSpace : public FixedSpace { public: // Creates a map space object with a maximum capacity. MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) - : FixedSpace(heap, max_capacity, id, Map::kSize, "map"), + : FixedSpace(heap, max_capacity, id, Map::kSize), max_map_space_pages_(kMaxMapPageIndex - 1) { } @@ -2410,9 +2486,7 @@ class MapSpace : public FixedSpace { } protected: -#ifdef DEBUG virtual void VerifyObject(HeapObject* obj); -#endif private: static const int kMapsPerPage = Page::kNonCodeObjectAreaSize / Map::kSize; @@ -2436,7 +2510,7 @@ class CellSpace : public FixedSpace { public: // Creates a property cell space object with a maximum capacity. CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) - : FixedSpace(heap, max_capacity, id, JSGlobalPropertyCell::kSize, "cell") + : FixedSpace(heap, max_capacity, id, JSGlobalPropertyCell::kSize) {} virtual int RoundSizeDownToObjectAlignment(int size) { @@ -2448,9 +2522,7 @@ class CellSpace : public FixedSpace { } protected: -#ifdef DEBUG virtual void VerifyObject(HeapObject* obj); -#endif public: TRACK_MEMORY("CellSpace") @@ -2500,6 +2572,9 @@ class LargeObjectSpace : public Space { return Size(); } + // Approximate amount of physical memory committed for this space. + size_t CommittedPhysicalMemory(); + int PageCount() { return page_count_; } @@ -2529,8 +2604,11 @@ class LargeObjectSpace : public Space { LargePage* first_page() { return first_page_; } -#ifdef DEBUG +#ifdef VERIFY_HEAP virtual void Verify(); +#endif + +#ifdef DEBUG virtual void Print(); void ReportStatistics(); void CollectCodeStatistics(); |