OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 // collection. The large object space is paged and uses the same remembered | 58 // collection. The large object space is paged and uses the same remembered |
59 // set implementation. Pages in large object space may be larger than 8K. | 59 // set implementation. Pages in large object space may be larger than 8K. |
60 // | 60 // |
61 // NOTE: The mark-compact collector rebuilds the remembered set after a | 61 // NOTE: The mark-compact collector rebuilds the remembered set after a |
62 // collection. It reuses first a few words of the remembered set for | 62 // collection. It reuses first a few words of the remembered set for |
63 // bookkeeping relocation information. | 63 // bookkeeping relocation information. |
64 | 64 |
65 | 65 |
66 // Some assertion macros used in the debugging mode. | 66 // Some assertion macros used in the debugging mode. |
67 | 67 |
68 #define ASSERT_PAGE_ALIGNED(address) \ | 68 #define ASSERT_PAGE_ALIGNED(address) \ |
69 ASSERT((OffsetFrom(address) & Page::kPageAlignmentMask) == 0) | 69 ASSERT((OffsetFrom(address) & Page::kPageAlignmentMask) == 0) |
70 | 70 |
71 #define ASSERT_OBJECT_ALIGNED(address) \ | 71 #define ASSERT_OBJECT_ALIGNED(address) \ |
72 ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0) | 72 ASSERT((OffsetFrom(address) & kObjectAlignmentMask) == 0) |
73 | 73 |
74 #define ASSERT_OBJECT_SIZE(size) \ | 74 #define ASSERT_MAP_ALIGNED(address) \ |
| 75 ASSERT((OffsetFrom(address) & kMapAlignmentMask) == 0) |
| 76 |
| 77 #define ASSERT_OBJECT_SIZE(size) \ |
75 ASSERT((0 < size) && (size <= Page::kMaxHeapObjectSize)) | 78 ASSERT((0 < size) && (size <= Page::kMaxHeapObjectSize)) |
76 | 79 |
77 #define ASSERT_PAGE_OFFSET(offset) \ | 80 #define ASSERT_PAGE_OFFSET(offset) \ |
78 ASSERT((Page::kObjectStartOffset <= offset) \ | 81 ASSERT((Page::kObjectStartOffset <= offset) \ |
79 && (offset <= Page::kPageSize)) | 82 && (offset <= Page::kPageSize)) |
80 | 83 |
81 #define ASSERT_MAP_PAGE_INDEX(index) \ | 84 #define ASSERT_MAP_PAGE_INDEX(index) \ |
82 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) | 85 ASSERT((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) |
83 | 86 |
84 | 87 |
85 class PagedSpace; | 88 class PagedSpace; |
86 class MemoryAllocator; | 89 class MemoryAllocator; |
87 class AllocationInfo; | 90 class AllocationInfo; |
88 | 91 |
89 // ----------------------------------------------------------------------------- | 92 // ----------------------------------------------------------------------------- |
90 // A page normally has 8K bytes. Large object pages may be larger. A page | 93 // A page normally has 8K bytes. Large object pages may be larger. A page |
91 // address is always aligned to the 8K page size. A page is divided into | 94 // address is always aligned to the 8K page size. A page is divided into |
92 // three areas: the first two words are used for bookkeeping, the next 248 | 95 // three areas: the first two words are used for bookkeeping, the next 248 |
93 // bytes are used as remembered set, and the rest of the page is the object | 96 // bytes are used as remembered set, and the rest of the page is the object |
94 // area. | 97 // area. |
95 // | 98 // |
96 // Pointers are aligned to the pointer size (4), only 1 bit is needed | 99 // Pointers are aligned to the pointer size (4), only 1 bit is needed |
97 // for a pointer in the remembered set. Given an address, its remembered set | 100 // for a pointer in the remembered set. Given an address, its remembered set |
98 // bit position (offset from the start of the page) is calculated by dividing | 101 // bit position (offset from the start of the page) is calculated by dividing |
99 // its page offset by 32. Therefore, the object area in a page starts at the | 102 // its page offset by 32. Therefore, the object area in a page starts at the |
100 // 256th byte (8K/32). Bytes 0 to 255 do not need the remembered set, so that | 103 // 256th byte (8K/32). Bytes 0 to 255 do not need the remembered set, so that |
101 // the first two words (64 bits) in a page can be used for other purposes. | 104 // the first two words (64 bits) in a page can be used for other purposes. |
102 // | 105 // |
103 // On the 64-bit platform, we add an offset to the start of the remembered set, | 106 // On the 64-bit platform, we add an offset to the start of the remembered set, |
104 // and pointers are aligned to 8-byte pointer size. This means that we need | 107 // and pointers are aligned to 8-byte pointer size. This means that we need |
105 // only 128 bytes for the RSet, and only get two bytes free in the RSet's RSet. | 108 // only 128 bytes for the RSet, and only get two bytes free in the RSet's RSet. |
106 // For this reason we add an offset to get room for the Page data at the start. | 109 // For this reason we add an offset to get room for the Page data at the start. |
107 // | 110 // |
108 // The mark-compact collector transforms a map pointer into a page index and a | 111 // The mark-compact collector transforms a map pointer into a page index and a |
109 // page offset. The map space can have up to 1024 pages, and 8M bytes (1024 * | 112 // page offset. The excact encoding is described in the comments for |
110 // 8K) in total. Because a map pointer is aligned to the pointer size (4 | 113 // class MapWord in objects.h. |
111 // bytes), 11 bits are enough to encode the page offset. 21 bits (10 for the | |
112 // page index + 11 for the offset in the page) are required to encode a map | |
113 // pointer. | |
114 // | 114 // |
115 // The only way to get a page pointer is by calling factory methods: | 115 // The only way to get a page pointer is by calling factory methods: |
116 // Page* p = Page::FromAddress(addr); or | 116 // Page* p = Page::FromAddress(addr); or |
117 // Page* p = Page::FromAllocationTop(top); | 117 // Page* p = Page::FromAllocationTop(top); |
118 class Page { | 118 class Page { |
119 public: | 119 public: |
120 // Returns the page containing a given address. The address ranges | 120 // Returns the page containing a given address. The address ranges |
121 // from [page_addr .. page_addr + kPageSize[ | 121 // from [page_addr .. page_addr + kPageSize[ |
122 // | 122 // |
123 // Note that this function only works for addresses in normal paged | 123 // Note that this function only works for addresses in normal paged |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 static inline bool IsRSetSet(Address address, int offset); | 205 static inline bool IsRSetSet(Address address, int offset); |
206 | 206 |
207 #ifdef DEBUG | 207 #ifdef DEBUG |
208 // Use a state to mark whether remembered set space can be used for other | 208 // Use a state to mark whether remembered set space can be used for other |
209 // purposes. | 209 // purposes. |
210 enum RSetState { IN_USE, NOT_IN_USE }; | 210 enum RSetState { IN_USE, NOT_IN_USE }; |
211 static bool is_rset_in_use() { return rset_state_ == IN_USE; } | 211 static bool is_rset_in_use() { return rset_state_ == IN_USE; } |
212 static void set_rset_state(RSetState state) { rset_state_ = state; } | 212 static void set_rset_state(RSetState state) { rset_state_ = state; } |
213 #endif | 213 #endif |
214 | 214 |
215 // 8K bytes per page. | |
216 static const int kPageSizeBits = 13; | |
217 | |
218 // Page size in bytes. This must be a multiple of the OS page size. | 215 // Page size in bytes. This must be a multiple of the OS page size. |
219 static const int kPageSize = 1 << kPageSizeBits; | 216 static const int kPageSize = 1 << kPageSizeBits; |
220 | 217 |
221 // Page size mask. | 218 // Page size mask. |
222 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; | 219 static const intptr_t kPageAlignmentMask = (1 << kPageSizeBits) - 1; |
223 | 220 |
224 // The offset of the remembered set in a page, in addition to the empty bytes | 221 // The offset of the remembered set in a page, in addition to the empty bytes |
225 // formed as the remembered bits of the remembered set itself. | 222 // formed as the remembered bits of the remembered set itself. |
226 #ifdef V8_TARGET_ARCH_X64 | 223 #ifdef V8_TARGET_ARCH_X64 |
227 static const int kRSetOffset = 4 * kPointerSize; // Room for four pointers. | 224 static const int kRSetOffset = 4 * kPointerSize; // Room for four pointers. |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 static inline void ProtectChunkFromPage(Page* page); | 504 static inline void ProtectChunkFromPage(Page* page); |
508 static inline void UnprotectChunkFromPage(Page* page); | 505 static inline void UnprotectChunkFromPage(Page* page); |
509 #endif | 506 #endif |
510 | 507 |
511 #ifdef DEBUG | 508 #ifdef DEBUG |
512 // Reports statistic info of the space. | 509 // Reports statistic info of the space. |
513 static void ReportStatistics(); | 510 static void ReportStatistics(); |
514 #endif | 511 #endif |
515 | 512 |
516 // Due to encoding limitation, we can only have 8K chunks. | 513 // Due to encoding limitation, we can only have 8K chunks. |
517 static const int kMaxNofChunks = 1 << Page::kPageSizeBits; | 514 static const int kMaxNofChunks = 1 << kPageSizeBits; |
518 // If a chunk has at least 16 pages, the maximum heap size is about | 515 // If a chunk has at least 16 pages, the maximum heap size is about |
519 // 8K * 8K * 16 = 1G bytes. | 516 // 8K * 8K * 16 = 1G bytes. |
520 #ifdef V8_TARGET_ARCH_X64 | 517 #ifdef V8_TARGET_ARCH_X64 |
521 static const int kPagesPerChunk = 32; | 518 static const int kPagesPerChunk = 32; |
522 #else | 519 #else |
523 static const int kPagesPerChunk = 16; | 520 static const int kPagesPerChunk = 16; |
524 #endif | 521 #endif |
525 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; | 522 static const int kChunkSize = kPagesPerChunk * Page::kPageSize; |
526 | 523 |
527 private: | 524 private: |
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 | 1946 |
1950 private: | 1947 private: |
1951 LargeObjectChunk* current_; | 1948 LargeObjectChunk* current_; |
1952 HeapObjectCallback size_func_; | 1949 HeapObjectCallback size_func_; |
1953 }; | 1950 }; |
1954 | 1951 |
1955 | 1952 |
1956 } } // namespace v8::internal | 1953 } } // namespace v8::internal |
1957 | 1954 |
1958 #endif // V8_SPACES_H_ | 1955 #endif // V8_SPACES_H_ |
OLD | NEW |