Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Side by Side Diff: src/heap/spaces.h

Issue 1023443004: Version 4.3.48.1 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.3.48
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact-inl.h ('k') | src/heap/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HEAP_SPACES_H_ 5 #ifndef V8_HEAP_SPACES_H_
6 #define V8_HEAP_SPACES_H_ 6 #define V8_HEAP_SPACES_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/base/atomicops.h" 9 #include "src/base/atomicops.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 25 matching lines...) Expand all
36 // There is a separate large object space for objects larger than 36 // There is a separate large object space for objects larger than
37 // Page::kMaxHeapObjectSize, so that they do not have to move during 37 // Page::kMaxHeapObjectSize, so that they do not have to move during
38 // collection. The large object space is paged. Pages in large object space 38 // collection. The large object space is paged. Pages in large object space
39 // may be larger than the page size. 39 // may be larger than the page size.
40 // 40 //
41 // A store-buffer based write barrier is used to keep track of intergenerational 41 // A store-buffer based write barrier is used to keep track of intergenerational
42 // references. See heap/store-buffer.h. 42 // references. See heap/store-buffer.h.
43 // 43 //
44 // During scavenges and mark-sweep collections we sometimes (after a store 44 // During scavenges and mark-sweep collections we sometimes (after a store
45 // buffer overflow) iterate intergenerational pointers without decoding heap 45 // buffer overflow) iterate intergenerational pointers without decoding heap
46 // object maps so if the page belongs to old space or large object space 46 // object maps so if the page belongs to old pointer space or large object
47 // it is essential to guarantee that the page does not contain any 47 // space it is essential to guarantee that the page does not contain any
48 // garbage pointers to new space: every pointer aligned word which satisfies 48 // garbage pointers to new space: every pointer aligned word which satisfies
49 // the Heap::InNewSpace() predicate must be a pointer to a live heap object in 49 // the Heap::InNewSpace() predicate must be a pointer to a live heap object in
50 // new space. Thus objects in old space and large object spaces should have a 50 // new space. Thus objects in old pointer and large object spaces should have a
51 // special layout (e.g. no bare integer fields). This requirement does not 51 // special layout (e.g. no bare integer fields). This requirement does not
52 // apply to map space which is iterated in a special fashion. However we still 52 // apply to map space which is iterated in a special fashion. However we still
53 // require pointer fields of dead maps to be cleaned. 53 // require pointer fields of dead maps to be cleaned.
54 // 54 //
55 // To enable lazy cleaning of old space pages we can mark chunks of the page 55 // To enable lazy cleaning of old space pages we can mark chunks of the page
56 // as being garbage. Garbage sections are marked with a special map. These 56 // as being garbage. Garbage sections are marked with a special map. These
57 // sections are skipped when scanning the page, even if we are otherwise 57 // sections are skipped when scanning the page, even if we are otherwise
58 // scanning without regard for object boundaries. Garbage sections are chained 58 // scanning without regard for object boundaries. Garbage sections are chained
59 // together to form a free list after a GC. Garbage sections created outside 59 // together to form a free list after a GC. Garbage sections created outside
60 // of GCs by object trunctation etc. may not be in the free list chain. Very 60 // of GCs by object trunctation etc. may not be in the free list chain. Very
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 class MemoryAllocator; 95 class MemoryAllocator;
96 class AllocationInfo; 96 class AllocationInfo;
97 class Space; 97 class Space;
98 class FreeList; 98 class FreeList;
99 class MemoryChunk; 99 class MemoryChunk;
100 100
101 class MarkBit { 101 class MarkBit {
102 public: 102 public:
103 typedef uint32_t CellType; 103 typedef uint32_t CellType;
104 104
105 inline MarkBit(CellType* cell, CellType mask) : cell_(cell), mask_(mask) {} 105 inline MarkBit(CellType* cell, CellType mask, bool data_only)
106 : cell_(cell), mask_(mask), data_only_(data_only) {}
106 107
107 inline CellType* cell() { return cell_; } 108 inline CellType* cell() { return cell_; }
108 inline CellType mask() { return mask_; } 109 inline CellType mask() { return mask_; }
109 110
110 #ifdef DEBUG 111 #ifdef DEBUG
111 bool operator==(const MarkBit& other) { 112 bool operator==(const MarkBit& other) {
112 return cell_ == other.cell_ && mask_ == other.mask_; 113 return cell_ == other.cell_ && mask_ == other.mask_;
113 } 114 }
114 #endif 115 #endif
115 116
116 inline void Set() { *cell_ |= mask_; } 117 inline void Set() { *cell_ |= mask_; }
117 inline bool Get() { return (*cell_ & mask_) != 0; } 118 inline bool Get() { return (*cell_ & mask_) != 0; }
118 inline void Clear() { *cell_ &= ~mask_; } 119 inline void Clear() { *cell_ &= ~mask_; }
119 120
121 inline bool data_only() { return data_only_; }
120 122
121 inline MarkBit Next() { 123 inline MarkBit Next() {
122 CellType new_mask = mask_ << 1; 124 CellType new_mask = mask_ << 1;
123 if (new_mask == 0) { 125 if (new_mask == 0) {
124 return MarkBit(cell_ + 1, 1); 126 return MarkBit(cell_ + 1, 1, data_only_);
125 } else { 127 } else {
126 return MarkBit(cell_, new_mask); 128 return MarkBit(cell_, new_mask, data_only_);
127 } 129 }
128 } 130 }
129 131
130 private: 132 private:
131 CellType* cell_; 133 CellType* cell_;
132 CellType mask_; 134 CellType mask_;
135 // This boolean indicates that the object is in a data-only space with no
136 // pointers. This enables some optimizations when marking.
137 // It is expected that this field is inlined and turned into control flow
138 // at the place where the MarkBit object is created.
139 bool data_only_;
133 }; 140 };
134 141
135 142
136 // Bitmap is a sequence of cells each containing fixed number of bits. 143 // Bitmap is a sequence of cells each containing fixed number of bits.
137 class Bitmap { 144 class Bitmap {
138 public: 145 public:
139 static const uint32_t kBitsPerCell = 32; 146 static const uint32_t kBitsPerCell = 32;
140 static const uint32_t kBitsPerCellLog2 = 5; 147 static const uint32_t kBitsPerCellLog2 = 5;
141 static const uint32_t kBitIndexMask = kBitsPerCell - 1; 148 static const uint32_t kBitIndexMask = kBitsPerCell - 1;
142 static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte; 149 static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte;
(...skipping 30 matching lines...) Expand all
173 INLINE(MarkBit::CellType* cells()) { 180 INLINE(MarkBit::CellType* cells()) {
174 return reinterpret_cast<MarkBit::CellType*>(this); 181 return reinterpret_cast<MarkBit::CellType*>(this);
175 } 182 }
176 183
177 INLINE(Address address()) { return reinterpret_cast<Address>(this); } 184 INLINE(Address address()) { return reinterpret_cast<Address>(this); }
178 185
179 INLINE(static Bitmap* FromAddress(Address addr)) { 186 INLINE(static Bitmap* FromAddress(Address addr)) {
180 return reinterpret_cast<Bitmap*>(addr); 187 return reinterpret_cast<Bitmap*>(addr);
181 } 188 }
182 189
183 inline MarkBit MarkBitFromIndex(uint32_t index) { 190 inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) {
184 MarkBit::CellType mask = 1 << (index & kBitIndexMask); 191 MarkBit::CellType mask = 1 << (index & kBitIndexMask);
185 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); 192 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2);
186 return MarkBit(cell, mask); 193 return MarkBit(cell, mask, data_only);
187 } 194 }
188 195
189 static inline void Clear(MemoryChunk* chunk); 196 static inline void Clear(MemoryChunk* chunk);
190 197
191 static void PrintWord(uint32_t word, uint32_t himask = 0) { 198 static void PrintWord(uint32_t word, uint32_t himask = 0) {
192 for (uint32_t mask = 1; mask != 0; mask <<= 1) { 199 for (uint32_t mask = 1; mask != 0; mask <<= 1) {
193 if ((mask & himask) != 0) PrintF("["); 200 if ((mask & himask) != 0) PrintF("[");
194 PrintF((mask & word) ? "1" : "0"); 201 PrintF((mask & word) ? "1" : "0");
195 if ((mask & himask) != 0) PrintF("]"); 202 if ((mask & himask) != 0) PrintF("]");
196 } 203 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 363
357 enum MemoryChunkFlags { 364 enum MemoryChunkFlags {
358 IS_EXECUTABLE, 365 IS_EXECUTABLE,
359 ABOUT_TO_BE_FREED, 366 ABOUT_TO_BE_FREED,
360 POINTERS_TO_HERE_ARE_INTERESTING, 367 POINTERS_TO_HERE_ARE_INTERESTING,
361 POINTERS_FROM_HERE_ARE_INTERESTING, 368 POINTERS_FROM_HERE_ARE_INTERESTING,
362 SCAN_ON_SCAVENGE, 369 SCAN_ON_SCAVENGE,
363 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. 370 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE.
364 IN_TO_SPACE, // All pages in new space has one of these two set. 371 IN_TO_SPACE, // All pages in new space has one of these two set.
365 NEW_SPACE_BELOW_AGE_MARK, 372 NEW_SPACE_BELOW_AGE_MARK,
373 CONTAINS_ONLY_DATA,
366 EVACUATION_CANDIDATE, 374 EVACUATION_CANDIDATE,
367 RESCAN_ON_EVACUATION, 375 RESCAN_ON_EVACUATION,
368 NEVER_EVACUATE, // May contain immortal immutables. 376 NEVER_EVACUATE, // May contain immortal immutables.
369 377
370 // WAS_SWEPT indicates that marking bits have been cleared by the sweeper, 378 // WAS_SWEPT indicates that marking bits have been cleared by the sweeper,
371 // otherwise marking bits are still intact. 379 // otherwise marking bits are still intact.
372 WAS_SWEPT, 380 WAS_SWEPT,
373 381
374 // Large objects can have a progress bar in their page header. These object 382 // Large objects can have a progress bar in their page header. These object
375 // are scanned in increments and will be kept black while being scanned. 383 // are scanned in increments and will be kept black while being scanned.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 558
551 void SetArea(Address area_start, Address area_end) { 559 void SetArea(Address area_start, Address area_end) {
552 area_start_ = area_start; 560 area_start_ = area_start;
553 area_end_ = area_end; 561 area_end_ = area_end;
554 } 562 }
555 563
556 Executability executable() { 564 Executability executable() {
557 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 565 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
558 } 566 }
559 567
568 bool ContainsOnlyData() { return IsFlagSet(CONTAINS_ONLY_DATA); }
569
560 bool InNewSpace() { 570 bool InNewSpace() {
561 return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0; 571 return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0;
562 } 572 }
563 573
564 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); } 574 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); }
565 575
566 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); } 576 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); }
567 577
568 // --------------------------------------------------------------------- 578 // ---------------------------------------------------------------------
569 // Markbits support 579 // Markbits support
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
2579 MUST_USE_RESULT AllocationResult SlowAllocateRaw(int size_in_bytes); 2589 MUST_USE_RESULT AllocationResult SlowAllocateRaw(int size_in_bytes);
2580 2590
2581 friend class SemiSpaceIterator; 2591 friend class SemiSpaceIterator;
2582 2592
2583 public: 2593 public:
2584 TRACK_MEMORY("NewSpace") 2594 TRACK_MEMORY("NewSpace")
2585 }; 2595 };
2586 2596
2587 2597
2588 // ----------------------------------------------------------------------------- 2598 // -----------------------------------------------------------------------------
2589 // Old object space (includes the old space of objects and code space) 2599 // Old object space (excluding map objects)
2590 2600
2591 class OldSpace : public PagedSpace { 2601 class OldSpace : public PagedSpace {
2592 public: 2602 public:
2593 // Creates an old space object with a given maximum capacity. 2603 // Creates an old space object with a given maximum capacity.
2594 // The constructor does not allocate pages from OS. 2604 // The constructor does not allocate pages from OS.
2595 OldSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id, 2605 OldSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id,
2596 Executability executable) 2606 Executability executable)
2597 : PagedSpace(heap, max_capacity, id, executable) {} 2607 : PagedSpace(heap, max_capacity, id, executable) {}
2598 2608
2599 public: 2609 public:
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 2798
2789 // Iterates over the chunks (pages and large object pages) that can contain 2799 // Iterates over the chunks (pages and large object pages) that can contain
2790 // pointers to new space. 2800 // pointers to new space.
2791 class PointerChunkIterator BASE_EMBEDDED { 2801 class PointerChunkIterator BASE_EMBEDDED {
2792 public: 2802 public:
2793 inline explicit PointerChunkIterator(Heap* heap); 2803 inline explicit PointerChunkIterator(Heap* heap);
2794 2804
2795 // Return NULL when the iterator is done. 2805 // Return NULL when the iterator is done.
2796 MemoryChunk* next() { 2806 MemoryChunk* next() {
2797 switch (state_) { 2807 switch (state_) {
2798 case kOldSpaceState: { 2808 case kOldPointerState: {
2799 if (old_pointer_iterator_.has_next()) { 2809 if (old_pointer_iterator_.has_next()) {
2800 return old_pointer_iterator_.next(); 2810 return old_pointer_iterator_.next();
2801 } 2811 }
2802 state_ = kMapState; 2812 state_ = kMapState;
2803 // Fall through. 2813 // Fall through.
2804 } 2814 }
2805 case kMapState: { 2815 case kMapState: {
2806 if (map_iterator_.has_next()) { 2816 if (map_iterator_.has_next()) {
2807 return map_iterator_.next(); 2817 return map_iterator_.next();
2808 } 2818 }
(...skipping 18 matching lines...) Expand all
2827 return NULL; 2837 return NULL;
2828 default: 2838 default:
2829 break; 2839 break;
2830 } 2840 }
2831 UNREACHABLE(); 2841 UNREACHABLE();
2832 return NULL; 2842 return NULL;
2833 } 2843 }
2834 2844
2835 2845
2836 private: 2846 private:
2837 enum State { kOldSpaceState, kMapState, kLargeObjectState, kFinishedState }; 2847 enum State { kOldPointerState, kMapState, kLargeObjectState, kFinishedState };
2838 State state_; 2848 State state_;
2839 PageIterator old_pointer_iterator_; 2849 PageIterator old_pointer_iterator_;
2840 PageIterator map_iterator_; 2850 PageIterator map_iterator_;
2841 LargeObjectIterator lo_iterator_; 2851 LargeObjectIterator lo_iterator_;
2842 }; 2852 };
2843 2853
2844 2854
2845 #ifdef DEBUG 2855 #ifdef DEBUG
2846 struct CommentStatistic { 2856 struct CommentStatistic {
2847 const char* comment; 2857 const char* comment;
2848 int size; 2858 int size;
2849 int count; 2859 int count;
2850 void Clear() { 2860 void Clear() {
2851 comment = NULL; 2861 comment = NULL;
2852 size = 0; 2862 size = 0;
2853 count = 0; 2863 count = 0;
2854 } 2864 }
2855 // Must be small, since an iteration is used for lookup. 2865 // Must be small, since an iteration is used for lookup.
2856 static const int kMaxComments = 64; 2866 static const int kMaxComments = 64;
2857 }; 2867 };
2858 #endif 2868 #endif
2859 } 2869 }
2860 } // namespace v8::internal 2870 } // namespace v8::internal
2861 2871
2862 #endif // V8_HEAP_SPACES_H_ 2872 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/mark-compact-inl.h ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698