| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_PAGES_H_ | 5 #ifndef VM_PAGES_H_ |
| 6 #define VM_PAGES_H_ | 6 #define VM_PAGES_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "vm/freelist.h" | 10 #include "vm/freelist.h" |
| 11 #include "vm/globals.h" | 11 #include "vm/globals.h" |
| 12 #include "vm/virtual_memory.h" | 12 #include "vm/virtual_memory.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 // Forward declarations. | 16 // Forward declarations. |
| 17 class Heap; | 17 class Heap; |
| 18 class ObjectPointerVisitor; | 18 class ObjectPointerVisitor; |
| 19 | 19 |
| 20 // An aligned page containing old generation objects. Alignment is used to be | 20 // An aligned page containing old generation objects. Alignment is used to be |
| 21 // able to get to a HeapPage header quickly based on a pointer to an object. | 21 // able to get to a HeapPage header quickly based on a pointer to an object. |
| 22 class HeapPage { | 22 class HeapPage { |
| 23 public: | 23 public: |
| 24 enum PageType { |
| 25 kData = 0, |
| 26 kExecutable, |
| 27 kNumPageTypes |
| 28 }; |
| 29 |
| 24 HeapPage* next() const { return next_; } | 30 HeapPage* next() const { return next_; } |
| 25 void set_next(HeapPage* next) { next_ = next; } | 31 void set_next(HeapPage* next) { next_ = next; } |
| 26 | 32 |
| 27 bool Contains(uword addr) { | 33 bool Contains(uword addr) { |
| 28 return memory_->Contains(addr); | 34 return memory_->Contains(addr); |
| 29 } | 35 } |
| 30 | 36 |
| 31 uword object_start() const { | 37 uword object_start() const { |
| 32 return (reinterpret_cast<uword>(this) + sizeof(HeapPage)); | 38 return (reinterpret_cast<uword>(this) + |
| 39 Utils::RoundUp(sizeof(HeapPage), kObjectAlignment)); |
| 33 } | 40 } |
| 34 uword object_end() const { | 41 uword object_end() const { |
| 35 return object_end_; | 42 return object_end_; |
| 36 } | 43 } |
| 37 | 44 |
| 38 void set_used(uword used) { used_ = used; } | 45 void set_used(uword used) { used_ = used; } |
| 39 uword used() const { return used_; } | 46 uword used() const { return used_; } |
| 40 void AddUsed(uword size) { | 47 void AddUsed(uword size) { |
| 41 used_ += size; | 48 used_ += size; |
| 42 } | 49 } |
| 43 | 50 |
| 51 PageType type() const { |
| 52 return executable_ ? kExecutable : kData; |
| 53 } |
| 54 |
| 44 void VisitObjects(ObjectVisitor* visitor) const; | 55 void VisitObjects(ObjectVisitor* visitor) const; |
| 45 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; | 56 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; |
| 46 | 57 |
| 47 RawObject* FindObject(FindObjectVisitor* visitor) const; | 58 RawObject* FindObject(FindObjectVisitor* visitor) const; |
| 48 | 59 |
| 49 void WriteProtect(bool read_only); | 60 void WriteProtect(bool read_only); |
| 50 | 61 |
| 51 private: | 62 private: |
| 52 void set_object_end(uword val) { | 63 void set_object_end(uword val) { |
| 53 ASSERT((val & kObjectAlignmentMask) == kOldObjectAlignmentOffset); | 64 ASSERT((val & kObjectAlignmentMask) == kOldObjectAlignmentOffset); |
| 54 object_end_ = val; | 65 object_end_ = val; |
| 55 } | 66 } |
| 56 | 67 |
| 57 static HeapPage* Initialize(VirtualMemory* memory, bool is_executable); | 68 static HeapPage* Initialize(VirtualMemory* memory, PageType type); |
| 58 static HeapPage* Allocate(intptr_t size, bool is_executable); | 69 static HeapPage* Allocate(intptr_t size, PageType type); |
| 59 | 70 |
| 60 // Deallocate the virtual memory backing this page. The page pointer to this | 71 // Deallocate the virtual memory backing this page. The page pointer to this |
| 61 // page becomes immediately inaccessible. | 72 // page becomes immediately inaccessible. |
| 62 void Deallocate(); | 73 void Deallocate(); |
| 63 | 74 |
| 64 VirtualMemory* memory_; | 75 VirtualMemory* memory_; |
| 65 HeapPage* next_; | 76 HeapPage* next_; |
| 66 uword used_; | 77 uword used_; |
| 67 uword object_end_; | 78 uword object_end_; |
| 79 bool executable_; |
| 68 | 80 |
| 69 friend class PageSpace; | 81 friend class PageSpace; |
| 70 | 82 |
| 71 DISALLOW_ALLOCATION(); | 83 DISALLOW_ALLOCATION(); |
| 72 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapPage); | 84 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapPage); |
| 73 }; | 85 }; |
| 74 | 86 |
| 75 | 87 |
| 76 // The history holds the timing information of the last garbage collection | 88 // The history holds the timing information of the last garbage collection |
| 77 // runs. | 89 // runs. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 public: | 162 public: |
| 151 // TODO(iposva): Determine heap sizes and tune the page size accordingly. | 163 // TODO(iposva): Determine heap sizes and tune the page size accordingly. |
| 152 static const intptr_t kPageSize = 256 * KB; | 164 static const intptr_t kPageSize = 256 * KB; |
| 153 static const intptr_t kPageAlignment = kPageSize; | 165 static const intptr_t kPageAlignment = kPageSize; |
| 154 | 166 |
| 155 enum GrowthPolicy { | 167 enum GrowthPolicy { |
| 156 kControlGrowth, | 168 kControlGrowth, |
| 157 kForceGrowth | 169 kForceGrowth |
| 158 }; | 170 }; |
| 159 | 171 |
| 160 PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable = false); | 172 PageSpace(Heap* heap, intptr_t max_capacity); |
| 161 ~PageSpace(); | 173 ~PageSpace(); |
| 162 | 174 |
| 163 uword TryAllocate(intptr_t size); | 175 uword TryAllocate(intptr_t size, |
| 164 uword TryAllocate(intptr_t size, GrowthPolicy growth_policy); | 176 HeapPage::PageType type = HeapPage::kData, |
| 177 GrowthPolicy growth_policy = kControlGrowth); |
| 165 | 178 |
| 166 intptr_t in_use() const { return in_use_; } | 179 intptr_t in_use() const { return in_use_; } |
| 167 intptr_t capacity() const { return capacity_; } | 180 intptr_t capacity() const { return capacity_; } |
| 168 | 181 |
| 169 bool Contains(uword addr) const; | 182 bool Contains(uword addr) const; |
| 183 bool Contains(uword addr, HeapPage::PageType type) const; |
| 170 bool IsValidAddress(uword addr) const { | 184 bool IsValidAddress(uword addr) const { |
| 171 return Contains(addr); | 185 return Contains(addr); |
| 172 } | 186 } |
| 173 static bool IsPageAllocatableSize(intptr_t size) { | 187 static bool IsPageAllocatableSize(intptr_t size) { |
| 174 return size <= kAllocatablePageSize; | 188 return size <= kAllocatablePageSize; |
| 175 } | 189 } |
| 176 | 190 |
| 177 void VisitObjects(ObjectVisitor* visitor) const; | 191 void VisitObjects(ObjectVisitor* visitor) const; |
| 178 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; | 192 void VisitObjectPointers(ObjectPointerVisitor* visitor) const; |
| 179 | 193 |
| 180 RawObject* FindObject(FindObjectVisitor* visitor) const; | 194 RawObject* FindObject(FindObjectVisitor* visitor, |
| 195 HeapPage::PageType type) const; |
| 181 | 196 |
| 182 // Collect the garbage in the page space using mark-sweep. | 197 // Collect the garbage in the page space using mark-sweep. |
| 183 void MarkSweep(bool invoke_api_callbacks, const char* gc_reason); | 198 void MarkSweep(bool invoke_api_callbacks, const char* gc_reason); |
| 184 | 199 |
| 185 static HeapPage* PageFor(RawObject* raw_obj) { | 200 static HeapPage* PageFor(RawObject* raw_obj) { |
| 186 return reinterpret_cast<HeapPage*>( | 201 return reinterpret_cast<HeapPage*>( |
| 187 RawObject::ToAddr(raw_obj) & ~(kPageSize -1)); | 202 RawObject::ToAddr(raw_obj) & ~(kPageSize -1)); |
| 188 } | 203 } |
| 189 | 204 |
| 190 void StartEndAddress(uword* start, uword* end) const; | 205 void StartEndAddress(uword* start, uword* end) const; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 201 | 216 |
| 202 void* GetPeer(RawObject* raw_obj); | 217 void* GetPeer(RawObject* raw_obj); |
| 203 | 218 |
| 204 int64_t PeerCount() const; | 219 int64_t PeerCount() const; |
| 205 | 220 |
| 206 PeerTable* GetPeerTable() { return &peer_table_; } | 221 PeerTable* GetPeerTable() { return &peer_table_; } |
| 207 | 222 |
| 208 private: | 223 private: |
| 209 static const intptr_t kAllocatablePageSize = kPageSize - sizeof(HeapPage); | 224 static const intptr_t kAllocatablePageSize = kPageSize - sizeof(HeapPage); |
| 210 | 225 |
| 211 HeapPage* AllocatePage(); | 226 HeapPage* AllocatePage(HeapPage::PageType type); |
| 212 void FreePage(HeapPage* page, HeapPage* previous_page); | 227 void FreePage(HeapPage* page, HeapPage* previous_page); |
| 213 HeapPage* AllocateLargePage(intptr_t size); | 228 HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type); |
| 214 void FreeLargePage(HeapPage* page, HeapPage* previous_page); | 229 void FreeLargePage(HeapPage* page, HeapPage* previous_page); |
| 215 void FreePages(HeapPage* pages); | 230 void FreePages(HeapPage* pages); |
| 216 | 231 |
| 217 static intptr_t LargePageSizeFor(intptr_t size); | 232 static intptr_t LargePageSizeFor(intptr_t size); |
| 218 | 233 |
| 219 bool CanIncreaseCapacity(intptr_t increase) { | 234 bool CanIncreaseCapacity(intptr_t increase) { |
| 220 ASSERT(capacity_ <= max_capacity_); | 235 ASSERT(capacity_ <= max_capacity_); |
| 221 return increase <= (max_capacity_ - capacity_); | 236 return increase <= (max_capacity_ - capacity_); |
| 222 } | 237 } |
| 223 | 238 |
| 224 FreeList freelist_; | 239 FreeList freelist_[HeapPage::kNumPageTypes]; |
| 225 | 240 |
| 226 Heap* heap_; | 241 Heap* heap_; |
| 227 | 242 |
| 228 HeapPage* pages_; | 243 HeapPage* pages_; |
| 229 HeapPage* pages_tail_; | 244 HeapPage* pages_tail_; |
| 230 HeapPage* large_pages_; | 245 HeapPage* large_pages_; |
| 231 | 246 |
| 232 PeerTable peer_table_; | 247 PeerTable peer_table_; |
| 233 | 248 |
| 234 // Various sizes being tracked for this generation. | 249 // Various sizes being tracked for this generation. |
| 235 intptr_t max_capacity_; | 250 intptr_t max_capacity_; |
| 236 intptr_t capacity_; | 251 intptr_t capacity_; |
| 237 intptr_t in_use_; | 252 intptr_t in_use_; |
| 238 | 253 |
| 239 // Old-gen GC cycle count. | 254 // Old-gen GC cycle count. |
| 240 int count_; | 255 int count_; |
| 241 | 256 |
| 242 bool is_executable_; | |
| 243 | |
| 244 // Keep track whether a MarkSweep is currently running. | 257 // Keep track whether a MarkSweep is currently running. |
| 245 bool sweeping_; | 258 bool sweeping_; |
| 246 | 259 |
| 247 PageSpaceController page_space_controller_; | 260 PageSpaceController page_space_controller_; |
| 248 | 261 |
| 249 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); | 262 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); |
| 250 }; | 263 }; |
| 251 | 264 |
| 252 } // namespace dart | 265 } // namespace dart |
| 253 | 266 |
| 254 #endif // VM_PAGES_H_ | 267 #endif // VM_PAGES_H_ |
| OLD | NEW |