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

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

Issue 2770253002: [heap] Enforce explicit MarkingState (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/scavenger.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HEAP_SPACES_H_ 5 #ifndef V8_HEAP_SPACES_H_
6 #define V8_HEAP_SPACES_H_ 6 #define V8_HEAP_SPACES_H_
7 7
8 #include <list> 8 #include <list>
9 #include <memory> 9 #include <memory>
10 #include <unordered_set> 10 #include <unordered_set>
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // |top_|: Points to the top FreeSpace* in the free list category. 217 // |top_|: Points to the top FreeSpace* in the free list category.
218 FreeSpace* top_; 218 FreeSpace* top_;
219 219
220 FreeListCategory* prev_; 220 FreeListCategory* prev_;
221 FreeListCategory* next_; 221 FreeListCategory* next_;
222 222
223 friend class FreeList; 223 friend class FreeList;
224 friend class PagedSpace; 224 friend class PagedSpace;
225 }; 225 };
226 226
227 // MarkingMode determines which bitmaps and counters should be used when
228 // accessing marking information on MemoryChunk.
229 enum class MarkingMode { FULL, YOUNG_GENERATION };
230
231 // MemoryChunk represents a memory region owned by a specific space. 227 // MemoryChunk represents a memory region owned by a specific space.
232 // It is divided into the header and the body. Chunk start is always 228 // It is divided into the header and the body. Chunk start is always
233 // 1MB aligned. Start of the body is aligned so it can accommodate 229 // 1MB aligned. Start of the body is aligned so it can accommodate
234 // any heap object. 230 // any heap object.
235 class MemoryChunk { 231 class MemoryChunk {
236 public: 232 public:
237 enum Flag { 233 enum Flag {
238 NO_FLAGS = 0u, 234 NO_FLAGS = 0u,
239 IS_EXECUTABLE = 1u << 0, 235 IS_EXECUTABLE = 1u << 0,
240 POINTERS_TO_HERE_ARE_INTERESTING = 1u << 1, 236 POINTERS_TO_HERE_ARE_INTERESTING = 1u << 1,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 static const int kObjectStartOffset = 366 static const int kObjectStartOffset =
371 kBodyOffset - 1 + 367 kBodyOffset - 1 +
372 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); 368 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment);
373 369
374 // Page size in bytes. This must be a multiple of the OS page size. 370 // Page size in bytes. This must be a multiple of the OS page size.
375 static const int kPageSize = 1 << kPageSizeBits; 371 static const int kPageSize = 1 << kPageSizeBits;
376 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; 372 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1;
377 373
378 static const int kAllocatableMemory = kPageSize - kObjectStartOffset; 374 static const int kAllocatableMemory = kPageSize - kObjectStartOffset;
379 375
380 template <MarkingMode mode = MarkingMode::FULL>
381 static inline void IncrementLiveBytes(HeapObject* object, int by);
382
383 // Only works if the pointer is in the first kPageSize of the MemoryChunk. 376 // Only works if the pointer is in the first kPageSize of the MemoryChunk.
384 static MemoryChunk* FromAddress(Address a) { 377 static MemoryChunk* FromAddress(Address a) {
385 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); 378 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask);
386 } 379 }
387 380
388 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); 381 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr);
389 382
390 static inline void UpdateHighWaterMark(Address mark) { 383 static inline void UpdateHighWaterMark(Address mark) {
391 if (mark == nullptr) return; 384 if (mark == nullptr) return;
392 // Need to subtract one from the mark because when a chunk is full the 385 // Need to subtract one from the mark because when a chunk is full the
(...skipping 27 matching lines...) Expand all
420 } 413 }
421 414
422 base::AtomicValue<ConcurrentSweepingState>& concurrent_sweeping_state() { 415 base::AtomicValue<ConcurrentSweepingState>& concurrent_sweeping_state() {
423 return concurrent_sweeping_; 416 return concurrent_sweeping_;
424 } 417 }
425 418
426 bool SweepingDone() { 419 bool SweepingDone() {
427 return concurrent_sweeping_state().Value() == kSweepingDone; 420 return concurrent_sweeping_state().Value() == kSweepingDone;
428 } 421 }
429 422
430 // Manage live byte count, i.e., count of bytes in black objects.
431 template <MarkingMode mode = MarkingMode::FULL>
432 inline void ResetLiveBytes();
433 template <MarkingMode mode = MarkingMode::FULL>
434 inline void IncrementLiveBytes(int by);
435
436 template <MarkingMode mode = MarkingMode::FULL>
437 int LiveBytes() {
438 switch (mode) {
439 case MarkingMode::FULL:
440 DCHECK_LE(static_cast<unsigned>(live_byte_count_), size_);
441 return static_cast<int>(live_byte_count_);
442 case MarkingMode::YOUNG_GENERATION:
443 DCHECK_LE(static_cast<unsigned>(young_generation_live_byte_count_),
444 size_);
445 return static_cast<int>(young_generation_live_byte_count_);
446 }
447 UNREACHABLE();
448 return 0;
449 }
450
451 void SetLiveBytes(int live_bytes) {
452 DCHECK_GE(live_bytes, 0);
453 DCHECK_LE(static_cast<size_t>(live_bytes), size_);
454 live_byte_count_ = live_bytes;
455 }
456
457 size_t size() const { return size_; } 423 size_t size() const { return size_; }
458 void set_size(size_t size) { size_ = size; } 424 void set_size(size_t size) { size_ = size; }
459 425
460 inline Heap* heap() const { return heap_; } 426 inline Heap* heap() const { return heap_; }
461 427
462 inline SkipList* skip_list() { return skip_list_; } 428 inline SkipList* skip_list() { return skip_list_; }
463 429
464 inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; } 430 inline void set_skip_list(SkipList* skip_list) { skip_list_ = skip_list; }
465 431
466 inline SlotSet* old_to_new_slots() { return old_to_new_slots_.Value(); } 432 inline SlotSet* old_to_new_slots() { return old_to_new_slots_.Value(); }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 DCHECK(IsFlagSet(HAS_PROGRESS_BAR)); 472 DCHECK(IsFlagSet(HAS_PROGRESS_BAR));
507 progress_bar_ = progress_bar; 473 progress_bar_ = progress_bar;
508 } 474 }
509 475
510 void ResetProgressBar() { 476 void ResetProgressBar() {
511 if (IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { 477 if (IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
512 set_progress_bar(0); 478 set_progress_bar(0);
513 } 479 }
514 } 480 }
515 481
516 template <MarkingMode mode = MarkingMode::FULL>
517 inline Bitmap* markbits() const {
518 return mode == MarkingMode::FULL
519 ? Bitmap::FromAddress(address() + kHeaderSize)
520 : young_generation_bitmap_;
521 }
522
523 template <MarkingMode mode = MarkingMode::FULL>
524 inline intptr_t* live_bytes_address() {
525 return mode == MarkingMode::FULL ? &live_byte_count_
526 : &young_generation_live_byte_count_;
527 }
528
529 inline uint32_t AddressToMarkbitIndex(Address addr) const { 482 inline uint32_t AddressToMarkbitIndex(Address addr) const {
530 return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2; 483 return static_cast<uint32_t>(addr - this->address()) >> kPointerSizeLog2;
531 } 484 }
532 485
533 inline Address MarkbitIndexToAddress(uint32_t index) const { 486 inline Address MarkbitIndexToAddress(uint32_t index) const {
534 return this->address() + (index << kPointerSizeLog2); 487 return this->address() + (index << kPointerSizeLog2);
535 } 488 }
536 489
537 template <MarkingMode mode = MarkingMode::FULL>
538 void ClearLiveness();
539
540 void PrintMarkbits() { markbits()->Print(); }
541
542 void SetFlag(Flag flag) { flags_ |= flag; } 490 void SetFlag(Flag flag) { flags_ |= flag; }
543 void ClearFlag(Flag flag) { flags_ &= ~Flags(flag); } 491 void ClearFlag(Flag flag) { flags_ &= ~Flags(flag); }
544 bool IsFlagSet(Flag flag) { return (flags_ & flag) != 0; } 492 bool IsFlagSet(Flag flag) { return (flags_ & flag) != 0; }
545 493
546 // Set or clear multiple flags at a time. The flags in the mask are set to 494 // Set or clear multiple flags at a time. The flags in the mask are set to
547 // the value in "flags", the rest retain the current value in |flags_|. 495 // the value in "flags", the rest retain the current value in |flags_|.
548 void SetFlags(uintptr_t flags, uintptr_t mask) { 496 void SetFlags(uintptr_t flags, uintptr_t mask) {
549 flags_ = (flags_ & ~Flags(mask)) | (Flags(flags) & Flags(mask)); 497 flags_ = (flags_ & ~Flags(mask)) | (Flags(flags) & Flags(mask));
550 } 498 }
551 499
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 static MemoryChunk* Initialize(Heap* heap, Address base, size_t size, 563 static MemoryChunk* Initialize(Heap* heap, Address base, size_t size,
616 Address area_start, Address area_end, 564 Address area_start, Address area_end,
617 Executability executable, Space* owner, 565 Executability executable, Space* owner,
618 base::VirtualMemory* reservation); 566 base::VirtualMemory* reservation);
619 567
620 // Should be called when memory chunk is about to be freed. 568 // Should be called when memory chunk is about to be freed.
621 void ReleaseAllocatedMemory(); 569 void ReleaseAllocatedMemory();
622 570
623 base::VirtualMemory* reserved_memory() { return &reservation_; } 571 base::VirtualMemory* reserved_memory() { return &reservation_; }
624 572
625 template <MarkingMode mode = MarkingMode::FULL>
626 inline void TraceLiveBytes(intptr_t old_value, intptr_t new_value);
627
628 size_t size_; 573 size_t size_;
629 Flags flags_; 574 Flags flags_;
630 575
631 // Start and end of allocatable memory on this chunk. 576 // Start and end of allocatable memory on this chunk.
632 Address area_start_; 577 Address area_start_;
633 Address area_end_; 578 Address area_end_;
634 579
635 // If the chunk needs to remember its memory reservation, it is stored here. 580 // If the chunk needs to remember its memory reservation, it is stored here.
636 base::VirtualMemory reservation_; 581 base::VirtualMemory reservation_;
637 582
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 FreeListCategory categories_[kNumberOfCategories]; 624 FreeListCategory categories_[kNumberOfCategories];
680 625
681 LocalArrayBufferTracker* local_tracker_; 626 LocalArrayBufferTracker* local_tracker_;
682 627
683 intptr_t young_generation_live_byte_count_; 628 intptr_t young_generation_live_byte_count_;
684 Bitmap* young_generation_bitmap_; 629 Bitmap* young_generation_bitmap_;
685 630
686 private: 631 private:
687 void InitializeReservedMemory() { reservation_.Reset(); } 632 void InitializeReservedMemory() { reservation_.Reset(); }
688 633
634 friend class MarkingState;
689 friend class MemoryAllocator; 635 friend class MemoryAllocator;
690 friend class MemoryChunkValidator; 636 friend class MemoryChunkValidator;
691 }; 637 };
692 638
693 DEFINE_OPERATORS_FOR_FLAGS(MemoryChunk::Flags) 639 DEFINE_OPERATORS_FOR_FLAGS(MemoryChunk::Flags)
694 640
695 static_assert(kMaxRegularHeapObjectSize <= MemoryChunk::kAllocatableMemory, 641 static_assert(kMaxRegularHeapObjectSize <= MemoryChunk::kAllocatableMemory,
696 "kMaxRegularHeapObjectSize <= MemoryChunk::kAllocatableMemory"); 642 "kMaxRegularHeapObjectSize <= MemoryChunk::kAllocatableMemory");
697 643
644 class MarkingState {
645 public:
646 static MarkingState External(HeapObject* object) {
647 return External(MemoryChunk::FromAddress(object->address()));
648 }
649
650 static MarkingState External(MemoryChunk* chunk) {
651 return MarkingState(chunk->young_generation_bitmap_,
652 &chunk->young_generation_live_byte_count_);
653 }
654
655 static MarkingState Internal(HeapObject* object) {
656 return Internal(MemoryChunk::FromAddress(object->address()));
657 }
658
659 static MarkingState Internal(MemoryChunk* chunk) {
660 return MarkingState(
661 Bitmap::FromAddress(chunk->address() + MemoryChunk::kHeaderSize),
662 &chunk->live_byte_count_);
663 }
664
665 MarkingState(Bitmap* bitmap, intptr_t* live_bytes)
666 : bitmap_(bitmap), live_bytes_(live_bytes) {}
667
668 void IncrementLiveBytes(intptr_t by) const {
669 *live_bytes_ += static_cast<int>(by);
670 }
671 void SetLiveBytes(intptr_t value) const {
672 *live_bytes_ = static_cast<int>(value);
673 }
674
675 void ClearLiveness() const {
676 bitmap_->Clear();
677 *live_bytes_ = 0;
678 }
679
680 Bitmap* bitmap() const { return bitmap_; }
681 intptr_t live_bytes() const { return *live_bytes_; }
682
683 private:
684 Bitmap* bitmap_;
685 intptr_t* live_bytes_;
686 };
687
698 // ----------------------------------------------------------------------------- 688 // -----------------------------------------------------------------------------
699 // A page is a memory chunk of a size 1MB. Large object pages may be larger. 689 // A page is a memory chunk of a size 1MB. Large object pages may be larger.
700 // 690 //
701 // The only way to get a page pointer is by calling factory methods: 691 // The only way to get a page pointer is by calling factory methods:
702 // Page* p = Page::FromAddress(addr); or 692 // Page* p = Page::FromAddress(addr); or
703 // Page* p = Page::FromTopOrLimit(top); 693 // Page* p = Page::FromTopOrLimit(top);
704 class Page : public MemoryChunk { 694 class Page : public MemoryChunk {
705 public: 695 public:
706 static const intptr_t kCopyAllFlags = ~0; 696 static const intptr_t kCopyAllFlags = ~0;
707 697
(...skipping 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2964 PageIterator old_iterator_; 2954 PageIterator old_iterator_;
2965 PageIterator code_iterator_; 2955 PageIterator code_iterator_;
2966 PageIterator map_iterator_; 2956 PageIterator map_iterator_;
2967 LargePageIterator lo_iterator_; 2957 LargePageIterator lo_iterator_;
2968 }; 2958 };
2969 2959
2970 } // namespace internal 2960 } // namespace internal
2971 } // namespace v8 2961 } // namespace v8
2972 2962
2973 #endif // V8_HEAP_SPACES_H_ 2963 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/scavenger.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698