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 <list> | 8 #include <list> |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 // Large objects can have a progress bar in their page header. These object | 418 // Large objects can have a progress bar in their page header. These object |
419 // are scanned in increments and will be kept black while being scanned. | 419 // are scanned in increments and will be kept black while being scanned. |
420 // Even if the mutator writes to them they will be kept black and a white | 420 // Even if the mutator writes to them they will be kept black and a white |
421 // to grey transition is performed in the value. | 421 // to grey transition is performed in the value. |
422 HAS_PROGRESS_BAR, | 422 HAS_PROGRESS_BAR, |
423 | 423 |
424 // |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted | 424 // |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted |
425 // from new to old space during evacuation. | 425 // from new to old space during evacuation. |
426 PAGE_NEW_OLD_PROMOTION, | 426 PAGE_NEW_OLD_PROMOTION, |
427 | 427 |
428 // |PAGE_NEW_NEW_PROMOTION|: A page tagged with this flag has been moved | |
429 // within the new space during evacuation. | |
430 PAGE_NEW_NEW_PROMOTION, | |
431 | |
428 // A black page has all mark bits set to 1 (black). A black page currently | 432 // A black page has all mark bits set to 1 (black). A black page currently |
429 // cannot be iterated because it is not swept. Moreover live bytes are also | 433 // cannot be iterated because it is not swept. Moreover live bytes are also |
430 // not updated. | 434 // not updated. |
431 BLACK_PAGE, | 435 BLACK_PAGE, |
432 | 436 |
433 // This flag is intended to be used for testing. Works only when both | 437 // This flag is intended to be used for testing. Works only when both |
434 // FLAG_stress_compaction and FLAG_manual_evacuation_candidates_selection | 438 // FLAG_stress_compaction and FLAG_manual_evacuation_candidates_selection |
435 // are set. It forces the page to become an evacuation candidate at next | 439 // are set. It forces the page to become an evacuation candidate at next |
436 // candidates selection cycle. | 440 // candidates selection cycle. |
437 FORCE_EVACUATION_CANDIDATE_FOR_TESTING, | 441 FORCE_EVACUATION_CANDIDATE_FOR_TESTING, |
(...skipping 1963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2401 | 2405 |
2402 SemiSpace(Heap* heap, SemiSpaceId semispace) | 2406 SemiSpace(Heap* heap, SemiSpaceId semispace) |
2403 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2407 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2404 current_capacity_(0), | 2408 current_capacity_(0), |
2405 maximum_capacity_(0), | 2409 maximum_capacity_(0), |
2406 minimum_capacity_(0), | 2410 minimum_capacity_(0), |
2407 age_mark_(nullptr), | 2411 age_mark_(nullptr), |
2408 committed_(false), | 2412 committed_(false), |
2409 id_(semispace), | 2413 id_(semispace), |
2410 anchor_(this), | 2414 anchor_(this), |
2411 current_page_(nullptr) {} | 2415 current_page_(nullptr), |
2416 pages_used_(0) {} | |
2412 | 2417 |
2413 inline bool Contains(HeapObject* o); | 2418 inline bool Contains(HeapObject* o); |
2414 inline bool Contains(Object* o); | 2419 inline bool Contains(Object* o); |
2415 inline bool ContainsSlow(Address a); | 2420 inline bool ContainsSlow(Address a); |
2416 | 2421 |
2417 void SetUp(int initial_capacity, int maximum_capacity); | 2422 void SetUp(int initial_capacity, int maximum_capacity); |
2418 void TearDown(); | 2423 void TearDown(); |
2419 bool HasBeenSetUp() { return maximum_capacity_ != 0; } | 2424 bool HasBeenSetUp() { return maximum_capacity_ != 0; } |
2420 | 2425 |
2421 bool Commit(); | 2426 bool Commit(); |
2422 bool Uncommit(); | 2427 bool Uncommit(); |
2423 bool is_committed() { return committed_; } | 2428 bool is_committed() { return committed_; } |
2424 | 2429 |
2425 // Grow the semispace to the new capacity. The new capacity requested must | 2430 // Grow the semispace to the new capacity. The new capacity requested must |
2426 // be larger than the current capacity and less than the maximum capacity. | 2431 // be larger than the current capacity and less than the maximum capacity. |
2427 bool GrowTo(int new_capacity); | 2432 bool GrowTo(int new_capacity); |
2428 | 2433 |
2429 // Shrinks the semispace to the new capacity. The new capacity requested | 2434 // Shrinks the semispace to the new capacity. The new capacity requested |
2430 // must be more than the amount of used memory in the semispace and less | 2435 // must be more than the amount of used memory in the semispace and less |
2431 // than the current capacity. | 2436 // than the current capacity. |
2432 bool ShrinkTo(int new_capacity); | 2437 bool ShrinkTo(int new_capacity); |
2433 | 2438 |
2439 bool EnsureCurrentCapacity(); | |
2440 | |
2434 // Returns the start address of the first page of the space. | 2441 // Returns the start address of the first page of the space. |
2435 Address space_start() { | 2442 Address space_start() { |
2436 DCHECK_NE(anchor_.next_page(), anchor()); | 2443 DCHECK_NE(anchor_.next_page(), anchor()); |
2437 return anchor_.next_page()->area_start(); | 2444 return anchor_.next_page()->area_start(); |
2438 } | 2445 } |
2439 | 2446 |
2440 Page* first_page() { return anchor_.next_page(); } | 2447 Page* first_page() { return anchor_.next_page(); } |
2441 Page* current_page() { return current_page_; } | 2448 Page* current_page() { return current_page_; } |
2449 int pages_used() { return pages_used_; } | |
2442 | 2450 |
2443 // Returns one past the end address of the space. | 2451 // Returns one past the end address of the space. |
2444 Address space_end() { return anchor_.prev_page()->area_end(); } | 2452 Address space_end() { return anchor_.prev_page()->area_end(); } |
2445 | 2453 |
2446 // Returns the start address of the current page of the space. | 2454 // Returns the start address of the current page of the space. |
2447 Address page_low() { return current_page_->area_start(); } | 2455 Address page_low() { return current_page_->area_start(); } |
2448 | 2456 |
2449 // Returns one past the end address of the current page of the space. | 2457 // Returns one past the end address of the current page of the space. |
2450 Address page_high() { return current_page_->area_end(); } | 2458 Address page_high() { return current_page_->area_end(); } |
2451 | 2459 |
2452 bool AdvancePage() { | 2460 bool AdvancePage() { |
2453 Page* next_page = current_page_->next_page(); | 2461 Page* next_page = current_page_->next_page(); |
2454 if (next_page == anchor()) return false; | 2462 if (next_page == anchor() || (pages_used_ == max_pages())) { |
ulan
2016/06/17 13:59:48
nit: no need for braces in (pages_used_ == max_pag
Michael Lippautz
2016/06/17 14:32:02
Done.
| |
2463 return false; | |
2464 } | |
2455 current_page_ = next_page; | 2465 current_page_ = next_page; |
2466 pages_used_++; | |
2456 return true; | 2467 return true; |
2457 } | 2468 } |
2458 | 2469 |
2459 // Resets the space to using the first page. | 2470 // Resets the space to using the first page. |
2460 void Reset(); | 2471 void Reset(); |
2461 | 2472 |
2462 bool ReplaceWithEmptyPage(Page* page); | 2473 void RemovePage(Page* page); |
2474 void PrependPage(Page* page); | |
2463 | 2475 |
2464 // Age mark accessors. | 2476 // Age mark accessors. |
2465 Address age_mark() { return age_mark_; } | 2477 Address age_mark() { return age_mark_; } |
2466 void set_age_mark(Address mark); | 2478 void set_age_mark(Address mark); |
2467 | 2479 |
2468 // Returns the current capacity of the semispace. | 2480 // Returns the current capacity of the semispace. |
2469 int current_capacity() { return current_capacity_; } | 2481 int current_capacity() { return current_capacity_; } |
2470 | 2482 |
2471 // Returns the maximum capacity of the semispace. | 2483 // Returns the maximum capacity of the semispace. |
2472 int maximum_capacity() { return maximum_capacity_; } | 2484 int maximum_capacity() { return maximum_capacity_; } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2506 #endif | 2518 #endif |
2507 | 2519 |
2508 #ifdef VERIFY_HEAP | 2520 #ifdef VERIFY_HEAP |
2509 virtual void Verify(); | 2521 virtual void Verify(); |
2510 #endif | 2522 #endif |
2511 | 2523 |
2512 private: | 2524 private: |
2513 void RewindPages(Page* start, int num_pages); | 2525 void RewindPages(Page* start, int num_pages); |
2514 | 2526 |
2515 inline Page* anchor() { return &anchor_; } | 2527 inline Page* anchor() { return &anchor_; } |
2528 inline int max_pages() { return current_capacity_ / Page::kPageSize; } | |
2516 | 2529 |
2517 // Copies the flags into the masked positions on all pages in the space. | 2530 // Copies the flags into the masked positions on all pages in the space. |
2518 void FixPagesFlags(intptr_t flags, intptr_t flag_mask); | 2531 void FixPagesFlags(intptr_t flags, intptr_t flag_mask); |
2519 | 2532 |
2520 // The currently committed space capacity. | 2533 // The currently committed space capacity. |
2521 int current_capacity_; | 2534 int current_capacity_; |
2522 | 2535 |
2523 // The maximum capacity that can be used by this space. | 2536 // The maximum capacity that can be used by this space. A space cannot grow |
2537 // beyond that size. | |
2524 int maximum_capacity_; | 2538 int maximum_capacity_; |
2525 | 2539 |
2526 // The minimum capacity for the space. A space cannot shrink below this size. | 2540 // The minimum capacity for the space. A space cannot shrink below this size. |
2527 int minimum_capacity_; | 2541 int minimum_capacity_; |
2528 | 2542 |
2529 // Used to govern object promotion during mark-compact collection. | 2543 // Used to govern object promotion during mark-compact collection. |
2530 Address age_mark_; | 2544 Address age_mark_; |
2531 | 2545 |
2532 bool committed_; | 2546 bool committed_; |
2533 SemiSpaceId id_; | 2547 SemiSpaceId id_; |
2534 | 2548 |
2535 Page anchor_; | 2549 Page anchor_; |
2536 Page* current_page_; | 2550 Page* current_page_; |
2551 int pages_used_; | |
2537 | 2552 |
2553 friend class NewSpace; | |
2554 friend class NewSpacePageIterator; | |
2538 friend class SemiSpaceIterator; | 2555 friend class SemiSpaceIterator; |
2539 friend class NewSpacePageIterator; | |
2540 }; | 2556 }; |
2541 | 2557 |
2542 | 2558 |
2543 // A SemiSpaceIterator is an ObjectIterator that iterates over the active | 2559 // A SemiSpaceIterator is an ObjectIterator that iterates over the active |
2544 // semispace of the heap's new space. It iterates over the objects in the | 2560 // semispace of the heap's new space. It iterates over the objects in the |
2545 // semispace from a given start address (defaulting to the bottom of the | 2561 // semispace from a given start address (defaulting to the bottom of the |
2546 // semispace) to the top of the semispace. New objects allocated after the | 2562 // semispace) to the top of the semispace. New objects allocated after the |
2547 // iterator is created are not iterated. | 2563 // iterator is created are not iterated. |
2548 class SemiSpaceIterator : public ObjectIterator { | 2564 class SemiSpaceIterator : public ObjectIterator { |
2549 public: | 2565 public: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2599 // The new space consists of a contiguous pair of semispaces. It simply | 2615 // The new space consists of a contiguous pair of semispaces. It simply |
2600 // forwards most functions to the appropriate semispace. | 2616 // forwards most functions to the appropriate semispace. |
2601 | 2617 |
2602 class NewSpace : public Space { | 2618 class NewSpace : public Space { |
2603 public: | 2619 public: |
2604 explicit NewSpace(Heap* heap) | 2620 explicit NewSpace(Heap* heap) |
2605 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2621 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2606 to_space_(heap, kToSpace), | 2622 to_space_(heap, kToSpace), |
2607 from_space_(heap, kFromSpace), | 2623 from_space_(heap, kFromSpace), |
2608 reservation_(), | 2624 reservation_(), |
2609 pages_used_(0), | |
2610 top_on_previous_step_(0), | 2625 top_on_previous_step_(0), |
2611 allocated_histogram_(nullptr), | 2626 allocated_histogram_(nullptr), |
2612 promoted_histogram_(nullptr) {} | 2627 promoted_histogram_(nullptr) {} |
2613 | 2628 |
2614 inline bool Contains(HeapObject* o); | 2629 inline bool Contains(HeapObject* o); |
2615 inline bool ContainsSlow(Address a); | 2630 inline bool ContainsSlow(Address a); |
2616 inline bool Contains(Object* o); | 2631 inline bool Contains(Object* o); |
2617 | 2632 |
2618 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); | 2633 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); |
2619 | 2634 |
(...skipping 11 matching lines...) Expand all Loading... | |
2631 | 2646 |
2632 // Grow the capacity of the semispaces. Assumes that they are not at | 2647 // Grow the capacity of the semispaces. Assumes that they are not at |
2633 // their maximum capacity. | 2648 // their maximum capacity. |
2634 void Grow(); | 2649 void Grow(); |
2635 | 2650 |
2636 // Shrink the capacity of the semispaces. | 2651 // Shrink the capacity of the semispaces. |
2637 void Shrink(); | 2652 void Shrink(); |
2638 | 2653 |
2639 // Return the allocated bytes in the active semispace. | 2654 // Return the allocated bytes in the active semispace. |
2640 intptr_t Size() override { | 2655 intptr_t Size() override { |
2641 return pages_used_ * Page::kAllocatableMemory + | 2656 return to_space_.pages_used() * Page::kAllocatableMemory + |
2642 static_cast<int>(top() - to_space_.page_low()); | 2657 static_cast<int>(top() - to_space_.page_low()); |
2643 } | 2658 } |
2644 | 2659 |
2645 // The same, but returning an int. We have to have the one that returns | 2660 // The same, but returning an int. We have to have the one that returns |
2646 // intptr_t because it is inherited, but if we know we are dealing with the | 2661 // intptr_t because it is inherited, but if we know we are dealing with the |
2647 // new space, which can't get as big as the other spaces then this is useful: | 2662 // new space, which can't get as big as the other spaces then this is useful: |
2648 int SizeAsInt() { return static_cast<int>(Size()); } | 2663 int SizeAsInt() { return static_cast<int>(Size()); } |
2649 | 2664 |
2650 // Return the allocatable capacity of a semispace. | 2665 // Return the allocatable capacity of a semispace. |
2651 intptr_t Capacity() { | 2666 intptr_t Capacity() { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2708 while (current_page != last_page) { | 2723 while (current_page != last_page) { |
2709 allocated += Page::kAllocatableMemory; | 2724 allocated += Page::kAllocatableMemory; |
2710 current_page = current_page->next_page(); | 2725 current_page = current_page->next_page(); |
2711 } | 2726 } |
2712 allocated += top() - current_page->area_start(); | 2727 allocated += top() - current_page->area_start(); |
2713 DCHECK_LE(0, allocated); | 2728 DCHECK_LE(0, allocated); |
2714 DCHECK_LE(allocated, Size()); | 2729 DCHECK_LE(allocated, Size()); |
2715 return static_cast<size_t>(allocated); | 2730 return static_cast<size_t>(allocated); |
2716 } | 2731 } |
2717 | 2732 |
2718 bool ReplaceWithEmptyPage(Page* page) { | 2733 void MovePageFromSpaceToSpace(Page* page) { |
2719 // This method is called after flipping the semispace. | |
2720 DCHECK(page->InFromSpace()); | 2734 DCHECK(page->InFromSpace()); |
2721 return from_space_.ReplaceWithEmptyPage(page); | 2735 from_space_.RemovePage(page); |
2736 to_space_.PrependPage(page); | |
2722 } | 2737 } |
2723 | 2738 |
2739 bool Rebalance(); | |
2740 | |
2724 // Return the maximum capacity of a semispace. | 2741 // Return the maximum capacity of a semispace. |
2725 int MaximumCapacity() { | 2742 int MaximumCapacity() { |
2726 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); | 2743 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); |
2727 return to_space_.maximum_capacity(); | 2744 return to_space_.maximum_capacity(); |
2728 } | 2745 } |
2729 | 2746 |
2730 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } | 2747 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } |
2731 | 2748 |
2732 // Returns the initial capacity of a semispace. | 2749 // Returns the initial capacity of a semispace. |
2733 int InitialTotalCapacity() { | 2750 int InitialTotalCapacity() { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2866 private: | 2883 private: |
2867 // Update allocation info to match the current to-space page. | 2884 // Update allocation info to match the current to-space page. |
2868 void UpdateAllocationInfo(); | 2885 void UpdateAllocationInfo(); |
2869 | 2886 |
2870 base::Mutex mutex_; | 2887 base::Mutex mutex_; |
2871 | 2888 |
2872 // The semispaces. | 2889 // The semispaces. |
2873 SemiSpace to_space_; | 2890 SemiSpace to_space_; |
2874 SemiSpace from_space_; | 2891 SemiSpace from_space_; |
2875 base::VirtualMemory reservation_; | 2892 base::VirtualMemory reservation_; |
2876 int pages_used_; | |
2877 | 2893 |
2878 // Allocation pointer and limit for normal allocation and allocation during | 2894 // Allocation pointer and limit for normal allocation and allocation during |
2879 // mark-compact collection. | 2895 // mark-compact collection. |
2880 AllocationInfo allocation_info_; | 2896 AllocationInfo allocation_info_; |
2881 | 2897 |
2882 Address top_on_previous_step_; | 2898 Address top_on_previous_step_; |
2883 | 2899 |
2884 HistogramInfo* allocated_histogram_; | 2900 HistogramInfo* allocated_histogram_; |
2885 HistogramInfo* promoted_histogram_; | 2901 HistogramInfo* promoted_histogram_; |
2886 | 2902 |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3148 count = 0; | 3164 count = 0; |
3149 } | 3165 } |
3150 // Must be small, since an iteration is used for lookup. | 3166 // Must be small, since an iteration is used for lookup. |
3151 static const int kMaxComments = 64; | 3167 static const int kMaxComments = 64; |
3152 }; | 3168 }; |
3153 #endif | 3169 #endif |
3154 } // namespace internal | 3170 } // namespace internal |
3155 } // namespace v8 | 3171 } // namespace v8 |
3156 | 3172 |
3157 #endif // V8_HEAP_SPACES_H_ | 3173 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |