OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_HEAP_SPACES_H_ | 5 #ifndef V8_HEAP_SPACES_H_ |
6 #define V8_HEAP_SPACES_H_ | 6 #define V8_HEAP_SPACES_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/atomic-utils.h" | 9 #include "src/atomic-utils.h" |
10 #include "src/base/atomicops.h" | 10 #include "src/base/atomicops.h" |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 } | 279 } |
280 // Clear all bits in the last cell till the last bit before index. | 280 // Clear all bits in the last cell till the last bit before index. |
281 uint32_t clear_mask = ~((1u << IndexInCell(index)) - 1); | 281 uint32_t clear_mask = ~((1u << IndexInCell(index)) - 1); |
282 cells()[end_cell_index] &= clear_mask; | 282 cells()[end_cell_index] &= clear_mask; |
283 } | 283 } |
284 }; | 284 }; |
285 | 285 |
286 | 286 |
287 class SkipList; | 287 class SkipList; |
288 class SlotsBuffer; | 288 class SlotsBuffer; |
| 289 class SlotSet; |
289 | 290 |
290 // MemoryChunk represents a memory region owned by a specific space. | 291 // MemoryChunk represents a memory region owned by a specific space. |
291 // It is divided into the header and the body. Chunk start is always | 292 // It is divided into the header and the body. Chunk start is always |
292 // 1MB aligned. Start of the body is aligned so it can accommodate | 293 // 1MB aligned. Start of the body is aligned so it can accommodate |
293 // any heap object. | 294 // any heap object. |
294 class MemoryChunk { | 295 class MemoryChunk { |
295 public: | 296 public: |
296 enum MemoryChunkFlags { | 297 enum MemoryChunkFlags { |
297 IS_EXECUTABLE, | 298 IS_EXECUTABLE, |
298 ABOUT_TO_BE_FREED, | 299 ABOUT_TO_BE_FREED, |
299 POINTERS_TO_HERE_ARE_INTERESTING, | 300 POINTERS_TO_HERE_ARE_INTERESTING, |
300 POINTERS_FROM_HERE_ARE_INTERESTING, | 301 POINTERS_FROM_HERE_ARE_INTERESTING, |
301 SCAN_ON_SCAVENGE, | |
302 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. | 302 IN_FROM_SPACE, // Mutually exclusive with IN_TO_SPACE. |
303 IN_TO_SPACE, // All pages in new space has one of these two set. | 303 IN_TO_SPACE, // All pages in new space has one of these two set. |
304 NEW_SPACE_BELOW_AGE_MARK, | 304 NEW_SPACE_BELOW_AGE_MARK, |
305 EVACUATION_CANDIDATE, | 305 EVACUATION_CANDIDATE, |
306 RESCAN_ON_EVACUATION, | 306 RESCAN_ON_EVACUATION, |
307 NEVER_EVACUATE, // May contain immortal immutables. | 307 NEVER_EVACUATE, // May contain immortal immutables. |
308 POPULAR_PAGE, // Slots buffer of this page overflowed on the previous GC. | 308 POPULAR_PAGE, // Slots buffer of this page overflowed on the previous GC. |
309 | 309 |
310 // WAS_SWEPT indicates that marking bits have been cleared by the sweeper, | 310 // WAS_SWEPT indicates that marking bits have been cleared by the sweeper, |
311 // otherwise marking bits are still intact. | 311 // otherwise marking bits are still intact. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 + 2 * kPointerSize // base::VirtualMemory reservation_ | 396 + 2 * kPointerSize // base::VirtualMemory reservation_ |
397 + kPointerSize // Address owner_ | 397 + kPointerSize // Address owner_ |
398 + kPointerSize // Heap* heap_ | 398 + kPointerSize // Heap* heap_ |
399 + kIntSize; // int progress_bar_ | 399 + kIntSize; // int progress_bar_ |
400 | 400 |
401 static const size_t kSlotsBufferOffset = | 401 static const size_t kSlotsBufferOffset = |
402 kLiveBytesOffset + kIntSize; // int live_byte_count_ | 402 kLiveBytesOffset + kIntSize; // int live_byte_count_ |
403 | 403 |
404 static const size_t kWriteBarrierCounterOffset = | 404 static const size_t kWriteBarrierCounterOffset = |
405 kSlotsBufferOffset + kPointerSize // SlotsBuffer* slots_buffer_; | 405 kSlotsBufferOffset + kPointerSize // SlotsBuffer* slots_buffer_; |
| 406 + kPointerSize // SlotSet* old_to_new_slots_; |
406 + kPointerSize; // SkipList* skip_list_; | 407 + kPointerSize; // SkipList* skip_list_; |
407 | 408 |
408 static const size_t kMinHeaderSize = | 409 static const size_t kMinHeaderSize = |
409 kWriteBarrierCounterOffset + | 410 kWriteBarrierCounterOffset + |
410 kIntptrSize // intptr_t write_barrier_counter_ | 411 kIntptrSize // intptr_t write_barrier_counter_ |
411 + kPointerSize // AtomicValue high_water_mark_ | 412 + kPointerSize // AtomicValue high_water_mark_ |
412 + kPointerSize // base::Mutex* mutex_ | 413 + kPointerSize // base::Mutex* mutex_ |
413 + kPointerSize // base::AtomicWord parallel_sweeping_ | 414 + kPointerSize // base::AtomicWord parallel_sweeping_ |
414 + kPointerSize // AtomicValue parallel_compaction_ | 415 + kPointerSize // AtomicValue parallel_compaction_ |
415 + 5 * kPointerSize // AtomicNumber free-list statistics | 416 + 5 * kPointerSize // AtomicNumber free-list statistics |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 kPageHeaderTag); | 502 kPageHeaderTag); |
502 } | 503 } |
503 | 504 |
504 base::VirtualMemory* reserved_memory() { return &reservation_; } | 505 base::VirtualMemory* reserved_memory() { return &reservation_; } |
505 | 506 |
506 void set_reserved_memory(base::VirtualMemory* reservation) { | 507 void set_reserved_memory(base::VirtualMemory* reservation) { |
507 DCHECK_NOT_NULL(reservation); | 508 DCHECK_NOT_NULL(reservation); |
508 reservation_.TakeControl(reservation); | 509 reservation_.TakeControl(reservation); |
509 } | 510 } |
510 | 511 |
511 bool scan_on_scavenge() { return IsFlagSet(SCAN_ON_SCAVENGE); } | |
512 void initialize_scan_on_scavenge(bool scan) { | |
513 if (scan) { | |
514 SetFlag(SCAN_ON_SCAVENGE); | |
515 } else { | |
516 ClearFlag(SCAN_ON_SCAVENGE); | |
517 } | |
518 } | |
519 inline void set_scan_on_scavenge(bool scan); | |
520 | |
521 bool Contains(Address addr) { | 512 bool Contains(Address addr) { |
522 return addr >= area_start() && addr < area_end(); | 513 return addr >= area_start() && addr < area_end(); |
523 } | 514 } |
524 | 515 |
525 // Checks whether addr can be a limit of addresses in this page. | 516 // Checks whether addr can be a limit of addresses in this page. |
526 // It's a limit if it's in the page, or if it's just after the | 517 // It's a limit if it's in the page, or if it's just after the |
527 // last byte of the page. | 518 // last byte of the page. |
528 bool ContainsLimit(Address addr) { | 519 bool ContainsLimit(Address addr) { |
529 return addr >= area_start() && addr <= area_end(); | 520 return addr >= area_start() && addr <= area_end(); |
530 } | 521 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } | 688 } |
698 | 689 |
699 inline SkipList* skip_list() { return skip_list_; } | 690 inline SkipList* skip_list() { return skip_list_; } |
700 | 691 |
701 inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; } | 692 inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; } |
702 | 693 |
703 inline SlotsBuffer* slots_buffer() { return slots_buffer_; } | 694 inline SlotsBuffer* slots_buffer() { return slots_buffer_; } |
704 | 695 |
705 inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; } | 696 inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; } |
706 | 697 |
| 698 inline SlotSet* old_to_new_slots() { return old_to_new_slots_; } |
| 699 |
| 700 void AllocateOldToNewSlots(); |
| 701 void ReleaseOldToNewSlots(); |
| 702 |
707 void MarkEvacuationCandidate() { | 703 void MarkEvacuationCandidate() { |
708 DCHECK(!IsFlagSet(NEVER_EVACUATE)); | 704 DCHECK(!IsFlagSet(NEVER_EVACUATE)); |
709 DCHECK(slots_buffer_ == NULL); | 705 DCHECK(slots_buffer_ == NULL); |
710 SetFlag(EVACUATION_CANDIDATE); | 706 SetFlag(EVACUATION_CANDIDATE); |
711 } | 707 } |
712 | 708 |
713 void ClearEvacuationCandidate() { | 709 void ClearEvacuationCandidate() { |
714 DCHECK(slots_buffer_ == NULL); | 710 DCHECK(slots_buffer_ == NULL); |
715 ClearFlag(EVACUATION_CANDIDATE); | 711 ClearFlag(EVACUATION_CANDIDATE); |
716 } | 712 } |
(...skipping 27 matching lines...) Expand all Loading... |
744 // no failure can be in an object, so this can be distinguished from any entry | 740 // no failure can be in an object, so this can be distinguished from any entry |
745 // in a fixed array. | 741 // in a fixed array. |
746 Address owner_; | 742 Address owner_; |
747 Heap* heap_; | 743 Heap* heap_; |
748 // Used by the incremental marker to keep track of the scanning progress in | 744 // Used by the incremental marker to keep track of the scanning progress in |
749 // large objects that have a progress bar and are scanned in increments. | 745 // large objects that have a progress bar and are scanned in increments. |
750 int progress_bar_; | 746 int progress_bar_; |
751 // Count of bytes marked black on page. | 747 // Count of bytes marked black on page. |
752 int live_byte_count_; | 748 int live_byte_count_; |
753 SlotsBuffer* slots_buffer_; | 749 SlotsBuffer* slots_buffer_; |
| 750 // A single slot set for small pages (of size kPageSize) or an array of slot |
| 751 // set for large pages. In the latter case the number of entries in the array |
| 752 // is ceil(size() / kPageSize). |
| 753 SlotSet* old_to_new_slots_; |
754 SkipList* skip_list_; | 754 SkipList* skip_list_; |
755 intptr_t write_barrier_counter_; | 755 intptr_t write_barrier_counter_; |
756 // Assuming the initial allocation on a page is sequential, | 756 // Assuming the initial allocation on a page is sequential, |
757 // count highest number of bytes ever allocated on the page. | 757 // count highest number of bytes ever allocated on the page. |
758 AtomicValue<intptr_t> high_water_mark_; | 758 AtomicValue<intptr_t> high_water_mark_; |
759 | 759 |
760 base::Mutex* mutex_; | 760 base::Mutex* mutex_; |
761 AtomicValue<ParallelSweepingState> parallel_sweeping_; | 761 AtomicValue<ParallelSweepingState> parallel_sweeping_; |
762 AtomicValue<ParallelCompactingState> parallel_compaction_; | 762 AtomicValue<ParallelCompactingState> parallel_compaction_; |
763 | 763 |
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2259 | 2259 |
2260 class SemiSpace; | 2260 class SemiSpace; |
2261 | 2261 |
2262 | 2262 |
2263 class NewSpacePage : public MemoryChunk { | 2263 class NewSpacePage : public MemoryChunk { |
2264 public: | 2264 public: |
2265 // GC related flags copied from from-space to to-space when | 2265 // GC related flags copied from from-space to to-space when |
2266 // flipping semispaces. | 2266 // flipping semispaces. |
2267 static const intptr_t kCopyOnFlipFlagsMask = | 2267 static const intptr_t kCopyOnFlipFlagsMask = |
2268 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | | 2268 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | |
2269 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING) | | 2269 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
2270 (1 << MemoryChunk::SCAN_ON_SCAVENGE); | |
2271 | 2270 |
2272 static const int kAreaSize = Page::kAllocatableMemory; | 2271 static const int kAreaSize = Page::kAllocatableMemory; |
2273 | 2272 |
2274 inline NewSpacePage* next_page() { | 2273 inline NewSpacePage* next_page() { |
2275 return static_cast<NewSpacePage*>(next_chunk()); | 2274 return static_cast<NewSpacePage*>(next_chunk()); |
2276 } | 2275 } |
2277 | 2276 |
2278 inline void set_next_page(NewSpacePage* page) { set_next_chunk(page); } | 2277 inline void set_next_page(NewSpacePage* page) { set_next_chunk(page); } |
2279 | 2278 |
2280 inline NewSpacePage* prev_page() { | 2279 inline NewSpacePage* prev_page() { |
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 count = 0; | 3219 count = 0; |
3221 } | 3220 } |
3222 // Must be small, since an iteration is used for lookup. | 3221 // Must be small, since an iteration is used for lookup. |
3223 static const int kMaxComments = 64; | 3222 static const int kMaxComments = 64; |
3224 }; | 3223 }; |
3225 #endif | 3224 #endif |
3226 } // namespace internal | 3225 } // namespace internal |
3227 } // namespace v8 | 3226 } // namespace v8 |
3228 | 3227 |
3229 #endif // V8_HEAP_SPACES_H_ | 3228 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |