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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 NEW_SPACE_BELOW_AGE_MARK, | 412 NEW_SPACE_BELOW_AGE_MARK, |
413 EVACUATION_CANDIDATE, | 413 EVACUATION_CANDIDATE, |
414 NEVER_EVACUATE, // May contain immortal immutables. | 414 NEVER_EVACUATE, // May contain immortal immutables. |
415 | 415 |
416 // Large objects can have a progress bar in their page header. These object | 416 // Large objects can have a progress bar in their page header. These object |
417 // are scanned in increments and will be kept black while being scanned. | 417 // are scanned in increments and will be kept black while being scanned. |
418 // Even if the mutator writes to them they will be kept black and a white | 418 // Even if the mutator writes to them they will be kept black and a white |
419 // to grey transition is performed in the value. | 419 // to grey transition is performed in the value. |
420 HAS_PROGRESS_BAR, | 420 HAS_PROGRESS_BAR, |
421 | 421 |
| 422 // |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted |
| 423 // from new to old space during evacuation. |
| 424 PAGE_NEW_OLD_PROMOTION, |
| 425 |
422 // A black page has all mark bits set to 1 (black). A black page currently | 426 // A black page has all mark bits set to 1 (black). A black page currently |
423 // cannot be iterated because it is not swept. Moreover live bytes are also | 427 // cannot be iterated because it is not swept. Moreover live bytes are also |
424 // not updated. | 428 // not updated. |
425 BLACK_PAGE, | 429 BLACK_PAGE, |
426 | 430 |
427 // This flag is intended to be used for testing. Works only when both | 431 // This flag is intended to be used for testing. Works only when both |
428 // FLAG_stress_compaction and FLAG_manual_evacuation_candidates_selection | 432 // FLAG_stress_compaction and FLAG_manual_evacuation_candidates_selection |
429 // are set. It forces the page to become an evacuation candidate at next | 433 // are set. It forces the page to become an evacuation candidate at next |
430 // candidates selection cycle. | 434 // candidates selection cycle. |
431 FORCE_EVACUATION_CANDIDATE_FOR_TESTING, | 435 FORCE_EVACUATION_CANDIDATE_FOR_TESTING, |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 }; | 821 }; |
818 | 822 |
819 // ----------------------------------------------------------------------------- | 823 // ----------------------------------------------------------------------------- |
820 // A page is a memory chunk of a size 1MB. Large object pages may be larger. | 824 // A page is a memory chunk of a size 1MB. Large object pages may be larger. |
821 // | 825 // |
822 // The only way to get a page pointer is by calling factory methods: | 826 // The only way to get a page pointer is by calling factory methods: |
823 // Page* p = Page::FromAddress(addr); or | 827 // Page* p = Page::FromAddress(addr); or |
824 // Page* p = Page::FromAllocationTop(top); | 828 // Page* p = Page::FromAllocationTop(top); |
825 class Page : public MemoryChunk { | 829 class Page : public MemoryChunk { |
826 public: | 830 public: |
| 831 static inline Page* Convert(NewSpacePage* old_page, PagedSpace* new_owner); |
| 832 |
827 // Returns the page containing a given address. The address ranges | 833 // Returns the page containing a given address. The address ranges |
828 // from [page_addr .. page_addr + kPageSize[ | 834 // from [page_addr .. page_addr + kPageSize[ |
829 // This only works if the object is in fact in a page. See also MemoryChunk:: | 835 // This only works if the object is in fact in a page. See also MemoryChunk:: |
830 // FromAddress() and FromAnyAddress(). | 836 // FromAddress() and FromAnyAddress(). |
831 INLINE(static Page* FromAddress(Address a)) { | 837 INLINE(static Page* FromAddress(Address a)) { |
832 return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask); | 838 return reinterpret_cast<Page*>(OffsetFrom(a) & ~kPageAlignmentMask); |
833 } | 839 } |
834 | 840 |
835 // Only works for addresses in pointer spaces, not code space. | 841 // Only works for addresses in pointer spaces, not code space. |
836 inline static Page* FromAnyPointerAddress(Heap* heap, Address addr); | 842 inline static Page* FromAnyPointerAddress(Heap* heap, Address addr); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 | 937 |
932 #ifdef DEBUG | 938 #ifdef DEBUG |
933 void Print(); | 939 void Print(); |
934 #endif // DEBUG | 940 #endif // DEBUG |
935 | 941 |
936 inline void MarkNeverAllocateForTesting(); | 942 inline void MarkNeverAllocateForTesting(); |
937 inline void MarkEvacuationCandidate(); | 943 inline void MarkEvacuationCandidate(); |
938 inline void ClearEvacuationCandidate(); | 944 inline void ClearEvacuationCandidate(); |
939 | 945 |
940 private: | 946 private: |
| 947 enum InitializationMode { kFreeMemory, kDoNotFreeMemory }; |
| 948 |
| 949 template <InitializationMode mode = kFreeMemory> |
941 static inline Page* Initialize(Heap* heap, MemoryChunk* chunk, | 950 static inline Page* Initialize(Heap* heap, MemoryChunk* chunk, |
942 Executability executable, PagedSpace* owner); | 951 Executability executable, PagedSpace* owner); |
943 | 952 |
944 inline void InitializeFreeListCategories(); | 953 inline void InitializeFreeListCategories(); |
945 | 954 |
946 friend class MemoryAllocator; | 955 friend class MemoryAllocator; |
947 }; | 956 }; |
948 | 957 |
949 | 958 |
950 class LargePage : public MemoryChunk { | 959 class LargePage : public MemoryChunk { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 virtual intptr_t Available() = 0; | 1043 virtual intptr_t Available() = 0; |
1035 | 1044 |
1036 virtual int RoundSizeDownToObjectAlignment(int size) { | 1045 virtual int RoundSizeDownToObjectAlignment(int size) { |
1037 if (id_ == CODE_SPACE) { | 1046 if (id_ == CODE_SPACE) { |
1038 return RoundDown(size, kCodeAlignment); | 1047 return RoundDown(size, kCodeAlignment); |
1039 } else { | 1048 } else { |
1040 return RoundDown(size, kPointerSize); | 1049 return RoundDown(size, kPointerSize); |
1041 } | 1050 } |
1042 } | 1051 } |
1043 | 1052 |
1044 #ifdef DEBUG | |
1045 virtual void Print() = 0; | |
1046 #endif | |
1047 | |
1048 protected: | |
1049 void AccountCommitted(intptr_t bytes) { | 1053 void AccountCommitted(intptr_t bytes) { |
1050 DCHECK_GE(bytes, 0); | 1054 DCHECK_GE(bytes, 0); |
1051 committed_ += bytes; | 1055 committed_ += bytes; |
1052 if (committed_ > max_committed_) { | 1056 if (committed_ > max_committed_) { |
1053 max_committed_ = committed_; | 1057 max_committed_ = committed_; |
1054 } | 1058 } |
1055 } | 1059 } |
1056 | 1060 |
1057 void AccountUncommitted(intptr_t bytes) { | 1061 void AccountUncommitted(intptr_t bytes) { |
1058 DCHECK_GE(bytes, 0); | 1062 DCHECK_GE(bytes, 0); |
1059 committed_ -= bytes; | 1063 committed_ -= bytes; |
1060 DCHECK_GE(committed_, 0); | 1064 DCHECK_GE(committed_, 0); |
1061 } | 1065 } |
1062 | 1066 |
| 1067 #ifdef DEBUG |
| 1068 virtual void Print() = 0; |
| 1069 #endif |
| 1070 |
| 1071 protected: |
1063 v8::base::SmartPointer<List<AllocationObserver*>> allocation_observers_; | 1072 v8::base::SmartPointer<List<AllocationObserver*>> allocation_observers_; |
1064 bool allocation_observers_paused_; | 1073 bool allocation_observers_paused_; |
1065 | 1074 |
1066 private: | 1075 private: |
1067 Heap* heap_; | 1076 Heap* heap_; |
1068 AllocationSpace id_; | 1077 AllocationSpace id_; |
1069 Executability executable_; | 1078 Executability executable_; |
1070 | 1079 |
1071 // Keeps track of committed memory in a space. | 1080 // Keeps track of committed memory in a space. |
1072 intptr_t committed_; | 1081 intptr_t committed_; |
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 static inline NewSpacePage* Initialize(Heap* heap, MemoryChunk* chunk, | 2357 static inline NewSpacePage* Initialize(Heap* heap, MemoryChunk* chunk, |
2349 Executability executable, | 2358 Executability executable, |
2350 SemiSpace* owner); | 2359 SemiSpace* owner); |
2351 | 2360 |
2352 // GC related flags copied from from-space to to-space when | 2361 // GC related flags copied from from-space to to-space when |
2353 // flipping semispaces. | 2362 // flipping semispaces. |
2354 static const intptr_t kCopyOnFlipFlagsMask = | 2363 static const intptr_t kCopyOnFlipFlagsMask = |
2355 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | | 2364 (1 << MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING) | |
2356 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); | 2365 (1 << MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING); |
2357 | 2366 |
| 2367 static const intptr_t kCopyAllFlags = ~0; |
| 2368 |
2358 // Create a NewSpacePage object that is only used as anchor | 2369 // Create a NewSpacePage object that is only used as anchor |
2359 // for the doubly-linked list of real pages. | 2370 // for the doubly-linked list of real pages. |
2360 explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); } | 2371 explicit NewSpacePage(SemiSpace* owner) { InitializeAsAnchor(owner); } |
2361 | 2372 |
2362 // Intialize a fake NewSpacePage used as sentinel at the ends | 2373 // Intialize a fake NewSpacePage used as sentinel at the ends |
2363 // of a doubly-linked list of real NewSpacePages. | 2374 // of a doubly-linked list of real NewSpacePages. |
2364 // Only uses the prev/next links, and sets flags to not be in new-space. | 2375 // Only uses the prev/next links, and sets flags to not be in new-space. |
2365 void InitializeAsAnchor(SemiSpace* owner); | 2376 void InitializeAsAnchor(SemiSpace* owner); |
2366 | 2377 |
2367 friend class MemoryAllocator; | 2378 friend class MemoryAllocator; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2433 bool AdvancePage() { | 2444 bool AdvancePage() { |
2434 NewSpacePage* next_page = current_page_->next_page(); | 2445 NewSpacePage* next_page = current_page_->next_page(); |
2435 if (next_page == anchor()) return false; | 2446 if (next_page == anchor()) return false; |
2436 current_page_ = next_page; | 2447 current_page_ = next_page; |
2437 return true; | 2448 return true; |
2438 } | 2449 } |
2439 | 2450 |
2440 // Resets the space to using the first page. | 2451 // Resets the space to using the first page. |
2441 void Reset(); | 2452 void Reset(); |
2442 | 2453 |
| 2454 void ReplaceWithEmptyPage(NewSpacePage* page); |
| 2455 |
2443 // Age mark accessors. | 2456 // Age mark accessors. |
2444 Address age_mark() { return age_mark_; } | 2457 Address age_mark() { return age_mark_; } |
2445 void set_age_mark(Address mark); | 2458 void set_age_mark(Address mark); |
2446 | 2459 |
2447 // Returns the current capacity of the semispace. | 2460 // Returns the current capacity of the semispace. |
2448 int current_capacity() { return current_capacity_; } | 2461 int current_capacity() { return current_capacity_; } |
2449 | 2462 |
2450 // Returns the maximum capacity of the semispace. | 2463 // Returns the maximum capacity of the semispace. |
2451 int maximum_capacity() { return maximum_capacity_; } | 2464 int maximum_capacity() { return maximum_capacity_; } |
2452 | 2465 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 } | 2666 } |
2654 | 2667 |
2655 // Approximate amount of physical memory committed for this space. | 2668 // Approximate amount of physical memory committed for this space. |
2656 size_t CommittedPhysicalMemory() override; | 2669 size_t CommittedPhysicalMemory() override; |
2657 | 2670 |
2658 // Return the available bytes without growing. | 2671 // Return the available bytes without growing. |
2659 intptr_t Available() override { return Capacity() - Size(); } | 2672 intptr_t Available() override { return Capacity() - Size(); } |
2660 | 2673 |
2661 inline size_t AllocatedSinceLastGC(); | 2674 inline size_t AllocatedSinceLastGC(); |
2662 | 2675 |
| 2676 void ReplaceWithEmptyPage(NewSpacePage* page) { |
| 2677 // This method is called after flipping the semispace. |
| 2678 DCHECK(page->InFromSpace()); |
| 2679 from_space_.ReplaceWithEmptyPage(page); |
| 2680 } |
| 2681 |
2663 // Return the maximum capacity of a semispace. | 2682 // Return the maximum capacity of a semispace. |
2664 int MaximumCapacity() { | 2683 int MaximumCapacity() { |
2665 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); | 2684 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); |
2666 return to_space_.maximum_capacity(); | 2685 return to_space_.maximum_capacity(); |
2667 } | 2686 } |
2668 | 2687 |
2669 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } | 2688 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } |
2670 | 2689 |
2671 // Returns the initial capacity of a semispace. | 2690 // Returns the initial capacity of a semispace. |
2672 int InitialTotalCapacity() { | 2691 int InitialTotalCapacity() { |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3089 count = 0; | 3108 count = 0; |
3090 } | 3109 } |
3091 // Must be small, since an iteration is used for lookup. | 3110 // Must be small, since an iteration is used for lookup. |
3092 static const int kMaxComments = 64; | 3111 static const int kMaxComments = 64; |
3093 }; | 3112 }; |
3094 #endif | 3113 #endif |
3095 } // namespace internal | 3114 } // namespace internal |
3096 } // namespace v8 | 3115 } // namespace v8 |
3097 | 3116 |
3098 #endif // V8_HEAP_SPACES_H_ | 3117 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |