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

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

Issue 437993003: Move a bunch of GC related files to heap/ subdirectory (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: make presubmit happy Created 6 years, 4 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 | Annotate | Revision Log
« 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_SPACES_H_ 5 #ifndef V8_HEAP_SPACES_H_
6 #define V8_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/platform/mutex.h" 10 #include "src/base/platform/mutex.h"
11 #include "src/hashmap.h" 11 #include "src/hashmap.h"
12 #include "src/list.h" 12 #include "src/list.h"
13 #include "src/log.h" 13 #include "src/log.h"
14 #include "src/utils.h" 14 #include "src/utils.h"
15 15
16 namespace v8 { 16 namespace v8 {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 // is to enable linear allocation without having to constantly update the byte 67 // is to enable linear allocation without having to constantly update the byte
68 // array every time the top field is updated and a new object is created. The 68 // array every time the top field is updated and a new object is created. The
69 // special garbage section is not in the chain of garbage sections. 69 // special garbage section is not in the chain of garbage sections.
70 // 70 //
71 // Since the top and limit fields are in the space, not the page, only one page 71 // Since the top and limit fields are in the space, not the page, only one page
72 // has a special garbage section, and if the top and limit are equal then there 72 // has a special garbage section, and if the top and limit are equal then there
73 // is no special garbage section. 73 // is no special garbage section.
74 74
75 // Some assertion macros used in the debugging mode. 75 // Some assertion macros used in the debugging mode.
76 76
77 #define DCHECK_PAGE_ALIGNED(address) \ 77 #define DCHECK_PAGE_ALIGNED(address) \
78 DCHECK((OffsetFrom(address) & Page::kPageAlignmentMask) == 0) 78 DCHECK((OffsetFrom(address) & Page::kPageAlignmentMask) == 0)
79 79
80 #define DCHECK_OBJECT_ALIGNED(address) \ 80 #define DCHECK_OBJECT_ALIGNED(address) \
81 DCHECK((OffsetFrom(address) & kObjectAlignmentMask) == 0) 81 DCHECK((OffsetFrom(address) & kObjectAlignmentMask) == 0)
82 82
83 #define DCHECK_OBJECT_SIZE(size) \ 83 #define DCHECK_OBJECT_SIZE(size) \
84 DCHECK((0 < size) && (size <= Page::kMaxRegularHeapObjectSize)) 84 DCHECK((0 < size) && (size <= Page::kMaxRegularHeapObjectSize))
85 85
86 #define DCHECK_PAGE_OFFSET(offset) \ 86 #define DCHECK_PAGE_OFFSET(offset) \
87 DCHECK((Page::kObjectStartOffset <= offset) \ 87 DCHECK((Page::kObjectStartOffset <= offset) && (offset <= Page::kPageSize))
88 && (offset <= Page::kPageSize))
89 88
90 #define DCHECK_MAP_PAGE_INDEX(index) \ 89 #define DCHECK_MAP_PAGE_INDEX(index) \
91 DCHECK((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) 90 DCHECK((0 <= index) && (index <= MapSpace::kMaxMapPageIndex))
92 91
93 92
94 class PagedSpace; 93 class PagedSpace;
95 class MemoryAllocator; 94 class MemoryAllocator;
96 class AllocationInfo; 95 class AllocationInfo;
97 class Space; 96 class Space;
98 class FreeList; 97 class FreeList;
99 class MemoryChunk; 98 class MemoryChunk;
100 99
101 class MarkBit { 100 class MarkBit {
102 public: 101 public:
103 typedef uint32_t CellType; 102 typedef uint32_t CellType;
104 103
105 inline MarkBit(CellType* cell, CellType mask, bool data_only) 104 inline MarkBit(CellType* cell, CellType mask, bool data_only)
106 : cell_(cell), mask_(mask), data_only_(data_only) { } 105 : cell_(cell), mask_(mask), data_only_(data_only) {}
107 106
108 inline CellType* cell() { return cell_; } 107 inline CellType* cell() { return cell_; }
109 inline CellType mask() { return mask_; } 108 inline CellType mask() { return mask_; }
110 109
111 #ifdef DEBUG 110 #ifdef DEBUG
112 bool operator==(const MarkBit& other) { 111 bool operator==(const MarkBit& other) {
113 return cell_ == other.cell_ && mask_ == other.mask_; 112 return cell_ == other.cell_ && mask_ == other.mask_;
114 } 113 }
115 #endif 114 #endif
116 115
(...skipping 25 matching lines...) Expand all
142 141
143 // Bitmap is a sequence of cells each containing fixed number of bits. 142 // Bitmap is a sequence of cells each containing fixed number of bits.
144 class Bitmap { 143 class Bitmap {
145 public: 144 public:
146 static const uint32_t kBitsPerCell = 32; 145 static const uint32_t kBitsPerCell = 32;
147 static const uint32_t kBitsPerCellLog2 = 5; 146 static const uint32_t kBitsPerCellLog2 = 5;
148 static const uint32_t kBitIndexMask = kBitsPerCell - 1; 147 static const uint32_t kBitIndexMask = kBitsPerCell - 1;
149 static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte; 148 static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte;
150 static const uint32_t kBytesPerCellLog2 = kBitsPerCellLog2 - kBitsPerByteLog2; 149 static const uint32_t kBytesPerCellLog2 = kBitsPerCellLog2 - kBitsPerByteLog2;
151 150
152 static const size_t kLength = 151 static const size_t kLength = (1 << kPageSizeBits) >> (kPointerSizeLog2);
153 (1 << kPageSizeBits) >> (kPointerSizeLog2);
154 152
155 static const size_t kSize = 153 static const size_t kSize =
156 (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2); 154 (1 << kPageSizeBits) >> (kPointerSizeLog2 + kBitsPerByteLog2);
157 155
158 156
159 static int CellsForLength(int length) { 157 static int CellsForLength(int length) {
160 return (length + kBitsPerCell - 1) >> kBitsPerCellLog2; 158 return (length + kBitsPerCell - 1) >> kBitsPerCellLog2;
161 } 159 }
162 160
163 int CellsCount() { 161 int CellsCount() { return CellsForLength(kLength); }
164 return CellsForLength(kLength);
165 }
166 162
167 static int SizeFor(int cells_count) { 163 static int SizeFor(int cells_count) {
168 return sizeof(MarkBit::CellType) * cells_count; 164 return sizeof(MarkBit::CellType) * cells_count;
169 } 165 }
170 166
171 INLINE(static uint32_t IndexToCell(uint32_t index)) { 167 INLINE(static uint32_t IndexToCell(uint32_t index)) {
172 return index >> kBitsPerCellLog2; 168 return index >> kBitsPerCellLog2;
173 } 169 }
174 170
175 INLINE(static uint32_t CellToIndex(uint32_t index)) { 171 INLINE(static uint32_t CellToIndex(uint32_t index)) {
176 return index << kBitsPerCellLog2; 172 return index << kBitsPerCellLog2;
177 } 173 }
178 174
179 INLINE(static uint32_t CellAlignIndex(uint32_t index)) { 175 INLINE(static uint32_t CellAlignIndex(uint32_t index)) {
180 return (index + kBitIndexMask) & ~kBitIndexMask; 176 return (index + kBitIndexMask) & ~kBitIndexMask;
181 } 177 }
182 178
183 INLINE(MarkBit::CellType* cells()) { 179 INLINE(MarkBit::CellType* cells()) {
184 return reinterpret_cast<MarkBit::CellType*>(this); 180 return reinterpret_cast<MarkBit::CellType*>(this);
185 } 181 }
186 182
187 INLINE(Address address()) { 183 INLINE(Address address()) { return reinterpret_cast<Address>(this); }
188 return reinterpret_cast<Address>(this);
189 }
190 184
191 INLINE(static Bitmap* FromAddress(Address addr)) { 185 INLINE(static Bitmap* FromAddress(Address addr)) {
192 return reinterpret_cast<Bitmap*>(addr); 186 return reinterpret_cast<Bitmap*>(addr);
193 } 187 }
194 188
195 inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) { 189 inline MarkBit MarkBitFromIndex(uint32_t index, bool data_only = false) {
196 MarkBit::CellType mask = 1 << (index & kBitIndexMask); 190 MarkBit::CellType mask = 1 << (index & kBitIndexMask);
197 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2); 191 MarkBit::CellType* cell = this->cells() + (index >> kBitsPerCellLog2);
198 return MarkBit(cell, mask, data_only); 192 return MarkBit(cell, mask, data_only);
199 } 193 }
200 194
201 static inline void Clear(MemoryChunk* chunk); 195 static inline void Clear(MemoryChunk* chunk);
202 196
203 static void PrintWord(uint32_t word, uint32_t himask = 0) { 197 static void PrintWord(uint32_t word, uint32_t himask = 0) {
204 for (uint32_t mask = 1; mask != 0; mask <<= 1) { 198 for (uint32_t mask = 1; mask != 0; mask <<= 1) {
205 if ((mask & himask) != 0) PrintF("["); 199 if ((mask & himask) != 0) PrintF("[");
206 PrintF((mask & word) ? "1" : "0"); 200 PrintF((mask & word) ? "1" : "0");
207 if ((mask & himask) != 0) PrintF("]"); 201 if ((mask & himask) != 0) PrintF("]");
208 } 202 }
209 } 203 }
210 204
211 class CellPrinter { 205 class CellPrinter {
212 public: 206 public:
213 CellPrinter() : seq_start(0), seq_type(0), seq_length(0) { } 207 CellPrinter() : seq_start(0), seq_type(0), seq_length(0) {}
214 208
215 void Print(uint32_t pos, uint32_t cell) { 209 void Print(uint32_t pos, uint32_t cell) {
216 if (cell == seq_type) { 210 if (cell == seq_type) {
217 seq_length++; 211 seq_length++;
218 return; 212 return;
219 } 213 }
220 214
221 Flush(); 215 Flush();
222 216
223 if (IsSeq(cell)) { 217 if (IsSeq(cell)) {
224 seq_start = pos; 218 seq_start = pos;
225 seq_length = 0; 219 seq_length = 0;
226 seq_type = cell; 220 seq_type = cell;
227 return; 221 return;
228 } 222 }
229 223
230 PrintF("%d: ", pos); 224 PrintF("%d: ", pos);
231 PrintWord(cell); 225 PrintWord(cell);
232 PrintF("\n"); 226 PrintF("\n");
233 } 227 }
234 228
235 void Flush() { 229 void Flush() {
236 if (seq_length > 0) { 230 if (seq_length > 0) {
237 PrintF("%d: %dx%d\n", 231 PrintF("%d: %dx%d\n", seq_start, seq_type == 0 ? 0 : 1,
238 seq_start,
239 seq_type == 0 ? 0 : 1,
240 seq_length * kBitsPerCell); 232 seq_length * kBitsPerCell);
241 seq_length = 0; 233 seq_length = 0;
242 } 234 }
243 } 235 }
244 236
245 static bool IsSeq(uint32_t cell) { return cell == 0 || cell == 0xFFFFFFFF; } 237 static bool IsSeq(uint32_t cell) { return cell == 0 || cell == 0xFFFFFFFF; }
246 238
247 private: 239 private:
248 uint32_t seq_start; 240 uint32_t seq_start;
249 uint32_t seq_type; 241 uint32_t seq_type;
(...skipping 27 matching lines...) Expand all
277 // It is divided into the header and the body. Chunk start is always 269 // It is divided into the header and the body. Chunk start is always
278 // 1MB aligned. Start of the body is aligned so it can accommodate 270 // 1MB aligned. Start of the body is aligned so it can accommodate
279 // any heap object. 271 // any heap object.
280 class MemoryChunk { 272 class MemoryChunk {
281 public: 273 public:
282 // Only works if the pointer is in the first kPageSize of the MemoryChunk. 274 // Only works if the pointer is in the first kPageSize of the MemoryChunk.
283 static MemoryChunk* FromAddress(Address a) { 275 static MemoryChunk* FromAddress(Address a) {
284 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); 276 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask);
285 } 277 }
286 static const MemoryChunk* FromAddress(const byte* a) { 278 static const MemoryChunk* FromAddress(const byte* a) {
287 return reinterpret_cast<const MemoryChunk*>( 279 return reinterpret_cast<const MemoryChunk*>(OffsetFrom(a) &
288 OffsetFrom(a) & ~kAlignmentMask); 280 ~kAlignmentMask);
289 } 281 }
290 282
291 // Only works for addresses in pointer spaces, not data or code spaces. 283 // Only works for addresses in pointer spaces, not data or code spaces.
292 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); 284 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr);
293 285
294 Address address() { return reinterpret_cast<Address>(this); } 286 Address address() { return reinterpret_cast<Address>(this); }
295 287
296 bool is_valid() { return address() != NULL; } 288 bool is_valid() { return address() != NULL; }
297 289
298 MemoryChunk* next_chunk() const { 290 MemoryChunk* next_chunk() const {
(...skipping 22 matching lines...) Expand all
321 } 313 }
322 } 314 }
323 315
324 void set_owner(Space* space) { 316 void set_owner(Space* space) {
325 DCHECK((reinterpret_cast<intptr_t>(space) & kPageHeaderTagMask) == 0); 317 DCHECK((reinterpret_cast<intptr_t>(space) & kPageHeaderTagMask) == 0);
326 owner_ = reinterpret_cast<Address>(space) + kPageHeaderTag; 318 owner_ = reinterpret_cast<Address>(space) + kPageHeaderTag;
327 DCHECK((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) == 319 DCHECK((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) ==
328 kPageHeaderTag); 320 kPageHeaderTag);
329 } 321 }
330 322
331 base::VirtualMemory* reserved_memory() { 323 base::VirtualMemory* reserved_memory() { return &reservation_; }
332 return &reservation_;
333 }
334 324
335 void InitializeReservedMemory() { 325 void InitializeReservedMemory() { reservation_.Reset(); }
336 reservation_.Reset();
337 }
338 326
339 void set_reserved_memory(base::VirtualMemory* reservation) { 327 void set_reserved_memory(base::VirtualMemory* reservation) {
340 DCHECK_NOT_NULL(reservation); 328 DCHECK_NOT_NULL(reservation);
341 reservation_.TakeControl(reservation); 329 reservation_.TakeControl(reservation);
342 } 330 }
343 331
344 bool scan_on_scavenge() { return IsFlagSet(SCAN_ON_SCAVENGE); } 332 bool scan_on_scavenge() { return IsFlagSet(SCAN_ON_SCAVENGE); }
345 void initialize_scan_on_scavenge(bool scan) { 333 void initialize_scan_on_scavenge(bool scan) {
346 if (scan) { 334 if (scan) {
347 SetFlag(SCAN_ON_SCAVENGE); 335 SetFlag(SCAN_ON_SCAVENGE);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 NUM_MEMORY_CHUNK_FLAGS 390 NUM_MEMORY_CHUNK_FLAGS
403 }; 391 };
404 392
405 393
406 static const int kPointersToHereAreInterestingMask = 394 static const int kPointersToHereAreInterestingMask =
407 1 << POINTERS_TO_HERE_ARE_INTERESTING; 395 1 << POINTERS_TO_HERE_ARE_INTERESTING;
408 396
409 static const int kPointersFromHereAreInterestingMask = 397 static const int kPointersFromHereAreInterestingMask =
410 1 << POINTERS_FROM_HERE_ARE_INTERESTING; 398 1 << POINTERS_FROM_HERE_ARE_INTERESTING;
411 399
412 static const int kEvacuationCandidateMask = 400 static const int kEvacuationCandidateMask = 1 << EVACUATION_CANDIDATE;
413 1 << EVACUATION_CANDIDATE;
414 401
415 static const int kSkipEvacuationSlotsRecordingMask = 402 static const int kSkipEvacuationSlotsRecordingMask =
416 (1 << EVACUATION_CANDIDATE) | 403 (1 << EVACUATION_CANDIDATE) | (1 << RESCAN_ON_EVACUATION) |
417 (1 << RESCAN_ON_EVACUATION) | 404 (1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE);
418 (1 << IN_FROM_SPACE) |
419 (1 << IN_TO_SPACE);
420 405
421 406
422 void SetFlag(int flag) { 407 void SetFlag(int flag) { flags_ |= static_cast<uintptr_t>(1) << flag; }
423 flags_ |= static_cast<uintptr_t>(1) << flag;
424 }
425 408
426 void ClearFlag(int flag) { 409 void ClearFlag(int flag) { flags_ &= ~(static_cast<uintptr_t>(1) << flag); }
427 flags_ &= ~(static_cast<uintptr_t>(1) << flag);
428 }
429 410
430 void SetFlagTo(int flag, bool value) { 411 void SetFlagTo(int flag, bool value) {
431 if (value) { 412 if (value) {
432 SetFlag(flag); 413 SetFlag(flag);
433 } else { 414 } else {
434 ClearFlag(flag); 415 ClearFlag(flag);
435 } 416 }
436 } 417 }
437 418
438 bool IsFlagSet(int flag) { 419 bool IsFlagSet(int flag) {
(...skipping 27 matching lines...) Expand all
466 ParallelSweepingState parallel_sweeping() { 447 ParallelSweepingState parallel_sweeping() {
467 return static_cast<ParallelSweepingState>( 448 return static_cast<ParallelSweepingState>(
468 base::Acquire_Load(&parallel_sweeping_)); 449 base::Acquire_Load(&parallel_sweeping_));
469 } 450 }
470 451
471 void set_parallel_sweeping(ParallelSweepingState state) { 452 void set_parallel_sweeping(ParallelSweepingState state) {
472 base::Release_Store(&parallel_sweeping_, state); 453 base::Release_Store(&parallel_sweeping_, state);
473 } 454 }
474 455
475 bool TryParallelSweeping() { 456 bool TryParallelSweeping() {
476 return base::Acquire_CompareAndSwap( 457 return base::Acquire_CompareAndSwap(&parallel_sweeping_, SWEEPING_PENDING,
477 &parallel_sweeping_, SWEEPING_PENDING, SWEEPING_IN_PROGRESS) == 458 SWEEPING_IN_PROGRESS) ==
478 SWEEPING_PENDING; 459 SWEEPING_PENDING;
479 } 460 }
480 461
481 bool SweepingCompleted() { return parallel_sweeping() <= SWEEPING_FINALIZE; } 462 bool SweepingCompleted() { return parallel_sweeping() <= SWEEPING_FINALIZE; }
482 463
483 // Manage live byte count (count of bytes known to be live, 464 // Manage live byte count (count of bytes known to be live,
484 // because they are marked black). 465 // because they are marked black).
485 void ResetLiveBytes() { 466 void ResetLiveBytes() {
486 if (FLAG_gc_verbose) { 467 if (FLAG_gc_verbose) {
487 PrintF("ResetLiveBytes:%p:%x->0\n", 468 PrintF("ResetLiveBytes:%p:%x->0\n", static_cast<void*>(this),
488 static_cast<void*>(this), live_byte_count_); 469 live_byte_count_);
489 } 470 }
490 live_byte_count_ = 0; 471 live_byte_count_ = 0;
491 } 472 }
492 void IncrementLiveBytes(int by) { 473 void IncrementLiveBytes(int by) {
493 if (FLAG_gc_verbose) { 474 if (FLAG_gc_verbose) {
494 printf("UpdateLiveBytes:%p:%x%c=%x->%x\n", 475 printf("UpdateLiveBytes:%p:%x%c=%x->%x\n", static_cast<void*>(this),
495 static_cast<void*>(this), live_byte_count_, 476 live_byte_count_, ((by < 0) ? '-' : '+'), ((by < 0) ? -by : by),
496 ((by < 0) ? '-' : '+'), ((by < 0) ? -by : by),
497 live_byte_count_ + by); 477 live_byte_count_ + by);
498 } 478 }
499 live_byte_count_ += by; 479 live_byte_count_ += by;
500 DCHECK_LE(static_cast<unsigned>(live_byte_count_), size_); 480 DCHECK_LE(static_cast<unsigned>(live_byte_count_), size_);
501 } 481 }
502 int LiveBytes() { 482 int LiveBytes() {
503 DCHECK(static_cast<unsigned>(live_byte_count_) <= size_); 483 DCHECK(static_cast<unsigned>(live_byte_count_) <= size_);
504 return live_byte_count_; 484 return live_byte_count_;
505 } 485 }
506 486
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 static void IncrementLiveBytesFromMutator(Address address, int by); 523 static void IncrementLiveBytesFromMutator(Address address, int by);
544 524
545 static const intptr_t kAlignment = 525 static const intptr_t kAlignment =
546 (static_cast<uintptr_t>(1) << kPageSizeBits); 526 (static_cast<uintptr_t>(1) << kPageSizeBits);
547 527
548 static const intptr_t kAlignmentMask = kAlignment - 1; 528 static const intptr_t kAlignmentMask = kAlignment - 1;
549 529
550 static const intptr_t kSizeOffset = 0; 530 static const intptr_t kSizeOffset = 0;
551 531
552 static const intptr_t kLiveBytesOffset = 532 static const intptr_t kLiveBytesOffset =
553 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + 533 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + kPointerSize +
554 kPointerSize + kPointerSize + 534 kPointerSize + kPointerSize + kPointerSize + kPointerSize + kIntSize;
555 kPointerSize + kPointerSize + kPointerSize + kIntSize;
556 535
557 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; 536 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize;
558 537
559 static const size_t kWriteBarrierCounterOffset = 538 static const size_t kWriteBarrierCounterOffset =
560 kSlotsBufferOffset + kPointerSize + kPointerSize; 539 kSlotsBufferOffset + kPointerSize + kPointerSize;
561 540
562 static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize + 541 static const size_t kHeaderSize =
563 kIntSize + kIntSize + kPointerSize + 542 kWriteBarrierCounterOffset + kPointerSize + kIntSize + kIntSize +
564 5 * kPointerSize + 543 kPointerSize + 5 * kPointerSize + kPointerSize + kPointerSize;
565 kPointerSize + kPointerSize;
566 544
567 static const int kBodyOffset = 545 static const int kBodyOffset =
568 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); 546 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize);
569 547
570 // The start offset of the object area in a page. Aligned to both maps and 548 // The start offset of the object area in a page. Aligned to both maps and
571 // code alignment to be suitable for both. Also aligned to 32 words because 549 // code alignment to be suitable for both. Also aligned to 32 words because
572 // the marking bitmap is arranged in 32 bit chunks. 550 // the marking bitmap is arranged in 32 bit chunks.
573 static const int kObjectStartAlignment = 32 * kPointerSize; 551 static const int kObjectStartAlignment = 32 * kPointerSize;
574 static const int kObjectStartOffset = kBodyOffset - 1 + 552 static const int kObjectStartOffset =
553 kBodyOffset - 1 +
575 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); 554 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment);
576 555
577 size_t size() const { return size_; } 556 size_t size() const { return size_; }
578 557
579 void set_size(size_t size) { 558 void set_size(size_t size) { size_ = size; }
580 size_ = size;
581 }
582 559
583 void SetArea(Address area_start, Address area_end) { 560 void SetArea(Address area_start, Address area_end) {
584 area_start_ = area_start; 561 area_start_ = area_start;
585 area_end_ = area_end; 562 area_end_ = area_end;
586 } 563 }
587 564
588 Executability executable() { 565 Executability executable() {
589 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 566 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
590 } 567 }
591 568
592 bool ContainsOnlyData() { 569 bool ContainsOnlyData() { return IsFlagSet(CONTAINS_ONLY_DATA); }
593 return IsFlagSet(CONTAINS_ONLY_DATA);
594 }
595 570
596 bool InNewSpace() { 571 bool InNewSpace() {
597 return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0; 572 return (flags_ & ((1 << IN_FROM_SPACE) | (1 << IN_TO_SPACE))) != 0;
598 } 573 }
599 574
600 bool InToSpace() { 575 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); }
601 return IsFlagSet(IN_TO_SPACE);
602 }
603 576
604 bool InFromSpace() { 577 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); }
605 return IsFlagSet(IN_FROM_SPACE);
606 }
607 578
608 // --------------------------------------------------------------------- 579 // ---------------------------------------------------------------------
609 // Markbits support 580 // Markbits support
610 581
611 inline Bitmap* markbits() { 582 inline Bitmap* markbits() {
612 return Bitmap::FromAddress(address() + kHeaderSize); 583 return Bitmap::FromAddress(address() + kHeaderSize);
613 } 584 }
614 585
615 void PrintMarkbits() { markbits()->Print(); } 586 void PrintMarkbits() { markbits()->Print(); }
616 587
617 inline uint32_t AddressToMarkbitIndex(Address addr) { 588 inline uint32_t AddressToMarkbitIndex(Address addr) {
618 return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; 589 return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2;
619 } 590 }
620 591
621 inline static uint32_t FastAddressToMarkbitIndex(Address addr) { 592 inline static uint32_t FastAddressToMarkbitIndex(Address addr) {
622 const intptr_t offset = 593 const intptr_t offset = reinterpret_cast<intptr_t>(addr) & kAlignmentMask;
623 reinterpret_cast<intptr_t>(addr) & kAlignmentMask;
624 594
625 return static_cast<uint32_t>(offset) >> kPointerSizeLog2; 595 return static_cast<uint32_t>(offset) >> kPointerSizeLog2;
626 } 596 }
627 597
628 inline Address MarkbitIndexToAddress(uint32_t index) { 598 inline Address MarkbitIndexToAddress(uint32_t index) {
629 return this->address() + (index << kPointerSizeLog2); 599 return this->address() + (index << kPointerSizeLog2);
630 } 600 }
631 601
632 void InsertAfter(MemoryChunk* other); 602 void InsertAfter(MemoryChunk* other);
633 void Unlink(); 603 void Unlink();
634 604
635 inline Heap* heap() const { return heap_; } 605 inline Heap* heap() const { return heap_; }
636 606
637 static const int kFlagsOffset = kPointerSize; 607 static const int kFlagsOffset = kPointerSize;
638 608
639 bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } 609 bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); }
640 610
641 bool ShouldSkipEvacuationSlotRecording() { 611 bool ShouldSkipEvacuationSlotRecording() {
642 return (flags_ & kSkipEvacuationSlotsRecordingMask) != 0; 612 return (flags_ & kSkipEvacuationSlotsRecordingMask) != 0;
643 } 613 }
644 614
645 inline SkipList* skip_list() { 615 inline SkipList* skip_list() { return skip_list_; }
646 return skip_list_;
647 }
648 616
649 inline void set_skip_list(SkipList* skip_list) { 617 inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; }
650 skip_list_ = skip_list;
651 }
652 618
653 inline SlotsBuffer* slots_buffer() { 619 inline SlotsBuffer* slots_buffer() { return slots_buffer_; }
654 return slots_buffer_;
655 }
656 620
657 inline SlotsBuffer** slots_buffer_address() { 621 inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; }
658 return &slots_buffer_;
659 }
660 622
661 void MarkEvacuationCandidate() { 623 void MarkEvacuationCandidate() {
662 DCHECK(slots_buffer_ == NULL); 624 DCHECK(slots_buffer_ == NULL);
663 SetFlag(EVACUATION_CANDIDATE); 625 SetFlag(EVACUATION_CANDIDATE);
664 } 626 }
665 627
666 void ClearEvacuationCandidate() { 628 void ClearEvacuationCandidate() {
667 DCHECK(slots_buffer_ == NULL); 629 DCHECK(slots_buffer_ == NULL);
668 ClearFlag(EVACUATION_CANDIDATE); 630 ClearFlag(EVACUATION_CANDIDATE);
669 } 631 }
670 632
671 Address area_start() { return area_start_; } 633 Address area_start() { return area_start_; }
672 Address area_end() { return area_end_; } 634 Address area_end() { return area_end_; }
673 int area_size() { 635 int area_size() { return static_cast<int>(area_end() - area_start()); }
674 return static_cast<int>(area_end() - area_start());
675 }
676 bool CommitArea(size_t requested); 636 bool CommitArea(size_t requested);
677 637
678 // Approximate amount of physical memory committed for this chunk. 638 // Approximate amount of physical memory committed for this chunk.
679 size_t CommittedPhysicalMemory() { 639 size_t CommittedPhysicalMemory() { return high_water_mark_; }
680 return high_water_mark_;
681 }
682 640
683 static inline void UpdateHighWaterMark(Address mark); 641 static inline void UpdateHighWaterMark(Address mark);
684 642
685 protected: 643 protected:
686 size_t size_; 644 size_t size_;
687 intptr_t flags_; 645 intptr_t flags_;
688 646
689 // Start and end of allocatable memory on this chunk. 647 // Start and end of allocatable memory on this chunk.
690 Address area_start_; 648 Address area_start_;
691 Address area_end_; 649 Address area_end_;
(...skipping 22 matching lines...) Expand all
714 672
715 base::AtomicWord parallel_sweeping_; 673 base::AtomicWord parallel_sweeping_;
716 674
717 // PagedSpace free-list statistics. 675 // PagedSpace free-list statistics.
718 intptr_t available_in_small_free_list_; 676 intptr_t available_in_small_free_list_;
719 intptr_t available_in_medium_free_list_; 677 intptr_t available_in_medium_free_list_;
720 intptr_t available_in_large_free_list_; 678 intptr_t available_in_large_free_list_;
721 intptr_t available_in_huge_free_list_; 679 intptr_t available_in_huge_free_list_;
722 intptr_t non_available_small_blocks_; 680 intptr_t non_available_small_blocks_;
723 681
724 static MemoryChunk* Initialize(Heap* heap, 682 static MemoryChunk* Initialize(Heap* heap, Address base, size_t size,
725 Address base, 683 Address area_start, Address area_end,
726 size_t size, 684 Executability executable, Space* owner);
727 Address area_start,
728 Address area_end,
729 Executability executable,
730 Space* owner);
731 685
732 private: 686 private:
733 // next_chunk_ holds a pointer of type MemoryChunk 687 // next_chunk_ holds a pointer of type MemoryChunk
734 base::AtomicWord next_chunk_; 688 base::AtomicWord next_chunk_;
735 // prev_chunk_ holds a pointer of type MemoryChunk 689 // prev_chunk_ holds a pointer of type MemoryChunk
736 base::AtomicWord prev_chunk_; 690 base::AtomicWord prev_chunk_;
737 691
738 friend class MemoryAllocator; 692 friend class MemoryAllocator;
739 }; 693 };
740 694
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // are allocated in large object space and are never moved in memory. This 753 // are allocated in large object space and are never moved in memory. This
800 // also applies to new space allocation, since objects are never migrated 754 // also applies to new space allocation, since objects are never migrated
801 // from new space to large object space. Takes double alignment into account. 755 // from new space to large object space. Takes double alignment into account.
802 static const int kMaxRegularHeapObjectSize = kPageSize - kObjectStartOffset; 756 static const int kMaxRegularHeapObjectSize = kPageSize - kObjectStartOffset;
803 757
804 // Page size mask. 758 // Page size mask.
805 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; 759 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
806 760
807 inline void ClearGCFields(); 761 inline void ClearGCFields();
808 762
809 static inline Page* Initialize(Heap* heap, 763 static inline Page* Initialize(Heap* heap, MemoryChunk* chunk,
810 MemoryChunk* chunk, 764 Executability executable, PagedSpace* owner);
811 Executability executable,
812 PagedSpace* owner);
813 765
814 void InitializeAsAnchor(PagedSpace* owner); 766 void InitializeAsAnchor(PagedSpace* owner);
815 767
816 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } 768 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); }
817 bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); } 769 bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); }
818 bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); } 770 bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); }
819 771
820 void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); } 772 void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); }
821 void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); } 773 void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); }
822 774
(...skipping 21 matching lines...) Expand all
844 796
845 friend class MemoryAllocator; 797 friend class MemoryAllocator;
846 }; 798 };
847 799
848 800
849 STATIC_ASSERT(sizeof(Page) <= MemoryChunk::kHeaderSize); 801 STATIC_ASSERT(sizeof(Page) <= MemoryChunk::kHeaderSize);
850 802
851 803
852 class LargePage : public MemoryChunk { 804 class LargePage : public MemoryChunk {
853 public: 805 public:
854 HeapObject* GetObject() { 806 HeapObject* GetObject() { return HeapObject::FromAddress(area_start()); }
855 return HeapObject::FromAddress(area_start());
856 }
857 807
858 inline LargePage* next_page() const { 808 inline LargePage* next_page() const {
859 return static_cast<LargePage*>(next_chunk()); 809 return static_cast<LargePage*>(next_chunk());
860 } 810 }
861 811
862 inline void set_next_page(LargePage* page) { 812 inline void set_next_page(LargePage* page) { set_next_chunk(page); }
863 set_next_chunk(page); 813
864 }
865 private: 814 private:
866 static inline LargePage* Initialize(Heap* heap, MemoryChunk* chunk); 815 static inline LargePage* Initialize(Heap* heap, MemoryChunk* chunk);
867 816
868 friend class MemoryAllocator; 817 friend class MemoryAllocator;
869 }; 818 };
870 819
871 STATIC_ASSERT(sizeof(LargePage) <= MemoryChunk::kHeaderSize); 820 STATIC_ASSERT(sizeof(LargePage) <= MemoryChunk::kHeaderSize);
872 821
873 // ---------------------------------------------------------------------------- 822 // ----------------------------------------------------------------------------
874 // Space is the abstract superclass for all allocation spaces. 823 // Space is the abstract superclass for all allocation spaces.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 // Compares the start addresses of two free blocks. 944 // Compares the start addresses of two free blocks.
996 static int CompareFreeBlockAddress(const FreeBlock* left, 945 static int CompareFreeBlockAddress(const FreeBlock* left,
997 const FreeBlock* right); 946 const FreeBlock* right);
998 947
999 DISALLOW_COPY_AND_ASSIGN(CodeRange); 948 DISALLOW_COPY_AND_ASSIGN(CodeRange);
1000 }; 949 };
1001 950
1002 951
1003 class SkipList { 952 class SkipList {
1004 public: 953 public:
1005 SkipList() { 954 SkipList() { Clear(); }
1006 Clear();
1007 }
1008 955
1009 void Clear() { 956 void Clear() {
1010 for (int idx = 0; idx < kSize; idx++) { 957 for (int idx = 0; idx < kSize; idx++) {
1011 starts_[idx] = reinterpret_cast<Address>(-1); 958 starts_[idx] = reinterpret_cast<Address>(-1);
1012 } 959 }
1013 } 960 }
1014 961
1015 Address StartFor(Address addr) { 962 Address StartFor(Address addr) { return starts_[RegionNumber(addr)]; }
1016 return starts_[RegionNumber(addr)];
1017 }
1018 963
1019 void AddObject(Address addr, int size) { 964 void AddObject(Address addr, int size) {
1020 int start_region = RegionNumber(addr); 965 int start_region = RegionNumber(addr);
1021 int end_region = RegionNumber(addr + size - kPointerSize); 966 int end_region = RegionNumber(addr + size - kPointerSize);
1022 for (int idx = start_region; idx <= end_region; idx++) { 967 for (int idx = start_region; idx <= end_region; idx++) {
1023 if (starts_[idx] > addr) starts_[idx] = addr; 968 if (starts_[idx] > addr) starts_[idx] = addr;
1024 } 969 }
1025 } 970 }
1026 971
1027 static inline int RegionNumber(Address addr) { 972 static inline int RegionNumber(Address addr) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 class MemoryAllocator { 1005 class MemoryAllocator {
1061 public: 1006 public:
1062 explicit MemoryAllocator(Isolate* isolate); 1007 explicit MemoryAllocator(Isolate* isolate);
1063 1008
1064 // Initializes its internal bookkeeping structures. 1009 // Initializes its internal bookkeeping structures.
1065 // Max capacity of the total space and executable memory limit. 1010 // Max capacity of the total space and executable memory limit.
1066 bool SetUp(intptr_t max_capacity, intptr_t capacity_executable); 1011 bool SetUp(intptr_t max_capacity, intptr_t capacity_executable);
1067 1012
1068 void TearDown(); 1013 void TearDown();
1069 1014
1070 Page* AllocatePage( 1015 Page* AllocatePage(intptr_t size, PagedSpace* owner,
1071 intptr_t size, PagedSpace* owner, Executability executable); 1016 Executability executable);
1072 1017
1073 LargePage* AllocateLargePage( 1018 LargePage* AllocateLargePage(intptr_t object_size, Space* owner,
1074 intptr_t object_size, Space* owner, Executability executable); 1019 Executability executable);
1075 1020
1076 void Free(MemoryChunk* chunk); 1021 void Free(MemoryChunk* chunk);
1077 1022
1078 // Returns the maximum available bytes of heaps. 1023 // Returns the maximum available bytes of heaps.
1079 intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; } 1024 intptr_t Available() { return capacity_ < size_ ? 0 : capacity_ - size_; }
1080 1025
1081 // Returns allocated spaces in bytes. 1026 // Returns allocated spaces in bytes.
1082 intptr_t Size() { return size_; } 1027 intptr_t Size() { return size_; }
1083 1028
1084 // Returns the maximum available executable bytes of heaps. 1029 // Returns the maximum available executable bytes of heaps.
1085 intptr_t AvailableExecutable() { 1030 intptr_t AvailableExecutable() {
1086 if (capacity_executable_ < size_executable_) return 0; 1031 if (capacity_executable_ < size_executable_) return 0;
1087 return capacity_executable_ - size_executable_; 1032 return capacity_executable_ - size_executable_;
1088 } 1033 }
1089 1034
1090 // Returns allocated executable spaces in bytes. 1035 // Returns allocated executable spaces in bytes.
1091 intptr_t SizeExecutable() { return size_executable_; } 1036 intptr_t SizeExecutable() { return size_executable_; }
1092 1037
1093 // Returns maximum available bytes that the old space can have. 1038 // Returns maximum available bytes that the old space can have.
1094 intptr_t MaxAvailable() { 1039 intptr_t MaxAvailable() {
1095 return (Available() / Page::kPageSize) * Page::kMaxRegularHeapObjectSize; 1040 return (Available() / Page::kPageSize) * Page::kMaxRegularHeapObjectSize;
1096 } 1041 }
1097 1042
1098 // Returns an indication of whether a pointer is in a space that has 1043 // Returns an indication of whether a pointer is in a space that has
1099 // been allocated by this MemoryAllocator. 1044 // been allocated by this MemoryAllocator.
1100 V8_INLINE bool IsOutsideAllocatedSpace(const void* address) const { 1045 V8_INLINE bool IsOutsideAllocatedSpace(const void* address) const {
1101 return address < lowest_ever_allocated_ || 1046 return address < lowest_ever_allocated_ ||
1102 address >= highest_ever_allocated_; 1047 address >= highest_ever_allocated_;
1103 } 1048 }
1104 1049
1105 #ifdef DEBUG 1050 #ifdef DEBUG
1106 // Reports statistic info of the space. 1051 // Reports statistic info of the space.
1107 void ReportStatistics(); 1052 void ReportStatistics();
1108 #endif 1053 #endif
1109 1054
1110 // Returns a MemoryChunk in which the memory region from commit_area_size to 1055 // Returns a MemoryChunk in which the memory region from commit_area_size to
1111 // reserve_area_size of the chunk area is reserved but not committed, it 1056 // reserve_area_size of the chunk area is reserved but not committed, it
1112 // could be committed later by calling MemoryChunk::CommitArea. 1057 // could be committed later by calling MemoryChunk::CommitArea.
1113 MemoryChunk* AllocateChunk(intptr_t reserve_area_size, 1058 MemoryChunk* AllocateChunk(intptr_t reserve_area_size,
1114 intptr_t commit_area_size, 1059 intptr_t commit_area_size,
1115 Executability executable, 1060 Executability executable, Space* space);
1116 Space* space);
1117 1061
1118 Address ReserveAlignedMemory(size_t requested, 1062 Address ReserveAlignedMemory(size_t requested, size_t alignment,
1119 size_t alignment,
1120 base::VirtualMemory* controller); 1063 base::VirtualMemory* controller);
1121 Address AllocateAlignedMemory(size_t reserve_size, 1064 Address AllocateAlignedMemory(size_t reserve_size, size_t commit_size,
1122 size_t commit_size, 1065 size_t alignment, Executability executable,
1123 size_t alignment,
1124 Executability executable,
1125 base::VirtualMemory* controller); 1066 base::VirtualMemory* controller);
1126 1067
1127 bool CommitMemory(Address addr, size_t size, Executability executable); 1068 bool CommitMemory(Address addr, size_t size, Executability executable);
1128 1069
1129 void FreeMemory(base::VirtualMemory* reservation, Executability executable); 1070 void FreeMemory(base::VirtualMemory* reservation, Executability executable);
1130 void FreeMemory(Address addr, size_t size, Executability executable); 1071 void FreeMemory(Address addr, size_t size, Executability executable);
1131 1072
1132 // Commit a contiguous block of memory from the initial chunk. Assumes that 1073 // Commit a contiguous block of memory from the initial chunk. Assumes that
1133 // the address is not NULL, the size is greater than zero, and that the 1074 // the address is not NULL, the size is greater than zero, and that the
1134 // block is contained in the initial chunk. Returns true if it succeeded 1075 // block is contained in the initial chunk. Returns true if it succeeded
1135 // and false otherwise. 1076 // and false otherwise.
1136 bool CommitBlock(Address start, size_t size, Executability executable); 1077 bool CommitBlock(Address start, size_t size, Executability executable);
1137 1078
1138 // Uncommit a contiguous block of memory [start..(start+size)[. 1079 // Uncommit a contiguous block of memory [start..(start+size)[.
1139 // start is not NULL, the size is greater than zero, and the 1080 // start is not NULL, the size is greater than zero, and the
1140 // block is contained in the initial chunk. Returns true if it succeeded 1081 // block is contained in the initial chunk. Returns true if it succeeded
1141 // and false otherwise. 1082 // and false otherwise.
1142 bool UncommitBlock(Address start, size_t size); 1083 bool UncommitBlock(Address start, size_t size);
1143 1084
1144 // Zaps a contiguous block of memory [start..(start+size)[ thus 1085 // Zaps a contiguous block of memory [start..(start+size)[ thus
1145 // filling it up with a recognizable non-NULL bit pattern. 1086 // filling it up with a recognizable non-NULL bit pattern.
1146 void ZapBlock(Address start, size_t size); 1087 void ZapBlock(Address start, size_t size);
1147 1088
1148 void PerformAllocationCallback(ObjectSpace space, 1089 void PerformAllocationCallback(ObjectSpace space, AllocationAction action,
1149 AllocationAction action,
1150 size_t size); 1090 size_t size);
1151 1091
1152 void AddMemoryAllocationCallback(MemoryAllocationCallback callback, 1092 void AddMemoryAllocationCallback(MemoryAllocationCallback callback,
1153 ObjectSpace space, 1093 ObjectSpace space, AllocationAction action);
1154 AllocationAction action);
1155 1094
1156 void RemoveMemoryAllocationCallback( 1095 void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
1157 MemoryAllocationCallback callback);
1158 1096
1159 bool MemoryAllocationCallbackRegistered( 1097 bool MemoryAllocationCallbackRegistered(MemoryAllocationCallback callback);
1160 MemoryAllocationCallback callback);
1161 1098
1162 static int CodePageGuardStartOffset(); 1099 static int CodePageGuardStartOffset();
1163 1100
1164 static int CodePageGuardSize(); 1101 static int CodePageGuardSize();
1165 1102
1166 static int CodePageAreaStartOffset(); 1103 static int CodePageAreaStartOffset();
1167 1104
1168 static int CodePageAreaEndOffset(); 1105 static int CodePageAreaEndOffset();
1169 1106
1170 static int CodePageAreaSize() { 1107 static int CodePageAreaSize() {
1171 return CodePageAreaEndOffset() - CodePageAreaStartOffset(); 1108 return CodePageAreaEndOffset() - CodePageAreaStartOffset();
1172 } 1109 }
1173 1110
1174 MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm, 1111 MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm,
1175 Address start, 1112 Address start, size_t commit_size,
1176 size_t commit_size,
1177 size_t reserved_size); 1113 size_t reserved_size);
1178 1114
1179 private: 1115 private:
1180 Isolate* isolate_; 1116 Isolate* isolate_;
1181 1117
1182 // Maximum space size in bytes. 1118 // Maximum space size in bytes.
1183 size_t capacity_; 1119 size_t capacity_;
1184 // Maximum subset of capacity_ that can be executable 1120 // Maximum subset of capacity_ that can be executable
1185 size_t capacity_executable_; 1121 size_t capacity_executable_;
1186 1122
1187 // Allocated space size in bytes. 1123 // Allocated space size in bytes.
1188 size_t size_; 1124 size_t size_;
1189 // Allocated executable space size in bytes. 1125 // Allocated executable space size in bytes.
1190 size_t size_executable_; 1126 size_t size_executable_;
1191 1127
1192 // We keep the lowest and highest addresses allocated as a quick way 1128 // We keep the lowest and highest addresses allocated as a quick way
1193 // of determining that pointers are outside the heap. The estimate is 1129 // of determining that pointers are outside the heap. The estimate is
1194 // conservative, i.e. not all addrsses in 'allocated' space are allocated 1130 // conservative, i.e. not all addrsses in 'allocated' space are allocated
1195 // to our heap. The range is [lowest, highest[, inclusive on the low end 1131 // to our heap. The range is [lowest, highest[, inclusive on the low end
1196 // and exclusive on the high end. 1132 // and exclusive on the high end.
1197 void* lowest_ever_allocated_; 1133 void* lowest_ever_allocated_;
1198 void* highest_ever_allocated_; 1134 void* highest_ever_allocated_;
1199 1135
1200 struct MemoryAllocationCallbackRegistration { 1136 struct MemoryAllocationCallbackRegistration {
1201 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback, 1137 MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback,
1202 ObjectSpace space, 1138 ObjectSpace space,
1203 AllocationAction action) 1139 AllocationAction action)
1204 : callback(callback), space(space), action(action) { 1140 : callback(callback), space(space), action(action) {}
1205 }
1206 MemoryAllocationCallback callback; 1141 MemoryAllocationCallback callback;
1207 ObjectSpace space; 1142 ObjectSpace space;
1208 AllocationAction action; 1143 AllocationAction action;
1209 }; 1144 };
1210 1145
1211 // A List of callback that are triggered when memory is allocated or free'd 1146 // A List of callback that are triggered when memory is allocated or free'd
1212 List<MemoryAllocationCallbackRegistration> 1147 List<MemoryAllocationCallbackRegistration> memory_allocation_callbacks_;
1213 memory_allocation_callbacks_;
1214 1148
1215 // Initializes pages in a chunk. Returns the first page address. 1149 // Initializes pages in a chunk. Returns the first page address.
1216 // This function and GetChunkId() are provided for the mark-compact 1150 // This function and GetChunkId() are provided for the mark-compact
1217 // collector to rebuild page headers in the from space, which is 1151 // collector to rebuild page headers in the from space, which is
1218 // used as a marking stack and its page headers are destroyed. 1152 // used as a marking stack and its page headers are destroyed.
1219 Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk, 1153 Page* InitializePagesInChunk(int chunk_id, int pages_in_chunk,
1220 PagedSpace* owner); 1154 PagedSpace* owner);
1221 1155
1222 void UpdateAllocatedSpaceLimits(void* low, void* high) { 1156 void UpdateAllocatedSpaceLimits(void* low, void* high) {
1223 lowest_ever_allocated_ = Min(lowest_ever_allocated_, low); 1157 lowest_ever_allocated_ = Min(lowest_ever_allocated_, low);
1224 highest_ever_allocated_ = Max(highest_ever_allocated_, high); 1158 highest_ever_allocated_ = Max(highest_ever_allocated_, high);
1225 } 1159 }
1226 1160
1227 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator); 1161 DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryAllocator);
1228 }; 1162 };
1229 1163
1230 1164
1231 // ----------------------------------------------------------------------------- 1165 // -----------------------------------------------------------------------------
1232 // Interface for heap object iterator to be implemented by all object space 1166 // Interface for heap object iterator to be implemented by all object space
1233 // object iterators. 1167 // object iterators.
1234 // 1168 //
1235 // NOTE: The space specific object iterators also implements the own next() 1169 // NOTE: The space specific object iterators also implements the own next()
1236 // method which is used to avoid using virtual functions 1170 // method which is used to avoid using virtual functions
1237 // iterating a specific space. 1171 // iterating a specific space.
1238 1172
1239 class ObjectIterator : public Malloced { 1173 class ObjectIterator : public Malloced {
1240 public: 1174 public:
1241 virtual ~ObjectIterator() { } 1175 virtual ~ObjectIterator() {}
1242 1176
1243 virtual HeapObject* next_object() = 0; 1177 virtual HeapObject* next_object() = 0;
1244 }; 1178 };
1245 1179
1246 1180
1247 // ----------------------------------------------------------------------------- 1181 // -----------------------------------------------------------------------------
1248 // Heap object iterator in new/old/map spaces. 1182 // Heap object iterator in new/old/map spaces.
1249 // 1183 //
1250 // A HeapObjectIterator iterates objects from the bottom of the given space 1184 // A HeapObjectIterator iterates objects from the bottom of the given space
1251 // to its top or from the bottom of the given page to its top. 1185 // to its top or from the bottom of the given page to its top.
1252 // 1186 //
1253 // If objects are allocated in the page during iteration the iterator may 1187 // If objects are allocated in the page during iteration the iterator may
1254 // or may not iterate over those objects. The caller must create a new 1188 // or may not iterate over those objects. The caller must create a new
1255 // iterator in order to be sure to visit these new objects. 1189 // iterator in order to be sure to visit these new objects.
1256 class HeapObjectIterator: public ObjectIterator { 1190 class HeapObjectIterator : public ObjectIterator {
1257 public: 1191 public:
1258 // Creates a new object iterator in a given space. 1192 // Creates a new object iterator in a given space.
1259 // If the size function is not given, the iterator calls the default 1193 // If the size function is not given, the iterator calls the default
1260 // Object::Size(). 1194 // Object::Size().
1261 explicit HeapObjectIterator(PagedSpace* space); 1195 explicit HeapObjectIterator(PagedSpace* space);
1262 HeapObjectIterator(PagedSpace* space, HeapObjectCallback size_func); 1196 HeapObjectIterator(PagedSpace* space, HeapObjectCallback size_func);
1263 HeapObjectIterator(Page* page, HeapObjectCallback size_func); 1197 HeapObjectIterator(Page* page, HeapObjectCallback size_func);
1264 1198
1265 // Advance to the next object, skipping free spaces and other fillers and 1199 // Advance to the next object, skipping free spaces and other fillers and
1266 // skipping the special garbage section of which there is one per space. 1200 // skipping the special garbage section of which there is one per space.
1267 // Returns NULL when the iteration has ended. 1201 // Returns NULL when the iteration has ended.
1268 inline HeapObject* Next() { 1202 inline HeapObject* Next() {
1269 do { 1203 do {
1270 HeapObject* next_obj = FromCurrentPage(); 1204 HeapObject* next_obj = FromCurrentPage();
1271 if (next_obj != NULL) return next_obj; 1205 if (next_obj != NULL) return next_obj;
1272 } while (AdvanceToNextPage()); 1206 } while (AdvanceToNextPage());
1273 return NULL; 1207 return NULL;
1274 } 1208 }
1275 1209
1276 virtual HeapObject* next_object() { 1210 virtual HeapObject* next_object() { return Next(); }
1277 return Next();
1278 }
1279 1211
1280 private: 1212 private:
1281 enum PageMode { kOnePageOnly, kAllPagesInSpace }; 1213 enum PageMode { kOnePageOnly, kAllPagesInSpace };
1282 1214
1283 Address cur_addr_; // Current iteration point. 1215 Address cur_addr_; // Current iteration point.
1284 Address cur_end_; // End iteration point. 1216 Address cur_end_; // End iteration point.
1285 HeapObjectCallback size_func_; // Size function or NULL. 1217 HeapObjectCallback size_func_; // Size function or NULL.
1286 PagedSpace* space_; 1218 PagedSpace* space_;
1287 PageMode page_mode_; 1219 PageMode page_mode_;
1288 1220
1289 // Fast (inlined) path of next(). 1221 // Fast (inlined) path of next().
1290 inline HeapObject* FromCurrentPage(); 1222 inline HeapObject* FromCurrentPage();
1291 1223
1292 // Slow path of next(), goes into the next page. Returns false if the 1224 // Slow path of next(), goes into the next page. Returns false if the
1293 // iteration has ended. 1225 // iteration has ended.
1294 bool AdvanceToNextPage(); 1226 bool AdvanceToNextPage();
1295 1227
1296 // Initializes fields. 1228 // Initializes fields.
1297 inline void Initialize(PagedSpace* owner, 1229 inline void Initialize(PagedSpace* owner, Address start, Address end,
1298 Address start, 1230 PageMode mode, HeapObjectCallback size_func);
1299 Address end,
1300 PageMode mode,
1301 HeapObjectCallback size_func);
1302 }; 1231 };
1303 1232
1304 1233
1305 // ----------------------------------------------------------------------------- 1234 // -----------------------------------------------------------------------------
1306 // A PageIterator iterates the pages in a paged space. 1235 // A PageIterator iterates the pages in a paged space.
1307 1236
1308 class PageIterator BASE_EMBEDDED { 1237 class PageIterator BASE_EMBEDDED {
1309 public: 1238 public:
1310 explicit inline PageIterator(PagedSpace* space); 1239 explicit inline PageIterator(PagedSpace* space);
1311 1240
(...skipping 10 matching lines...) Expand all
1322 1251
1323 1252
1324 // ----------------------------------------------------------------------------- 1253 // -----------------------------------------------------------------------------
1325 // A space has a circular list of pages. The next page can be accessed via 1254 // A space has a circular list of pages. The next page can be accessed via
1326 // Page::next_page() call. 1255 // Page::next_page() call.
1327 1256
1328 // An abstraction of allocation and relocation pointers in a page-structured 1257 // An abstraction of allocation and relocation pointers in a page-structured
1329 // space. 1258 // space.
1330 class AllocationInfo { 1259 class AllocationInfo {
1331 public: 1260 public:
1332 AllocationInfo() : top_(NULL), limit_(NULL) { 1261 AllocationInfo() : top_(NULL), limit_(NULL) {}
1333 }
1334 1262
1335 INLINE(void set_top(Address top)) { 1263 INLINE(void set_top(Address top)) {
1336 SLOW_DCHECK(top == NULL || 1264 SLOW_DCHECK(top == NULL ||
1337 (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0); 1265 (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0);
1338 top_ = top; 1266 top_ = top;
1339 } 1267 }
1340 1268
1341 INLINE(Address top()) const { 1269 INLINE(Address top()) const {
1342 SLOW_DCHECK(top_ == NULL || 1270 SLOW_DCHECK(top_ == NULL ||
1343 (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0); 1271 (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0);
1344 return top_; 1272 return top_;
1345 } 1273 }
1346 1274
1347 Address* top_address() { 1275 Address* top_address() { return &top_; }
1348 return &top_;
1349 }
1350 1276
1351 INLINE(void set_limit(Address limit)) { 1277 INLINE(void set_limit(Address limit)) {
1352 SLOW_DCHECK(limit == NULL || 1278 SLOW_DCHECK(limit == NULL ||
1353 (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0); 1279 (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0);
1354 limit_ = limit; 1280 limit_ = limit;
1355 } 1281 }
1356 1282
1357 INLINE(Address limit()) const { 1283 INLINE(Address limit()) const {
1358 SLOW_DCHECK(limit_ == NULL || 1284 SLOW_DCHECK(limit_ == NULL ||
1359 (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) == 0); 1285 (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) ==
1286 0);
1360 return limit_; 1287 return limit_;
1361 } 1288 }
1362 1289
1363 Address* limit_address() { 1290 Address* limit_address() { return &limit_; }
1364 return &limit_;
1365 }
1366 1291
1367 #ifdef DEBUG 1292 #ifdef DEBUG
1368 bool VerifyPagedAllocation() { 1293 bool VerifyPagedAllocation() {
1369 return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_)) 1294 return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_)) &&
1370 && (top_ <= limit_); 1295 (top_ <= limit_);
1371 } 1296 }
1372 #endif 1297 #endif
1373 1298
1374 private: 1299 private:
1375 // Current allocation top. 1300 // Current allocation top.
1376 Address top_; 1301 Address top_;
1377 // Current allocation limit. 1302 // Current allocation limit.
1378 Address limit_; 1303 Address limit_;
1379 }; 1304 };
1380 1305
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 }; 1395 };
1471 1396
1472 1397
1473 // ----------------------------------------------------------------------------- 1398 // -----------------------------------------------------------------------------
1474 // Free lists for old object spaces 1399 // Free lists for old object spaces
1475 // 1400 //
1476 // Free-list nodes are free blocks in the heap. They look like heap objects 1401 // Free-list nodes are free blocks in the heap. They look like heap objects
1477 // (free-list node pointers have the heap object tag, and they have a map like 1402 // (free-list node pointers have the heap object tag, and they have a map like
1478 // a heap object). They have a size and a next pointer. The next pointer is 1403 // a heap object). They have a size and a next pointer. The next pointer is
1479 // the raw address of the next free list node (or NULL). 1404 // the raw address of the next free list node (or NULL).
1480 class FreeListNode: public HeapObject { 1405 class FreeListNode : public HeapObject {
1481 public: 1406 public:
1482 // Obtain a free-list node from a raw address. This is not a cast because 1407 // Obtain a free-list node from a raw address. This is not a cast because
1483 // it does not check nor require that the first word at the address is a map 1408 // it does not check nor require that the first word at the address is a map
1484 // pointer. 1409 // pointer.
1485 static FreeListNode* FromAddress(Address address) { 1410 static FreeListNode* FromAddress(Address address) {
1486 return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address)); 1411 return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address));
1487 } 1412 }
1488 1413
1489 static inline bool IsFreeListNode(HeapObject* object); 1414 static inline bool IsFreeListNode(HeapObject* object);
1490 1415
(...skipping 18 matching lines...) Expand all
1509 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); 1434 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize);
1510 1435
1511 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); 1436 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode);
1512 }; 1437 };
1513 1438
1514 1439
1515 // The free list category holds a pointer to the top element and a pointer to 1440 // The free list category holds a pointer to the top element and a pointer to
1516 // the end element of the linked list of free memory blocks. 1441 // the end element of the linked list of free memory blocks.
1517 class FreeListCategory { 1442 class FreeListCategory {
1518 public: 1443 public:
1519 FreeListCategory() : 1444 FreeListCategory() : top_(0), end_(NULL), available_(0) {}
1520 top_(0),
1521 end_(NULL),
1522 available_(0) {}
1523 1445
1524 intptr_t Concatenate(FreeListCategory* category); 1446 intptr_t Concatenate(FreeListCategory* category);
1525 1447
1526 void Reset(); 1448 void Reset();
1527 1449
1528 void Free(FreeListNode* node, int size_in_bytes); 1450 void Free(FreeListNode* node, int size_in_bytes);
1529 1451
1530 FreeListNode* PickNodeFromList(int *node_size); 1452 FreeListNode* PickNodeFromList(int* node_size);
1531 FreeListNode* PickNodeFromList(int size_in_bytes, int *node_size); 1453 FreeListNode* PickNodeFromList(int size_in_bytes, int* node_size);
1532 1454
1533 intptr_t EvictFreeListItemsInList(Page* p); 1455 intptr_t EvictFreeListItemsInList(Page* p);
1534 bool ContainsPageFreeListItemsInList(Page* p); 1456 bool ContainsPageFreeListItemsInList(Page* p);
1535 1457
1536 void RepairFreeList(Heap* heap); 1458 void RepairFreeList(Heap* heap);
1537 1459
1538 FreeListNode* top() const { 1460 FreeListNode* top() const {
1539 return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_)); 1461 return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_));
1540 } 1462 }
1541 1463
1542 void set_top(FreeListNode* top) { 1464 void set_top(FreeListNode* top) {
1543 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); 1465 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top));
1544 } 1466 }
1545 1467
1546 FreeListNode** GetEndAddress() { return &end_; } 1468 FreeListNode** GetEndAddress() { return &end_; }
1547 FreeListNode* end() const { return end_; } 1469 FreeListNode* end() const { return end_; }
1548 void set_end(FreeListNode* end) { end_ = end; } 1470 void set_end(FreeListNode* end) { end_ = end; }
1549 1471
1550 int* GetAvailableAddress() { return &available_; } 1472 int* GetAvailableAddress() { return &available_; }
1551 int available() const { return available_; } 1473 int available() const { return available_; }
1552 void set_available(int available) { available_ = available; } 1474 void set_available(int available) { available_ = available; }
1553 1475
1554 base::Mutex* mutex() { return &mutex_; } 1476 base::Mutex* mutex() { return &mutex_; }
1555 1477
1556 bool IsEmpty() { 1478 bool IsEmpty() { return top() == 0; }
1557 return top() == 0;
1558 }
1559 1479
1560 #ifdef DEBUG 1480 #ifdef DEBUG
1561 intptr_t SumFreeList(); 1481 intptr_t SumFreeList();
1562 int FreeListLength(); 1482 int FreeListLength();
1563 #endif 1483 #endif
1564 1484
1565 private: 1485 private:
1566 // top_ points to the top FreeListNode* in the free list category. 1486 // top_ points to the top FreeListNode* in the free list category.
1567 base::AtomicWord top_; 1487 base::AtomicWord top_;
1568 FreeListNode* end_; 1488 FreeListNode* end_;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 FreeListCategory large_list_; 1604 FreeListCategory large_list_;
1685 FreeListCategory huge_list_; 1605 FreeListCategory huge_list_;
1686 1606
1687 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); 1607 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList);
1688 }; 1608 };
1689 1609
1690 1610
1691 class AllocationResult { 1611 class AllocationResult {
1692 public: 1612 public:
1693 // Implicit constructor from Object*. 1613 // Implicit constructor from Object*.
1694 AllocationResult(Object* object) : object_(object), // NOLINT 1614 explicit AllocationResult(Object* object)
1695 retry_space_(INVALID_SPACE) { } 1615 : object_(object), // NOLINT
1616 retry_space_(INVALID_SPACE) {}
1696 1617
1697 AllocationResult() : object_(NULL), 1618 AllocationResult() : object_(NULL), retry_space_(INVALID_SPACE) {}
1698 retry_space_(INVALID_SPACE) { }
1699 1619
1700 static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) { 1620 static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
1701 return AllocationResult(space); 1621 return AllocationResult(space);
1702 } 1622 }
1703 1623
1704 inline bool IsRetry() { return retry_space_ != INVALID_SPACE; } 1624 inline bool IsRetry() { return retry_space_ != INVALID_SPACE; }
1705 1625
1706 template <typename T> 1626 template <typename T>
1707 bool To(T** obj) { 1627 bool To(T** obj) {
1708 if (IsRetry()) return false; 1628 if (IsRetry()) return false;
1709 *obj = T::cast(object_); 1629 *obj = T::cast(object_);
1710 return true; 1630 return true;
1711 } 1631 }
1712 1632
1713 Object* ToObjectChecked() { 1633 Object* ToObjectChecked() {
1714 CHECK(!IsRetry()); 1634 CHECK(!IsRetry());
1715 return object_; 1635 return object_;
1716 } 1636 }
1717 1637
1718 AllocationSpace RetrySpace() { 1638 AllocationSpace RetrySpace() {
1719 DCHECK(IsRetry()); 1639 DCHECK(IsRetry());
1720 return retry_space_; 1640 return retry_space_;
1721 } 1641 }
1722 1642
1723 private: 1643 private:
1724 explicit AllocationResult(AllocationSpace space) : object_(NULL), 1644 explicit AllocationResult(AllocationSpace space)
1725 retry_space_(space) { } 1645 : object_(NULL), retry_space_(space) {}
1726 1646
1727 Object* object_; 1647 Object* object_;
1728 AllocationSpace retry_space_; 1648 AllocationSpace retry_space_;
1729 }; 1649 };
1730 1650
1731 1651
1732 class PagedSpace : public Space { 1652 class PagedSpace : public Space {
1733 public: 1653 public:
1734 // Creates a space with a maximum capacity, and an id. 1654 // Creates a space with a maximum capacity, and an id.
1735 PagedSpace(Heap* heap, 1655 PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id,
1736 intptr_t max_capacity,
1737 AllocationSpace id,
1738 Executability executable); 1656 Executability executable);
1739 1657
1740 virtual ~PagedSpace() {} 1658 virtual ~PagedSpace() {}
1741 1659
1742 // Set up the space using the given address range of virtual memory (from 1660 // Set up the space using the given address range of virtual memory (from
1743 // the memory allocator's initial chunk) if possible. If the block of 1661 // the memory allocator's initial chunk) if possible. If the block of
1744 // addresses is not big enough to contain a single page-aligned page, a 1662 // addresses is not big enough to contain a single page-aligned page, a
1745 // fresh chunk will be allocated. 1663 // fresh chunk will be allocated.
1746 bool SetUp(); 1664 bool SetUp();
1747 1665
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 // Wasted bytes in this space. These are just the bytes that were thrown away 1749 // Wasted bytes in this space. These are just the bytes that were thrown away
1832 // due to being too small to use for allocation. They do not include the 1750 // due to being too small to use for allocation. They do not include the
1833 // free bytes that were not found at all due to lazy sweeping. 1751 // free bytes that were not found at all due to lazy sweeping.
1834 virtual intptr_t Waste() { return accounting_stats_.Waste(); } 1752 virtual intptr_t Waste() { return accounting_stats_.Waste(); }
1835 1753
1836 // Returns the allocation pointer in this space. 1754 // Returns the allocation pointer in this space.
1837 Address top() { return allocation_info_.top(); } 1755 Address top() { return allocation_info_.top(); }
1838 Address limit() { return allocation_info_.limit(); } 1756 Address limit() { return allocation_info_.limit(); }
1839 1757
1840 // The allocation top address. 1758 // The allocation top address.
1841 Address* allocation_top_address() { 1759 Address* allocation_top_address() { return allocation_info_.top_address(); }
1842 return allocation_info_.top_address();
1843 }
1844 1760
1845 // The allocation limit address. 1761 // The allocation limit address.
1846 Address* allocation_limit_address() { 1762 Address* allocation_limit_address() {
1847 return allocation_info_.limit_address(); 1763 return allocation_info_.limit_address();
1848 } 1764 }
1849 1765
1850 // Allocate the requested number of bytes in the space if possible, return a 1766 // Allocate the requested number of bytes in the space if possible, return a
1851 // failure object if not. 1767 // failure object if not.
1852 MUST_USE_RESULT inline AllocationResult AllocateRaw(int size_in_bytes); 1768 MUST_USE_RESULT inline AllocationResult AllocateRaw(int size_in_bytes);
1853 1769
1854 // Give a block of memory to the space's free list. It might be added to 1770 // Give a block of memory to the space's free list. It might be added to
1855 // the free list or accounted as waste. 1771 // the free list or accounted as waste.
1856 // If add_to_freelist is false then just accounting stats are updated and 1772 // If add_to_freelist is false then just accounting stats are updated and
1857 // no attempt to add area to free list is made. 1773 // no attempt to add area to free list is made.
1858 int Free(Address start, int size_in_bytes) { 1774 int Free(Address start, int size_in_bytes) {
1859 int wasted = free_list_.Free(start, size_in_bytes); 1775 int wasted = free_list_.Free(start, size_in_bytes);
1860 accounting_stats_.DeallocateBytes(size_in_bytes); 1776 accounting_stats_.DeallocateBytes(size_in_bytes);
1861 accounting_stats_.WasteBytes(wasted); 1777 accounting_stats_.WasteBytes(wasted);
1862 return size_in_bytes - wasted; 1778 return size_in_bytes - wasted;
1863 } 1779 }
1864 1780
1865 void ResetFreeList() { 1781 void ResetFreeList() { free_list_.Reset(); }
1866 free_list_.Reset();
1867 }
1868 1782
1869 // Set space allocation info. 1783 // Set space allocation info.
1870 void SetTopAndLimit(Address top, Address limit) { 1784 void SetTopAndLimit(Address top, Address limit) {
1871 DCHECK(top == limit || 1785 DCHECK(top == limit ||
1872 Page::FromAddress(top) == Page::FromAddress(limit - 1)); 1786 Page::FromAddress(top) == Page::FromAddress(limit - 1));
1873 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); 1787 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
1874 allocation_info_.set_top(top); 1788 allocation_info_.set_top(top);
1875 allocation_info_.set_limit(limit); 1789 allocation_info_.set_limit(limit);
1876 } 1790 }
1877 1791
1878 // Empty space allocation info, returning unused area to free list. 1792 // Empty space allocation info, returning unused area to free list.
1879 void EmptyAllocationInfo() { 1793 void EmptyAllocationInfo() {
1880 // Mark the old linear allocation area with a free space map so it can be 1794 // Mark the old linear allocation area with a free space map so it can be
1881 // skipped when scanning the heap. 1795 // skipped when scanning the heap.
1882 int old_linear_size = static_cast<int>(limit() - top()); 1796 int old_linear_size = static_cast<int>(limit() - top());
1883 Free(top(), old_linear_size); 1797 Free(top(), old_linear_size);
1884 SetTopAndLimit(NULL, NULL); 1798 SetTopAndLimit(NULL, NULL);
1885 } 1799 }
1886 1800
1887 void Allocate(int bytes) { 1801 void Allocate(int bytes) { accounting_stats_.AllocateBytes(bytes); }
1888 accounting_stats_.AllocateBytes(bytes);
1889 }
1890 1802
1891 void IncreaseCapacity(int size); 1803 void IncreaseCapacity(int size);
1892 1804
1893 // Releases an unused page and shrinks the space. 1805 // Releases an unused page and shrinks the space.
1894 void ReleasePage(Page* page); 1806 void ReleasePage(Page* page);
1895 1807
1896 // The dummy page that anchors the linked list of pages. 1808 // The dummy page that anchors the linked list of pages.
1897 Page* anchor() { return &anchor_; } 1809 Page* anchor() { return &anchor_; }
1898 1810
1899 #ifdef VERIFY_HEAP 1811 #ifdef VERIFY_HEAP
(...skipping 18 matching lines...) Expand all
1918 static void ResetCodeStatistics(Isolate* isolate); 1830 static void ResetCodeStatistics(Isolate* isolate);
1919 #endif 1831 #endif
1920 1832
1921 bool swept_precisely() { return swept_precisely_; } 1833 bool swept_precisely() { return swept_precisely_; }
1922 void set_swept_precisely(bool b) { swept_precisely_ = b; } 1834 void set_swept_precisely(bool b) { swept_precisely_ = b; }
1923 1835
1924 // Evacuation candidates are swept by evacuator. Needs to return a valid 1836 // Evacuation candidates are swept by evacuator. Needs to return a valid
1925 // result before _and_ after evacuation has finished. 1837 // result before _and_ after evacuation has finished.
1926 static bool ShouldBeSweptBySweeperThreads(Page* p) { 1838 static bool ShouldBeSweptBySweeperThreads(Page* p) {
1927 return !p->IsEvacuationCandidate() && 1839 return !p->IsEvacuationCandidate() &&
1928 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && 1840 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && !p->WasSweptPrecisely();
1929 !p->WasSweptPrecisely();
1930 } 1841 }
1931 1842
1932 void IncrementUnsweptFreeBytes(intptr_t by) { 1843 void IncrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ += by; }
1933 unswept_free_bytes_ += by;
1934 }
1935 1844
1936 void IncreaseUnsweptFreeBytes(Page* p) { 1845 void IncreaseUnsweptFreeBytes(Page* p) {
1937 DCHECK(ShouldBeSweptBySweeperThreads(p)); 1846 DCHECK(ShouldBeSweptBySweeperThreads(p));
1938 unswept_free_bytes_ += (p->area_size() - p->LiveBytes()); 1847 unswept_free_bytes_ += (p->area_size() - p->LiveBytes());
1939 } 1848 }
1940 1849
1941 void DecrementUnsweptFreeBytes(intptr_t by) { 1850 void DecrementUnsweptFreeBytes(intptr_t by) { unswept_free_bytes_ -= by; }
1942 unswept_free_bytes_ -= by;
1943 }
1944 1851
1945 void DecreaseUnsweptFreeBytes(Page* p) { 1852 void DecreaseUnsweptFreeBytes(Page* p) {
1946 DCHECK(ShouldBeSweptBySweeperThreads(p)); 1853 DCHECK(ShouldBeSweptBySweeperThreads(p));
1947 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes()); 1854 unswept_free_bytes_ -= (p->area_size() - p->LiveBytes());
1948 } 1855 }
1949 1856
1950 void ResetUnsweptFreeBytes() { 1857 void ResetUnsweptFreeBytes() { unswept_free_bytes_ = 0; }
1951 unswept_free_bytes_ = 0;
1952 }
1953 1858
1954 // This function tries to steal size_in_bytes memory from the sweeper threads 1859 // This function tries to steal size_in_bytes memory from the sweeper threads
1955 // free-lists. If it does not succeed stealing enough memory, it will wait 1860 // free-lists. If it does not succeed stealing enough memory, it will wait
1956 // for the sweeper threads to finish sweeping. 1861 // for the sweeper threads to finish sweeping.
1957 // It returns true when sweeping is completed and false otherwise. 1862 // It returns true when sweeping is completed and false otherwise.
1958 bool EnsureSweeperProgress(intptr_t size_in_bytes); 1863 bool EnsureSweeperProgress(intptr_t size_in_bytes);
1959 1864
1960 void set_end_of_unswept_pages(Page* page) { 1865 void set_end_of_unswept_pages(Page* page) { end_of_unswept_pages_ = page; }
1961 end_of_unswept_pages_ = page;
1962 }
1963 1866
1964 Page* end_of_unswept_pages() { 1867 Page* end_of_unswept_pages() { return end_of_unswept_pages_; }
1965 return end_of_unswept_pages_;
1966 }
1967 1868
1968 Page* FirstPage() { return anchor_.next_page(); } 1869 Page* FirstPage() { return anchor_.next_page(); }
1969 Page* LastPage() { return anchor_.prev_page(); } 1870 Page* LastPage() { return anchor_.prev_page(); }
1970 1871
1971 void EvictEvacuationCandidatesFromFreeLists(); 1872 void EvictEvacuationCandidatesFromFreeLists();
1972 1873
1973 bool CanExpand(); 1874 bool CanExpand();
1974 1875
1975 // Returns the number of total pages in this space. 1876 // Returns the number of total pages in this space.
1976 int CountTotalPages(); 1877 int CountTotalPages();
1977 1878
1978 // Return size of allocatable area on a page in this space. 1879 // Return size of allocatable area on a page in this space.
1979 inline int AreaSize() { 1880 inline int AreaSize() { return area_size_; }
1980 return area_size_;
1981 }
1982 1881
1983 void CreateEmergencyMemory(); 1882 void CreateEmergencyMemory();
1984 void FreeEmergencyMemory(); 1883 void FreeEmergencyMemory();
1985 void UseEmergencyMemory(); 1884 void UseEmergencyMemory();
1986 1885
1987 bool HasEmergencyMemory() { return emergency_memory_ != NULL; } 1886 bool HasEmergencyMemory() { return emergency_memory_ != NULL; }
1988 1887
1989 protected: 1888 protected:
1990 FreeList* free_list() { return &free_list_; } 1889 FreeList* free_list() { return &free_list_; }
1991 1890
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 } 1965 }
2067 1966
2068 private: 1967 private:
2069 int number_; 1968 int number_;
2070 int bytes_; 1969 int bytes_;
2071 }; 1970 };
2072 1971
2073 1972
2074 // HistogramInfo class for recording a single "bar" of a histogram. This 1973 // HistogramInfo class for recording a single "bar" of a histogram. This
2075 // class is used for collecting statistics to print to the log file. 1974 // class is used for collecting statistics to print to the log file.
2076 class HistogramInfo: public NumberAndSizeInfo { 1975 class HistogramInfo : public NumberAndSizeInfo {
2077 public: 1976 public:
2078 HistogramInfo() : NumberAndSizeInfo() {} 1977 HistogramInfo() : NumberAndSizeInfo() {}
2079 1978
2080 const char* name() { return name_; } 1979 const char* name() { return name_; }
2081 void set_name(const char* name) { name_ = name; } 1980 void set_name(const char* name) { name_ = name; }
2082 1981
2083 private: 1982 private:
2084 const char* name_; 1983 const char* name_;
2085 }; 1984 };
2086 1985
2087 1986
2088 enum SemiSpaceId { 1987 enum SemiSpaceId { kFromSpace = 0, kToSpace = 1 };
2089 kFromSpace = 0,
2090 kToSpace = 1
2091 };
2092 1988
2093 1989
2094 class SemiSpace; 1990 class SemiSpace;
2095 1991
2096 1992
2097 class NewSpacePage : public MemoryChunk { 1993 class NewSpacePage : public MemoryChunk {
2098 public: 1994 public:
2099 // GC related flags copied from from-space to to-space when 1995 // GC related flags copied from from-space to to-space when
2100 // flipping semispaces. 1996 // flipping semispaces.
2101 static const intptr_t kCopyOnFlipFlagsMask = 1997 static const intptr_t kCopyOnFlipFlagsMask =
2102 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | 1998 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) |
2103 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | 1999 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) |
2104 (1 << MemoryChunk::SCAN_ON_SCAVENGE); 2000 (1 << MemoryChunk::SCAN_ON_SCAVENGE);
2105 2001
2106 static const int kAreaSize = Page::kMaxRegularHeapObjectSize; 2002 static const int kAreaSize = Page::kMaxRegularHeapObjectSize;
2107 2003
2108 inline NewSpacePage* next_page() const { 2004 inline NewSpacePage* next_page() const {
2109 return static_cast<NewSpacePage*>(next_chunk()); 2005 return static_cast<NewSpacePage*>(next_chunk());
2110 } 2006 }
2111 2007
2112 inline void set_next_page(NewSpacePage* page) { 2008 inline void set_next_page(NewSpacePage* page) { set_next_chunk(page); }
2113 set_next_chunk(page);
2114 }
2115 2009
2116 inline NewSpacePage* prev_page() const { 2010 inline NewSpacePage* prev_page() const {
2117 return static_cast<NewSpacePage*>(prev_chunk()); 2011 return static_cast<NewSpacePage*>(prev_chunk());
2118 } 2012 }
2119 2013
2120 inline void set_prev_page(NewSpacePage* page) { 2014 inline void set_prev_page(NewSpacePage* page) { set_prev_chunk(page); }
2121 set_prev_chunk(page);
2122 }
2123 2015
2124 SemiSpace* semi_space() { 2016 SemiSpace* semi_space() { return reinterpret_cast<SemiSpace*>(owner()); }
2125 return reinterpret_cast<SemiSpace*>(owner());
2126 }
2127 2017
2128 bool is_anchor() { return !this->InNewSpace(); } 2018 bool is_anchor() { return !this->InNewSpace(); }
2129 2019
2130 static bool IsAtStart(Address addr) { 2020 static bool IsAtStart(Address addr) {
2131 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) 2021 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) ==
2132 == kObjectStartOffset; 2022 kObjectStartOffset;
2133 } 2023 }
2134 2024
2135 static bool IsAtEnd(Address addr) { 2025 static bool IsAtEnd(Address addr) {
2136 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; 2026 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0;
2137 } 2027 }
2138 2028
2139 Address address() { 2029 Address address() { return reinterpret_cast<Address>(this); }
2140 return reinterpret_cast<Address>(this);
2141 }
2142 2030
2143 // Finds the NewSpacePage containg the given address. 2031 // Finds the NewSpacePage containg the given address.
2144 static inline NewSpacePage* FromAddress(Address address_in_page) { 2032 static inline NewSpacePage* FromAddress(Address address_in_page) {
2145 Address page_start = 2033 Address page_start =
2146 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) & 2034 reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) &
2147 ~Page::kPageAlignmentMask); 2035 ~Page::kPageAlignmentMask);
2148 NewSpacePage* page = reinterpret_cast<NewSpacePage*>(page_start); 2036 NewSpacePage* page = reinterpret_cast<NewSpacePage*>(page_start);
2149 return page; 2037 return page;
2150 } 2038 }
2151 2039
2152 // Find the page for a limit address. A limit address is either an address 2040 // Find the page for a limit address. A limit address is either an address
2153 // inside a page, or the address right after the last byte of a page. 2041 // inside a page, or the address right after the last byte of a page.
2154 static inline NewSpacePage* FromLimit(Address address_limit) { 2042 static inline NewSpacePage* FromLimit(Address address_limit) {
2155 return NewSpacePage::FromAddress(address_limit - 1); 2043 return NewSpacePage::FromAddress(address_limit - 1);
2156 } 2044 }
2157 2045
2158 // Checks if address1 and address2 are on the same new space page. 2046 // Checks if address1 and address2 are on the same new space page.
2159 static inline bool OnSamePage(Address address1, Address address2) { 2047 static inline bool OnSamePage(Address address1, Address address2) {
2160 return NewSpacePage::FromAddress(address1) == 2048 return NewSpacePage::FromAddress(address1) ==
2161 NewSpacePage::FromAddress(address2); 2049 NewSpacePage::FromAddress(address2);
2162 } 2050 }
2163 2051
2164 private: 2052 private:
2165 // Create a NewSpacePage object that is only used as anchor 2053 // Create a NewSpacePage object that is only used as anchor
2166 // for the doubly-linked list of real pages. 2054 // for the doubly-linked list of real pages.
2167 explicit NewSpacePage(SemiSpace* owner) { 2055 explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); }
2168 InitializeAsAnchor(owner);
2169 }
2170 2056
2171 static NewSpacePage* Initialize(Heap* heap, 2057 static NewSpacePage* Initialize(Heap* heap, Address start,
2172 Address start,
2173 SemiSpace* semi_space); 2058 SemiSpace* semi_space);
2174 2059
2175 // Intialize a fake NewSpacePage used as sentinel at the ends 2060 // Intialize a fake NewSpacePage used as sentinel at the ends
2176 // of a doubly-linked list of real NewSpacePages. 2061 // of a doubly-linked list of real NewSpacePages.
2177 // Only uses the prev/next links, and sets flags to not be in new-space. 2062 // Only uses the prev/next links, and sets flags to not be in new-space.
2178 void InitializeAsAnchor(SemiSpace* owner); 2063 void InitializeAsAnchor(SemiSpace* owner);
2179 2064
2180 friend class SemiSpace; 2065 friend class SemiSpace;
2181 friend class SemiSpaceIterator; 2066 friend class SemiSpaceIterator;
2182 }; 2067 };
2183 2068
2184 2069
2185 // ----------------------------------------------------------------------------- 2070 // -----------------------------------------------------------------------------
2186 // SemiSpace in young generation 2071 // SemiSpace in young generation
2187 // 2072 //
2188 // A semispace is a contiguous chunk of memory holding page-like memory 2073 // A semispace is a contiguous chunk of memory holding page-like memory
2189 // chunks. The mark-compact collector uses the memory of the first page in 2074 // chunks. The mark-compact collector uses the memory of the first page in
2190 // the from space as a marking stack when tracing live objects. 2075 // the from space as a marking stack when tracing live objects.
2191 2076
2192 class SemiSpace : public Space { 2077 class SemiSpace : public Space {
2193 public: 2078 public:
2194 // Constructor. 2079 // Constructor.
2195 SemiSpace(Heap* heap, SemiSpaceId semispace) 2080 SemiSpace(Heap* heap, SemiSpaceId semispace)
2196 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2081 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2197 start_(NULL), 2082 start_(NULL),
2198 age_mark_(NULL), 2083 age_mark_(NULL),
2199 id_(semispace), 2084 id_(semispace),
2200 anchor_(this), 2085 anchor_(this),
2201 current_page_(NULL) { } 2086 current_page_(NULL) {}
2202 2087
2203 // Sets up the semispace using the given chunk. 2088 // Sets up the semispace using the given chunk.
2204 void SetUp(Address start, int initial_capacity, int maximum_capacity); 2089 void SetUp(Address start, int initial_capacity, int maximum_capacity);
2205 2090
2206 // Tear down the space. Heap memory was not allocated by the space, so it 2091 // Tear down the space. Heap memory was not allocated by the space, so it
2207 // is not deallocated here. 2092 // is not deallocated here.
2208 void TearDown(); 2093 void TearDown();
2209 2094
2210 // True if the space has been set up but not torn down. 2095 // True if the space has been set up but not torn down.
2211 bool HasBeenSetUp() { return start_ != NULL; } 2096 bool HasBeenSetUp() { return start_ != NULL; }
2212 2097
2213 // Grow the semispace to the new capacity. The new capacity 2098 // Grow the semispace to the new capacity. The new capacity
2214 // requested must be larger than the current capacity and less than 2099 // requested must be larger than the current capacity and less than
2215 // the maximum capacity. 2100 // the maximum capacity.
2216 bool GrowTo(int new_capacity); 2101 bool GrowTo(int new_capacity);
2217 2102
2218 // Shrinks the semispace to the new capacity. The new capacity 2103 // Shrinks the semispace to the new capacity. The new capacity
2219 // requested must be more than the amount of used memory in the 2104 // requested must be more than the amount of used memory in the
2220 // semispace and less than the current capacity. 2105 // semispace and less than the current capacity.
2221 bool ShrinkTo(int new_capacity); 2106 bool ShrinkTo(int new_capacity);
2222 2107
2223 // Returns the start address of the first page of the space. 2108 // Returns the start address of the first page of the space.
2224 Address space_start() { 2109 Address space_start() {
2225 DCHECK(anchor_.next_page() != &anchor_); 2110 DCHECK(anchor_.next_page() != &anchor_);
2226 return anchor_.next_page()->area_start(); 2111 return anchor_.next_page()->area_start();
2227 } 2112 }
2228 2113
2229 // Returns the start address of the current page of the space. 2114 // Returns the start address of the current page of the space.
2230 Address page_low() { 2115 Address page_low() { return current_page_->area_start(); }
2231 return current_page_->area_start();
2232 }
2233 2116
2234 // Returns one past the end address of the space. 2117 // Returns one past the end address of the space.
2235 Address space_end() { 2118 Address space_end() { return anchor_.prev_page()->area_end(); }
2236 return anchor_.prev_page()->area_end();
2237 }
2238 2119
2239 // Returns one past the end address of the current page of the space. 2120 // Returns one past the end address of the current page of the space.
2240 Address page_high() { 2121 Address page_high() { return current_page_->area_end(); }
2241 return current_page_->area_end();
2242 }
2243 2122
2244 bool AdvancePage() { 2123 bool AdvancePage() {
2245 NewSpacePage* next_page = current_page_->next_page(); 2124 NewSpacePage* next_page = current_page_->next_page();
2246 if (next_page == anchor()) return false; 2125 if (next_page == anchor()) return false;
2247 current_page_ = next_page; 2126 current_page_ = next_page;
2248 return true; 2127 return true;
2249 } 2128 }
2250 2129
2251 // Resets the space to using the first page. 2130 // Resets the space to using the first page.
2252 void Reset(); 2131 void Reset();
2253 2132
2254 // Age mark accessors. 2133 // Age mark accessors.
2255 Address age_mark() { return age_mark_; } 2134 Address age_mark() { return age_mark_; }
2256 void set_age_mark(Address mark); 2135 void set_age_mark(Address mark);
2257 2136
2258 // True if the address is in the address range of this semispace (not 2137 // True if the address is in the address range of this semispace (not
2259 // necessarily below the allocation pointer). 2138 // necessarily below the allocation pointer).
2260 bool Contains(Address a) { 2139 bool Contains(Address a) {
2261 return (reinterpret_cast<uintptr_t>(a) & address_mask_) 2140 return (reinterpret_cast<uintptr_t>(a) & address_mask_) ==
2262 == reinterpret_cast<uintptr_t>(start_); 2141 reinterpret_cast<uintptr_t>(start_);
2263 } 2142 }
2264 2143
2265 // True if the object is a heap object in the address range of this 2144 // True if the object is a heap object in the address range of this
2266 // semispace (not necessarily below the allocation pointer). 2145 // semispace (not necessarily below the allocation pointer).
2267 bool Contains(Object* o) { 2146 bool Contains(Object* o) {
2268 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; 2147 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_;
2269 } 2148 }
2270 2149
2271 // If we don't have these here then SemiSpace will be abstract. However 2150 // If we don't have these here then SemiSpace will be abstract. However
2272 // they should never be called. 2151 // they should never be called.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2344 uintptr_t object_expected_; 2223 uintptr_t object_expected_;
2345 2224
2346 bool committed_; 2225 bool committed_;
2347 SemiSpaceId id_; 2226 SemiSpaceId id_;
2348 2227
2349 NewSpacePage anchor_; 2228 NewSpacePage anchor_;
2350 NewSpacePage* current_page_; 2229 NewSpacePage* current_page_;
2351 2230
2352 friend class SemiSpaceIterator; 2231 friend class SemiSpaceIterator;
2353 friend class NewSpacePageIterator; 2232 friend class NewSpacePageIterator;
2233
2354 public: 2234 public:
2355 TRACK_MEMORY("SemiSpace") 2235 TRACK_MEMORY("SemiSpace")
2356 }; 2236 };
2357 2237
2358 2238
2359 // A SemiSpaceIterator is an ObjectIterator that iterates over the active 2239 // A SemiSpaceIterator is an ObjectIterator that iterates over the active
2360 // semispace of the heap's new space. It iterates over the objects in the 2240 // semispace of the heap's new space. It iterates over the objects in the
2361 // semispace from a given start address (defaulting to the bottom of the 2241 // semispace from a given start address (defaulting to the bottom of the
2362 // semispace) to the top of the semispace. New objects allocated after the 2242 // semispace) to the top of the semispace. New objects allocated after the
2363 // iterator is created are not iterated. 2243 // iterator is created are not iterated.
(...skipping 27 matching lines...) Expand all
2391 int size = (size_func_ == NULL) ? object->Size() : size_func_(object); 2271 int size = (size_func_ == NULL) ? object->Size() : size_func_(object);
2392 2272
2393 current_ += size; 2273 current_ += size;
2394 return object; 2274 return object;
2395 } 2275 }
2396 2276
2397 // Implementation of the ObjectIterator functions. 2277 // Implementation of the ObjectIterator functions.
2398 virtual HeapObject* next_object() { return Next(); } 2278 virtual HeapObject* next_object() { return Next(); }
2399 2279
2400 private: 2280 private:
2401 void Initialize(Address start, 2281 void Initialize(Address start, Address end, HeapObjectCallback size_func);
2402 Address end,
2403 HeapObjectCallback size_func);
2404 2282
2405 // The current iteration point. 2283 // The current iteration point.
2406 Address current_; 2284 Address current_;
2407 // The end of iteration. 2285 // The end of iteration.
2408 Address limit_; 2286 Address limit_;
2409 // The callback function. 2287 // The callback function.
2410 HeapObjectCallback size_func_; 2288 HeapObjectCallback size_func_;
2411 }; 2289 };
2412 2290
2413 2291
(...skipping 28 matching lines...) Expand all
2442 // ----------------------------------------------------------------------------- 2320 // -----------------------------------------------------------------------------
2443 // The young generation space. 2321 // The young generation space.
2444 // 2322 //
2445 // The new space consists of a contiguous pair of semispaces. It simply 2323 // The new space consists of a contiguous pair of semispaces. It simply
2446 // forwards most functions to the appropriate semispace. 2324 // forwards most functions to the appropriate semispace.
2447 2325
2448 class NewSpace : public Space { 2326 class NewSpace : public Space {
2449 public: 2327 public:
2450 // Constructor. 2328 // Constructor.
2451 explicit NewSpace(Heap* heap) 2329 explicit NewSpace(Heap* heap)
2452 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2330 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2453 to_space_(heap, kToSpace), 2331 to_space_(heap, kToSpace),
2454 from_space_(heap, kFromSpace), 2332 from_space_(heap, kFromSpace),
2455 reservation_(), 2333 reservation_(),
2456 inline_allocation_limit_step_(0) {} 2334 inline_allocation_limit_step_(0) {}
2457 2335
2458 // Sets up the new space using the given chunk. 2336 // Sets up the new space using the given chunk.
2459 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); 2337 bool SetUp(int reserved_semispace_size_, int max_semi_space_size);
2460 2338
2461 // Tears down the space. Heap memory was not allocated by the space, so it 2339 // Tears down the space. Heap memory was not allocated by the space, so it
2462 // is not deallocated here. 2340 // is not deallocated here.
2463 void TearDown(); 2341 void TearDown();
2464 2342
2465 // True if the space has been set up but not torn down. 2343 // True if the space has been set up but not torn down.
2466 bool HasBeenSetUp() { 2344 bool HasBeenSetUp() {
2467 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); 2345 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp();
2468 } 2346 }
2469 2347
2470 // Flip the pair of spaces. 2348 // Flip the pair of spaces.
2471 void Flip(); 2349 void Flip();
2472 2350
2473 // Grow the capacity of the semispaces. Assumes that they are not at 2351 // Grow the capacity of the semispaces. Assumes that they are not at
2474 // their maximum capacity. 2352 // their maximum capacity.
2475 void Grow(); 2353 void Grow();
2476 2354
2477 // Shrink the capacity of the semispaces. 2355 // Shrink the capacity of the semispaces.
2478 void Shrink(); 2356 void Shrink();
2479 2357
2480 // True if the address or object lies in the address range of either 2358 // True if the address or object lies in the address range of either
2481 // semispace (not necessarily below the allocation pointer). 2359 // semispace (not necessarily below the allocation pointer).
2482 bool Contains(Address a) { 2360 bool Contains(Address a) {
2483 return (reinterpret_cast<uintptr_t>(a) & address_mask_) 2361 return (reinterpret_cast<uintptr_t>(a) & address_mask_) ==
2484 == reinterpret_cast<uintptr_t>(start_); 2362 reinterpret_cast<uintptr_t>(start_);
2485 } 2363 }
2486 2364
2487 bool Contains(Object* o) { 2365 bool Contains(Object* o) {
2488 Address a = reinterpret_cast<Address>(o); 2366 Address a = reinterpret_cast<Address>(o);
2489 return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_; 2367 return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_;
2490 } 2368 }
2491 2369
2492 // Return the allocated bytes in the active semispace. 2370 // Return the allocated bytes in the active semispace.
2493 virtual intptr_t Size() { 2371 virtual intptr_t Size() {
2494 return pages_used_ * NewSpacePage::kAreaSize + 2372 return pages_used_ * NewSpacePage::kAreaSize +
2495 static_cast<int>(top() - to_space_.page_low()); 2373 static_cast<int>(top() - to_space_.page_low());
2496 } 2374 }
2497 2375
2498 // The same, but returning an int. We have to have the one that returns 2376 // The same, but returning an int. We have to have the one that returns
2499 // intptr_t because it is inherited, but if we know we are dealing with the 2377 // intptr_t because it is inherited, but if we know we are dealing with the
2500 // new space, which can't get as big as the other spaces then this is useful: 2378 // new space, which can't get as big as the other spaces then this is useful:
2501 int SizeAsInt() { return static_cast<int>(Size()); } 2379 int SizeAsInt() { return static_cast<int>(Size()); }
2502 2380
2503 // Return the current capacity of a semispace. 2381 // Return the current capacity of a semispace.
2504 intptr_t EffectiveCapacity() { 2382 intptr_t EffectiveCapacity() {
2505 SLOW_DCHECK(to_space_.Capacity() == from_space_.Capacity()); 2383 SLOW_DCHECK(to_space_.Capacity() == from_space_.Capacity());
2506 return (to_space_.Capacity() / Page::kPageSize) * NewSpacePage::kAreaSize; 2384 return (to_space_.Capacity() / Page::kPageSize) * NewSpacePage::kAreaSize;
2507 } 2385 }
2508 2386
2509 // Return the current capacity of a semispace. 2387 // Return the current capacity of a semispace.
2510 intptr_t Capacity() { 2388 intptr_t Capacity() {
2511 DCHECK(to_space_.Capacity() == from_space_.Capacity()); 2389 DCHECK(to_space_.Capacity() == from_space_.Capacity());
2512 return to_space_.Capacity(); 2390 return to_space_.Capacity();
2513 } 2391 }
2514 2392
2515 // Return the total amount of memory committed for new space. 2393 // Return the total amount of memory committed for new space.
2516 intptr_t CommittedMemory() { 2394 intptr_t CommittedMemory() {
2517 if (from_space_.is_committed()) return 2 * Capacity(); 2395 if (from_space_.is_committed()) return 2 * Capacity();
2518 return Capacity(); 2396 return Capacity();
2519 } 2397 }
2520 2398
2521 // Return the total amount of memory committed for new space. 2399 // Return the total amount of memory committed for new space.
2522 intptr_t MaximumCommittedMemory() { 2400 intptr_t MaximumCommittedMemory() {
2523 return to_space_.MaximumCommittedMemory() + 2401 return to_space_.MaximumCommittedMemory() +
2524 from_space_.MaximumCommittedMemory(); 2402 from_space_.MaximumCommittedMemory();
2525 } 2403 }
2526 2404
2527 // Approximate amount of physical memory committed for this space. 2405 // Approximate amount of physical memory committed for this space.
2528 size_t CommittedPhysicalMemory(); 2406 size_t CommittedPhysicalMemory();
2529 2407
2530 // Return the available bytes without growing. 2408 // Return the available bytes without growing.
2531 intptr_t Available() { 2409 intptr_t Available() { return Capacity() - Size(); }
2532 return Capacity() - Size();
2533 }
2534 2410
2535 // Return the maximum capacity of a semispace. 2411 // Return the maximum capacity of a semispace.
2536 int MaximumCapacity() { 2412 int MaximumCapacity() {
2537 DCHECK(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); 2413 DCHECK(to_space_.MaximumCapacity() == from_space_.MaximumCapacity());
2538 return to_space_.MaximumCapacity(); 2414 return to_space_.MaximumCapacity();
2539 } 2415 }
2540 2416
2541 bool IsAtMaximumCapacity() { 2417 bool IsAtMaximumCapacity() { return Capacity() == MaximumCapacity(); }
2542 return Capacity() == MaximumCapacity();
2543 }
2544 2418
2545 // Returns the initial capacity of a semispace. 2419 // Returns the initial capacity of a semispace.
2546 int InitialCapacity() { 2420 int InitialCapacity() {
2547 DCHECK(to_space_.InitialCapacity() == from_space_.InitialCapacity()); 2421 DCHECK(to_space_.InitialCapacity() == from_space_.InitialCapacity());
2548 return to_space_.InitialCapacity(); 2422 return to_space_.InitialCapacity();
2549 } 2423 }
2550 2424
2551 // Return the address of the allocation pointer in the active semispace. 2425 // Return the address of the allocation pointer in the active semispace.
2552 Address top() { 2426 Address top() {
2553 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.top())); 2427 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.top()));
(...skipping 29 matching lines...) Expand all
2583 DCHECK(IsAligned(OffsetFrom(addr), kPointerSize) || 2457 DCHECK(IsAligned(OffsetFrom(addr), kPointerSize) ||
2584 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); 2458 IsAligned(OffsetFrom(addr) - 1, kPointerSize));
2585 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; 2459 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2;
2586 } 2460 }
2587 2461
2588 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { 2462 INLINE(Address MarkbitIndexToAddress(uint32_t index)) {
2589 return reinterpret_cast<Address>(index << kPointerSizeLog2); 2463 return reinterpret_cast<Address>(index << kPointerSizeLog2);
2590 } 2464 }
2591 2465
2592 // The allocation top and limit address. 2466 // The allocation top and limit address.
2593 Address* allocation_top_address() { 2467 Address* allocation_top_address() { return allocation_info_.top_address(); }
2594 return allocation_info_.top_address();
2595 }
2596 2468
2597 // The allocation limit address. 2469 // The allocation limit address.
2598 Address* allocation_limit_address() { 2470 Address* allocation_limit_address() {
2599 return allocation_info_.limit_address(); 2471 return allocation_info_.limit_address();
2600 } 2472 }
2601 2473
2602 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(int size_in_bytes)); 2474 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(int size_in_bytes));
2603 2475
2604 // Reset the allocation pointer to the beginning of the active semispace. 2476 // Reset the allocation pointer to the beginning of the active semispace.
2605 void ResetAllocationInfo(); 2477 void ResetAllocationInfo();
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 }; 2597 };
2726 2598
2727 2599
2728 // ----------------------------------------------------------------------------- 2600 // -----------------------------------------------------------------------------
2729 // Old object space (excluding map objects) 2601 // Old object space (excluding map objects)
2730 2602
2731 class OldSpace : public PagedSpace { 2603 class OldSpace : public PagedSpace {
2732 public: 2604 public:
2733 // Creates an old space object with a given maximum capacity. 2605 // Creates an old space object with a given maximum capacity.
2734 // The constructor does not allocate pages from OS. 2606 // The constructor does not allocate pages from OS.
2735 OldSpace(Heap* heap, 2607 OldSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id,
2736 intptr_t max_capacity,
2737 AllocationSpace id,
2738 Executability executable) 2608 Executability executable)
2739 : PagedSpace(heap, max_capacity, id, executable) { 2609 : PagedSpace(heap, max_capacity, id, executable) {}
2740 }
2741 2610
2742 public: 2611 public:
2743 TRACK_MEMORY("OldSpace") 2612 TRACK_MEMORY("OldSpace")
2744 }; 2613 };
2745 2614
2746 2615
2747 // For contiguous spaces, top should be in the space (or at the end) and limit 2616 // For contiguous spaces, top should be in the space (or at the end) and limit
2748 // should be the end of the space. 2617 // should be the end of the space.
2749 #define DCHECK_SEMISPACE_ALLOCATION_INFO(info, space) \ 2618 #define DCHECK_SEMISPACE_ALLOCATION_INFO(info, space) \
2750 SLOW_DCHECK((space).page_low() <= (info).top() \ 2619 SLOW_DCHECK((space).page_low() <= (info).top() && \
2751 && (info).top() <= (space).page_high() \ 2620 (info).top() <= (space).page_high() && \
2752 && (info).limit() <= (space).page_high()) 2621 (info).limit() <= (space).page_high())
2753 2622
2754 2623
2755 // ----------------------------------------------------------------------------- 2624 // -----------------------------------------------------------------------------
2756 // Old space for all map objects 2625 // Old space for all map objects
2757 2626
2758 class MapSpace : public PagedSpace { 2627 class MapSpace : public PagedSpace {
2759 public: 2628 public:
2760 // Creates a map space object with a maximum capacity. 2629 // Creates a map space object with a maximum capacity.
2761 MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) 2630 MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
2762 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), 2631 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE),
2763 max_map_space_pages_(kMaxMapPageIndex - 1) { 2632 max_map_space_pages_(kMaxMapPageIndex - 1) {}
2764 }
2765 2633
2766 // Given an index, returns the page address. 2634 // Given an index, returns the page address.
2767 // TODO(1600): this limit is artifical just to keep code compilable 2635 // TODO(1600): this limit is artifical just to keep code compilable
2768 static const int kMaxMapPageIndex = 1 << 16; 2636 static const int kMaxMapPageIndex = 1 << 16;
2769 2637
2770 virtual int RoundSizeDownToObjectAlignment(int size) { 2638 virtual int RoundSizeDownToObjectAlignment(int size) {
2771 if (IsPowerOf2(Map::kSize)) { 2639 if (IsPowerOf2(Map::kSize)) {
2772 return RoundDown(size, Map::kSize); 2640 return RoundDown(size, Map::kSize);
2773 } else { 2641 } else {
2774 return (size / Map::kSize) * Map::kSize; 2642 return (size / Map::kSize) * Map::kSize;
(...skipping 18 matching lines...) Expand all
2793 }; 2661 };
2794 2662
2795 2663
2796 // ----------------------------------------------------------------------------- 2664 // -----------------------------------------------------------------------------
2797 // Old space for simple property cell objects 2665 // Old space for simple property cell objects
2798 2666
2799 class CellSpace : public PagedSpace { 2667 class CellSpace : public PagedSpace {
2800 public: 2668 public:
2801 // Creates a property cell space object with a maximum capacity. 2669 // Creates a property cell space object with a maximum capacity.
2802 CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) 2670 CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
2803 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) { 2671 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
2804 }
2805 2672
2806 virtual int RoundSizeDownToObjectAlignment(int size) { 2673 virtual int RoundSizeDownToObjectAlignment(int size) {
2807 if (IsPowerOf2(Cell::kSize)) { 2674 if (IsPowerOf2(Cell::kSize)) {
2808 return RoundDown(size, Cell::kSize); 2675 return RoundDown(size, Cell::kSize);
2809 } else { 2676 } else {
2810 return (size / Cell::kSize) * Cell::kSize; 2677 return (size / Cell::kSize) * Cell::kSize;
2811 } 2678 }
2812 } 2679 }
2813 2680
2814 protected: 2681 protected:
2815 virtual void VerifyObject(HeapObject* obj); 2682 virtual void VerifyObject(HeapObject* obj);
2816 2683
2817 public: 2684 public:
2818 TRACK_MEMORY("CellSpace") 2685 TRACK_MEMORY("CellSpace")
2819 }; 2686 };
2820 2687
2821 2688
2822 // ----------------------------------------------------------------------------- 2689 // -----------------------------------------------------------------------------
2823 // Old space for all global object property cell objects 2690 // Old space for all global object property cell objects
2824 2691
2825 class PropertyCellSpace : public PagedSpace { 2692 class PropertyCellSpace : public PagedSpace {
2826 public: 2693 public:
2827 // Creates a property cell space object with a maximum capacity. 2694 // Creates a property cell space object with a maximum capacity.
2828 PropertyCellSpace(Heap* heap, intptr_t max_capacity, 2695 PropertyCellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id)
2829 AllocationSpace id) 2696 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
2830 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {
2831 }
2832 2697
2833 virtual int RoundSizeDownToObjectAlignment(int size) { 2698 virtual int RoundSizeDownToObjectAlignment(int size) {
2834 if (IsPowerOf2(PropertyCell::kSize)) { 2699 if (IsPowerOf2(PropertyCell::kSize)) {
2835 return RoundDown(size, PropertyCell::kSize); 2700 return RoundDown(size, PropertyCell::kSize);
2836 } else { 2701 } else {
2837 return (size / PropertyCell::kSize) * PropertyCell::kSize; 2702 return (size / PropertyCell::kSize) * PropertyCell::kSize;
2838 } 2703 }
2839 } 2704 }
2840 2705
2841 protected: 2706 protected:
(...skipping 22 matching lines...) Expand all
2864 // Releases internal resources, frees objects in this space. 2729 // Releases internal resources, frees objects in this space.
2865 void TearDown(); 2730 void TearDown();
2866 2731
2867 static intptr_t ObjectSizeFor(intptr_t chunk_size) { 2732 static intptr_t ObjectSizeFor(intptr_t chunk_size) {
2868 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0; 2733 if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0;
2869 return chunk_size - Page::kPageSize - Page::kObjectStartOffset; 2734 return chunk_size - Page::kPageSize - Page::kObjectStartOffset;
2870 } 2735 }
2871 2736
2872 // Shared implementation of AllocateRaw, AllocateRawCode and 2737 // Shared implementation of AllocateRaw, AllocateRawCode and
2873 // AllocateRawFixedArray. 2738 // AllocateRawFixedArray.
2874 MUST_USE_RESULT AllocationResult AllocateRaw(int object_size, 2739 MUST_USE_RESULT AllocationResult
2875 Executability executable); 2740 AllocateRaw(int object_size, Executability executable);
2876 2741
2877 // Available bytes for objects in this space. 2742 // Available bytes for objects in this space.
2878 inline intptr_t Available(); 2743 inline intptr_t Available();
2879 2744
2880 virtual intptr_t Size() { 2745 virtual intptr_t Size() { return size_; }
2881 return size_;
2882 }
2883 2746
2884 virtual intptr_t SizeOfObjects() { 2747 virtual intptr_t SizeOfObjects() { return objects_size_; }
2885 return objects_size_;
2886 }
2887 2748
2888 intptr_t MaximumCommittedMemory() { 2749 intptr_t MaximumCommittedMemory() { return maximum_committed_; }
2889 return maximum_committed_;
2890 }
2891 2750
2892 intptr_t CommittedMemory() { 2751 intptr_t CommittedMemory() { return Size(); }
2893 return Size();
2894 }
2895 2752
2896 // Approximate amount of physical memory committed for this space. 2753 // Approximate amount of physical memory committed for this space.
2897 size_t CommittedPhysicalMemory(); 2754 size_t CommittedPhysicalMemory();
2898 2755
2899 int PageCount() { 2756 int PageCount() { return page_count_; }
2900 return page_count_;
2901 }
2902 2757
2903 // Finds an object for a given address, returns a Smi if it is not found. 2758 // Finds an object for a given address, returns a Smi if it is not found.
2904 // The function iterates through all objects in this space, may be slow. 2759 // The function iterates through all objects in this space, may be slow.
2905 Object* FindObject(Address a); 2760 Object* FindObject(Address a);
2906 2761
2907 // Finds a large object page containing the given address, returns NULL 2762 // Finds a large object page containing the given address, returns NULL
2908 // if such a page doesn't exist. 2763 // if such a page doesn't exist.
2909 LargePage* FindPage(Address a); 2764 LargePage* FindPage(Address a);
2910 2765
2911 // Frees unmarked objects. 2766 // Frees unmarked objects.
(...skipping 18 matching lines...) Expand all
2930 #endif 2785 #endif
2931 // Checks whether an address is in the object area in this space. It 2786 // Checks whether an address is in the object area in this space. It
2932 // iterates all objects in the space. May be slow. 2787 // iterates all objects in the space. May be slow.
2933 bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } 2788 bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); }
2934 2789
2935 private: 2790 private:
2936 intptr_t max_capacity_; 2791 intptr_t max_capacity_;
2937 intptr_t maximum_committed_; 2792 intptr_t maximum_committed_;
2938 // The head of the linked list of large object chunks. 2793 // The head of the linked list of large object chunks.
2939 LargePage* first_page_; 2794 LargePage* first_page_;
2940 intptr_t size_; // allocated bytes 2795 intptr_t size_; // allocated bytes
2941 int page_count_; // number of chunks 2796 int page_count_; // number of chunks
2942 intptr_t objects_size_; // size of objects 2797 intptr_t objects_size_; // size of objects
2943 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them 2798 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them
2944 HashMap chunk_map_; 2799 HashMap chunk_map_;
2945 2800
2946 friend class LargeObjectIterator; 2801 friend class LargeObjectIterator;
2947 2802
2948 public: 2803 public:
2949 TRACK_MEMORY("LargeObjectSpace") 2804 TRACK_MEMORY("LargeObjectSpace")
2950 }; 2805 };
2951 2806
2952 2807
2953 class LargeObjectIterator: public ObjectIterator { 2808 class LargeObjectIterator : public ObjectIterator {
2954 public: 2809 public:
2955 explicit LargeObjectIterator(LargeObjectSpace* space); 2810 explicit LargeObjectIterator(LargeObjectSpace* space);
2956 LargeObjectIterator(LargeObjectSpace* space, HeapObjectCallback size_func); 2811 LargeObjectIterator(LargeObjectSpace* space, HeapObjectCallback size_func);
2957 2812
2958 HeapObject* Next(); 2813 HeapObject* Next();
2959 2814
2960 // implementation of ObjectIterator. 2815 // implementation of ObjectIterator.
2961 virtual HeapObject* next_object() { return Next(); } 2816 virtual HeapObject* next_object() { return Next(); }
2962 2817
2963 private: 2818 private:
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 return NULL; 2862 return NULL;
3008 default: 2863 default:
3009 break; 2864 break;
3010 } 2865 }
3011 UNREACHABLE(); 2866 UNREACHABLE();
3012 return NULL; 2867 return NULL;
3013 } 2868 }
3014 2869
3015 2870
3016 private: 2871 private:
3017 enum State { 2872 enum State { kOldPointerState, kMapState, kLargeObjectState, kFinishedState };
3018 kOldPointerState,
3019 kMapState,
3020 kLargeObjectState,
3021 kFinishedState
3022 };
3023 State state_; 2873 State state_;
3024 PageIterator old_pointer_iterator_; 2874 PageIterator old_pointer_iterator_;
3025 PageIterator map_iterator_; 2875 PageIterator map_iterator_;
3026 LargeObjectIterator lo_iterator_; 2876 LargeObjectIterator lo_iterator_;
3027 }; 2877 };
3028 2878
3029 2879
3030 #ifdef DEBUG 2880 #ifdef DEBUG
3031 struct CommentStatistic { 2881 struct CommentStatistic {
3032 const char* comment; 2882 const char* comment;
3033 int size; 2883 int size;
3034 int count; 2884 int count;
3035 void Clear() { 2885 void Clear() {
3036 comment = NULL; 2886 comment = NULL;
3037 size = 0; 2887 size = 0;
3038 count = 0; 2888 count = 0;
3039 } 2889 }
3040 // Must be small, since an iteration is used for lookup. 2890 // Must be small, since an iteration is used for lookup.
3041 static const int kMaxComments = 64; 2891 static const int kMaxComments = 64;
3042 }; 2892 };
3043 #endif 2893 #endif
2894 }
2895 } // namespace v8::internal
3044 2896
3045 2897 #endif // V8_HEAP_SPACES_H_
3046 } } // namespace v8::internal
3047
3048 #endif // V8_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