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 "vm/freelist.h" | 8 #include "vm/freelist.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/ring_buffer.h" | 10 #include "vm/ring_buffer.h" |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 Monitor* tasks_lock() const { return tasks_lock_; } | 299 Monitor* tasks_lock() const { return tasks_lock_; } |
300 intptr_t tasks() const { return tasks_; } | 300 intptr_t tasks() const { return tasks_; } |
301 void set_tasks(intptr_t val) { | 301 void set_tasks(intptr_t val) { |
302 ASSERT(val >= 0); | 302 ASSERT(val >= 0); |
303 tasks_ = val; | 303 tasks_ = val; |
304 } | 304 } |
305 | 305 |
306 // Attempt to allocate from bump block rather than normal freelist. | 306 // Attempt to allocate from bump block rather than normal freelist. |
307 uword TryAllocateDataBump(intptr_t size, GrowthPolicy growth_policy); | 307 uword TryAllocateDataBump(intptr_t size, GrowthPolicy growth_policy); |
308 uword TryAllocateDataBumpLocked(intptr_t size, GrowthPolicy growth_policy); | 308 uword TryAllocateDataBumpLocked(intptr_t size, GrowthPolicy growth_policy); |
| 309 // Prefer small freelist blocks, then chip away at the bump block. |
309 uword TryAllocatePromoLocked(intptr_t size, GrowthPolicy growth_policy); | 310 uword TryAllocatePromoLocked(intptr_t size, GrowthPolicy growth_policy); |
310 | 311 |
| 312 // Bump block allocation from generated code. |
| 313 uword* TopAddress() { return &bump_top_; } |
| 314 uword* EndAddress() { return &bump_end_; } |
| 315 |
311 private: | 316 private: |
312 // Ids for time and data records in Heap::GCStats. | 317 // Ids for time and data records in Heap::GCStats. |
313 enum { | 318 enum { |
314 // Time | 319 // Time |
315 kMarkObjects = 0, | 320 kMarkObjects = 0, |
316 kResetFreeLists = 1, | 321 kResetFreeLists = 1, |
317 kSweepPages = 2, | 322 kSweepPages = 2, |
318 kSweepLargePages = 3, | 323 kSweepLargePages = 3, |
319 // Data | 324 // Data |
320 kGarbageRatio = 0, | 325 kGarbageRatio = 0, |
321 kGCTimeFraction = 1, | 326 kGCTimeFraction = 1, |
322 kPageGrowth = 2, | 327 kPageGrowth = 2, |
323 kAllowedGrowth = 3 | 328 kAllowedGrowth = 3 |
324 }; | 329 }; |
325 | 330 |
326 static const intptr_t kAllocatablePageSize = 64 * KB; | 331 static const intptr_t kAllocatablePageSize = 64 * KB; |
327 | 332 |
328 uword TryAllocateInternal(intptr_t size, | 333 uword TryAllocateInternal(intptr_t size, |
329 HeapPage::PageType type, | 334 HeapPage::PageType type, |
330 GrowthPolicy growth_policy, | 335 GrowthPolicy growth_policy, |
331 bool is_protected, | 336 bool is_protected, |
332 bool is_locked); | 337 bool is_locked); |
333 uword TryAllocateInFreshPage(intptr_t size, | 338 uword TryAllocateInFreshPage(intptr_t size, |
334 HeapPage::PageType type, | 339 HeapPage::PageType type, |
335 GrowthPolicy growth_policy, | 340 GrowthPolicy growth_policy, |
336 bool is_locked); | 341 bool is_locked); |
337 uword TryAllocateDataBumpInternal(intptr_t size, | 342 uword TryAllocateDataBumpInternal(intptr_t size, |
338 GrowthPolicy growth_policy, | 343 GrowthPolicy growth_policy, |
339 bool is_locked); | 344 bool is_locked); |
| 345 // Makes bump block walkable; do not call concurrently with mutator. |
| 346 void MakeIterable() const; |
340 HeapPage* AllocatePage(HeapPage::PageType type); | 347 HeapPage* AllocatePage(HeapPage::PageType type); |
341 void FreePage(HeapPage* page, HeapPage* previous_page); | 348 void FreePage(HeapPage* page, HeapPage* previous_page); |
342 HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type); | 349 HeapPage* AllocateLargePage(intptr_t size, HeapPage::PageType type); |
343 void TruncateLargePage(HeapPage* page, intptr_t new_object_size_in_bytes); | 350 void TruncateLargePage(HeapPage* page, intptr_t new_object_size_in_bytes); |
344 void FreeLargePage(HeapPage* page, HeapPage* previous_page); | 351 void FreeLargePage(HeapPage* page, HeapPage* previous_page); |
345 void FreePages(HeapPage* pages); | 352 void FreePages(HeapPage* pages); |
346 HeapPage* NextPageAnySize(HeapPage* page) const { | 353 HeapPage* NextPageAnySize(HeapPage* page) const { |
347 ASSERT((pages_tail_ == NULL) || (pages_tail_->next() == NULL)); | 354 ASSERT((pages_tail_ == NULL) || (pages_tail_->next() == NULL)); |
348 ASSERT((exec_pages_tail_ == NULL) || (exec_pages_tail_->next() == NULL)); | 355 ASSERT((exec_pages_tail_ == NULL) || (exec_pages_tail_->next() == NULL)); |
349 if (page == pages_tail_) { | 356 if (page == pages_tail_) { |
350 return (exec_pages_ != NULL) ? exec_pages_ : large_pages_; | 357 return (exec_pages_ != NULL) ? exec_pages_ : large_pages_; |
351 } | 358 } |
352 return page == exec_pages_tail_ ? large_pages_ : page->next(); | 359 return page == exec_pages_tail_ ? large_pages_ : page->next(); |
353 } | 360 } |
354 | 361 |
355 static intptr_t LargePageSizeInWordsFor(intptr_t size); | 362 static intptr_t LargePageSizeInWordsFor(intptr_t size); |
356 | 363 |
357 bool CanIncreaseCapacityInWords(intptr_t increase_in_words) { | 364 bool CanIncreaseCapacityInWords(intptr_t increase_in_words) { |
358 ASSERT(CapacityInWords() <= max_capacity_in_words_); | 365 ASSERT(CapacityInWords() <= max_capacity_in_words_); |
359 return increase_in_words <= (max_capacity_in_words_ - CapacityInWords()); | 366 return increase_in_words <= (max_capacity_in_words_ - CapacityInWords()); |
360 } | 367 } |
361 | 368 |
362 FreeList freelist_[HeapPage::kNumPageTypes]; | 369 FreeList freelist_[HeapPage::kNumPageTypes]; |
363 | 370 |
364 Heap* heap_; | 371 Heap* heap_; |
365 | 372 |
| 373 // Use ExclusivePageIterator for safe access to these. |
366 Mutex* pages_lock_; | 374 Mutex* pages_lock_; |
367 HeapPage* pages_; | 375 HeapPage* pages_; |
368 HeapPage* pages_tail_; | 376 HeapPage* pages_tail_; |
369 HeapPage* exec_pages_; | 377 HeapPage* exec_pages_; |
370 HeapPage* exec_pages_tail_; | 378 HeapPage* exec_pages_tail_; |
371 HeapPage* large_pages_; | 379 HeapPage* large_pages_; |
372 | 380 |
373 // A block of memory in a data page, managed by bump allocation. The remainder | 381 // A block of memory in a data page, managed by bump allocation. The remainder |
374 // is kept formatted as a FreeListElement, but is not in any freelist. | 382 // is kept formatted as a FreeListElement, but is not in any freelist. |
375 uword bump_top_; | 383 uword bump_top_; |
376 uword bump_end_; | 384 uword bump_end_; |
377 | 385 |
378 // Various sizes being tracked for this generation. | 386 // Various sizes being tracked for this generation. |
379 intptr_t max_capacity_in_words_; | 387 intptr_t max_capacity_in_words_; |
380 SpaceUsage usage_; | 388 SpaceUsage usage_; |
381 | 389 |
382 // Keep track of running MarkSweep tasks. | 390 // Keep track of running MarkSweep tasks. |
383 Monitor* tasks_lock_; | 391 Monitor* tasks_lock_; |
384 intptr_t tasks_; | 392 intptr_t tasks_; |
385 | 393 |
386 PageSpaceController page_space_controller_; | 394 PageSpaceController page_space_controller_; |
387 | 395 |
388 int64_t gc_time_micros_; | 396 int64_t gc_time_micros_; |
389 intptr_t collections_; | 397 intptr_t collections_; |
390 | 398 |
| 399 friend class ExclusivePageIterator; |
391 friend class PageSpaceController; | 400 friend class PageSpaceController; |
392 friend class SweeperTask; | 401 friend class SweeperTask; |
393 | 402 |
394 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); | 403 DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace); |
395 }; | 404 }; |
396 | 405 |
397 } // namespace dart | 406 } // namespace dart |
398 | 407 |
399 #endif // VM_PAGES_H_ | 408 #endif // VM_PAGES_H_ |
OLD | NEW |