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 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2314 public: | 2314 public: |
2315 static void Swap(SemiSpace* from, SemiSpace* to); | 2315 static void Swap(SemiSpace* from, SemiSpace* to); |
2316 | 2316 |
2317 SemiSpace(Heap* heap, SemiSpaceId semispace) | 2317 SemiSpace(Heap* heap, SemiSpaceId semispace) |
2318 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2318 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2319 current_capacity_(0), | 2319 current_capacity_(0), |
2320 maximum_capacity_(0), | 2320 maximum_capacity_(0), |
2321 minimum_capacity_(0), | 2321 minimum_capacity_(0), |
2322 start_(nullptr), | 2322 start_(nullptr), |
2323 age_mark_(nullptr), | 2323 age_mark_(nullptr), |
2324 address_mask_(0), | |
2325 object_mask_(0), | |
2326 object_expected_(0), | |
2327 committed_(false), | 2324 committed_(false), |
2328 id_(semispace), | 2325 id_(semispace), |
2329 anchor_(this), | 2326 anchor_(this), |
2330 current_page_(nullptr) {} | 2327 current_page_(nullptr) {} |
2331 | 2328 |
| 2329 inline bool Contains(HeapObject* o); |
| 2330 inline bool Contains(Object* o); |
| 2331 inline bool ContainsSlow(Address a); |
| 2332 |
2332 // Creates a space in the young generation. The constructor does not | 2333 // Creates a space in the young generation. The constructor does not |
2333 // allocate memory from the OS. A SemiSpace is given a contiguous chunk of | 2334 // allocate memory from the OS. |
2334 // memory of size {initial_capacity} when set up. | |
2335 void SetUp(Address start, int initial_capacity, int maximum_capacity); | 2335 void SetUp(Address start, int initial_capacity, int maximum_capacity); |
2336 | 2336 |
2337 // Tear down the space. Heap memory was not allocated by the space, so it | 2337 // Tear down the space. Heap memory was not allocated by the space, so it |
2338 // is not deallocated here. | 2338 // is not deallocated here. |
2339 void TearDown(); | 2339 void TearDown(); |
2340 | 2340 |
2341 // True if the space has been set up but not torn down. | 2341 // True if the space has been set up but not torn down. |
2342 bool HasBeenSetUp() { return start_ != nullptr; } | 2342 bool HasBeenSetUp() { return start_ != nullptr; } |
2343 | 2343 |
2344 // Grow the semispace to the new capacity. The new capacity | 2344 // Grow the semispace to the new capacity. The new capacity |
(...skipping 28 matching lines...) Expand all Loading... |
2373 return true; | 2373 return true; |
2374 } | 2374 } |
2375 | 2375 |
2376 // Resets the space to using the first page. | 2376 // Resets the space to using the first page. |
2377 void Reset(); | 2377 void Reset(); |
2378 | 2378 |
2379 // Age mark accessors. | 2379 // Age mark accessors. |
2380 Address age_mark() { return age_mark_; } | 2380 Address age_mark() { return age_mark_; } |
2381 void set_age_mark(Address mark); | 2381 void set_age_mark(Address mark); |
2382 | 2382 |
2383 // True if the address is in the address range of this semispace (not | |
2384 // necessarily below the allocation pointer). | |
2385 bool Contains(Address a) { | |
2386 return (reinterpret_cast<uintptr_t>(a) & address_mask_) == | |
2387 reinterpret_cast<uintptr_t>(start_); | |
2388 } | |
2389 | |
2390 // True if the object is a heap object in the address range of this | |
2391 // semispace (not necessarily below the allocation pointer). | |
2392 bool Contains(Object* o) { | |
2393 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | |
2394 } | |
2395 | |
2396 bool is_committed() { return committed_; } | 2383 bool is_committed() { return committed_; } |
2397 bool Commit(); | 2384 bool Commit(); |
2398 bool Uncommit(); | 2385 bool Uncommit(); |
2399 | 2386 |
2400 NewSpacePage* first_page() { return anchor_.next_page(); } | 2387 NewSpacePage* first_page() { return anchor_.next_page(); } |
2401 NewSpacePage* current_page() { return current_page_; } | 2388 NewSpacePage* current_page() { return current_page_; } |
2402 | 2389 |
2403 // Returns the current total capacity of the semispace. | 2390 // Returns the current total capacity of the semispace. |
2404 int current_capacity() { return current_capacity_; } | 2391 int current_capacity() { return current_capacity_; } |
2405 | 2392 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2444 virtual void Verify(); | 2431 virtual void Verify(); |
2445 #endif | 2432 #endif |
2446 | 2433 |
2447 private: | 2434 private: |
2448 NewSpacePage* anchor() { return &anchor_; } | 2435 NewSpacePage* anchor() { return &anchor_; } |
2449 | 2436 |
2450 void set_current_capacity(int new_capacity) { | 2437 void set_current_capacity(int new_capacity) { |
2451 current_capacity_ = new_capacity; | 2438 current_capacity_ = new_capacity; |
2452 } | 2439 } |
2453 | 2440 |
2454 // Flips the semispace between being from-space and to-space. Copies the flags | 2441 // Copies the flags into the masked positions on all pages in the space. |
2455 // into the masked positions on all pages in the space. | 2442 void FixPages(intptr_t flags, intptr_t flag_mask); |
2456 void FlipPages(intptr_t flags, intptr_t flag_mask); | |
2457 | 2443 |
2458 // The currently committed space capacity. | 2444 // The currently committed space capacity. |
2459 int current_capacity_; | 2445 int current_capacity_; |
2460 | 2446 |
2461 // The maximum capacity that can be used by this space. | 2447 // The maximum capacity that can be used by this space. |
2462 int maximum_capacity_; | 2448 int maximum_capacity_; |
2463 | 2449 |
2464 // The mimnimum capacity for the space. A space cannot shrink below this size. | 2450 // The mimnimum capacity for the space. A space cannot shrink below this size. |
2465 int minimum_capacity_; | 2451 int minimum_capacity_; |
2466 | 2452 |
2467 // The start address of the space. | 2453 // The start address of the space. |
2468 Address start_; | 2454 Address start_; |
2469 // Used to govern object promotion during mark-compact collection. | 2455 // Used to govern object promotion during mark-compact collection. |
2470 Address age_mark_; | 2456 Address age_mark_; |
2471 | 2457 |
2472 // Masks and comparison values to test for containment in this semispace. | |
2473 uintptr_t address_mask_; | |
2474 uintptr_t object_mask_; | |
2475 uintptr_t object_expected_; | |
2476 | |
2477 bool committed_; | 2458 bool committed_; |
2478 SemiSpaceId id_; | 2459 SemiSpaceId id_; |
2479 | 2460 |
2480 NewSpacePage anchor_; | 2461 NewSpacePage anchor_; |
2481 NewSpacePage* current_page_; | 2462 NewSpacePage* current_page_; |
2482 | 2463 |
2483 friend class SemiSpaceIterator; | 2464 friend class SemiSpaceIterator; |
2484 friend class NewSpacePageIterator; | 2465 friend class NewSpacePageIterator; |
2485 }; | 2466 }; |
2486 | 2467 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2548 public: | 2529 public: |
2549 // Constructor. | 2530 // Constructor. |
2550 explicit NewSpace(Heap* heap) | 2531 explicit NewSpace(Heap* heap) |
2551 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2532 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2552 to_space_(heap, kToSpace), | 2533 to_space_(heap, kToSpace), |
2553 from_space_(heap, kFromSpace), | 2534 from_space_(heap, kFromSpace), |
2554 reservation_(), | 2535 reservation_(), |
2555 top_on_previous_step_(0), | 2536 top_on_previous_step_(0), |
2556 inline_allocation_observers_paused_(false) {} | 2537 inline_allocation_observers_paused_(false) {} |
2557 | 2538 |
| 2539 inline bool Contains(HeapObject* o); |
| 2540 inline bool ContainsSlow(Address a); |
| 2541 inline bool Contains(Object* o); |
| 2542 |
2558 // Sets up the new space using the given chunk. | 2543 // Sets up the new space using the given chunk. |
2559 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); | 2544 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); |
2560 | 2545 |
2561 // Tears down the space. Heap memory was not allocated by the space, so it | 2546 // Tears down the space. Heap memory was not allocated by the space, so it |
2562 // is not deallocated here. | 2547 // is not deallocated here. |
2563 void TearDown(); | 2548 void TearDown(); |
2564 | 2549 |
2565 // True if the space has been set up but not torn down. | 2550 // True if the space has been set up but not torn down. |
2566 bool HasBeenSetUp() { | 2551 bool HasBeenSetUp() { |
2567 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); | 2552 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); |
2568 } | 2553 } |
2569 | 2554 |
2570 // Flip the pair of spaces. | 2555 // Flip the pair of spaces. |
2571 void Flip(); | 2556 void Flip(); |
2572 | 2557 |
2573 // Grow the capacity of the semispaces. Assumes that they are not at | 2558 // Grow the capacity of the semispaces. Assumes that they are not at |
2574 // their maximum capacity. | 2559 // their maximum capacity. |
2575 void Grow(); | 2560 void Grow(); |
2576 | 2561 |
2577 // Shrink the capacity of the semispaces. | 2562 // Shrink the capacity of the semispaces. |
2578 void Shrink(); | 2563 void Shrink(); |
2579 | 2564 |
2580 // True if the address or object lies in the address range of either | |
2581 // semispace (not necessarily below the allocation pointer). | |
2582 bool Contains(Address a) { | |
2583 return (reinterpret_cast<uintptr_t>(a) & address_mask_) == | |
2584 reinterpret_cast<uintptr_t>(start_); | |
2585 } | |
2586 | |
2587 bool Contains(Object* o) { | |
2588 Address a = reinterpret_cast<Address>(o); | |
2589 return (reinterpret_cast<uintptr_t>(a) & object_mask_) == object_expected_; | |
2590 } | |
2591 | |
2592 // Return the allocated bytes in the active semispace. | 2565 // Return the allocated bytes in the active semispace. |
2593 intptr_t Size() override { | 2566 intptr_t Size() override { |
2594 return pages_used_ * NewSpacePage::kAreaSize + | 2567 return pages_used_ * NewSpacePage::kAreaSize + |
2595 static_cast<int>(top() - to_space_.page_low()); | 2568 static_cast<int>(top() - to_space_.page_low()); |
2596 } | 2569 } |
2597 | 2570 |
2598 // The same, but returning an int. We have to have the one that returns | 2571 // The same, but returning an int. We have to have the one that returns |
2599 // intptr_t because it is inherited, but if we know we are dealing with the | 2572 // intptr_t because it is inherited, but if we know we are dealing with the |
2600 // new space, which can't get as big as the other spaces then this is useful: | 2573 // new space, which can't get as big as the other spaces then this is useful: |
2601 int SizeAsInt() { return static_cast<int>(Size()); } | 2574 int SizeAsInt() { return static_cast<int>(Size()); } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2680 Address bottom() { return to_space_.space_start(); } | 2653 Address bottom() { return to_space_.space_start(); } |
2681 | 2654 |
2682 // Get the age mark of the inactive semispace. | 2655 // Get the age mark of the inactive semispace. |
2683 Address age_mark() { return from_space_.age_mark(); } | 2656 Address age_mark() { return from_space_.age_mark(); } |
2684 // Set the age mark in the active semispace. | 2657 // Set the age mark in the active semispace. |
2685 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } | 2658 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } |
2686 | 2659 |
2687 // The start address of the space and a bit mask. Anding an address in the | 2660 // The start address of the space and a bit mask. Anding an address in the |
2688 // new space with the mask will result in the start address. | 2661 // new space with the mask will result in the start address. |
2689 Address start() { return start_; } | 2662 Address start() { return start_; } |
2690 uintptr_t mask() { return address_mask_; } | |
2691 | |
2692 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { | |
2693 DCHECK(Contains(addr)); | |
2694 DCHECK(IsAligned(OffsetFrom(addr), kPointerSize) || | |
2695 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); | |
2696 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; | |
2697 } | |
2698 | |
2699 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { | |
2700 return reinterpret_cast<Address>(index << kPointerSizeLog2); | |
2701 } | |
2702 | 2663 |
2703 // The allocation top and limit address. | 2664 // The allocation top and limit address. |
2704 Address* allocation_top_address() { return allocation_info_.top_address(); } | 2665 Address* allocation_top_address() { return allocation_info_.top_address(); } |
2705 | 2666 |
2706 // The allocation limit address. | 2667 // The allocation limit address. |
2707 Address* allocation_limit_address() { | 2668 Address* allocation_limit_address() { |
2708 return allocation_info_.limit_address(); | 2669 return allocation_info_.limit_address(); |
2709 } | 2670 } |
2710 | 2671 |
2711 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( | 2672 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2744 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2705 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
2745 Address FromSpacePageLow() { return from_space_.page_low(); } | 2706 Address FromSpacePageLow() { return from_space_.page_low(); } |
2746 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2707 Address FromSpacePageHigh() { return from_space_.page_high(); } |
2747 Address FromSpaceStart() { return from_space_.space_start(); } | 2708 Address FromSpaceStart() { return from_space_.space_start(); } |
2748 Address FromSpaceEnd() { return from_space_.space_end(); } | 2709 Address FromSpaceEnd() { return from_space_.space_end(); } |
2749 | 2710 |
2750 // Get the extent of the active semispace's pages' memory. | 2711 // Get the extent of the active semispace's pages' memory. |
2751 Address ToSpaceStart() { return to_space_.space_start(); } | 2712 Address ToSpaceStart() { return to_space_.space_start(); } |
2752 Address ToSpaceEnd() { return to_space_.space_end(); } | 2713 Address ToSpaceEnd() { return to_space_.space_end(); } |
2753 | 2714 |
2754 inline bool ToSpaceContains(Address address) { | 2715 inline bool ToSpaceContainsSlow(Address a); |
2755 return to_space_.Contains(address); | 2716 inline bool FromSpaceContainsSlow(Address a); |
2756 } | 2717 inline bool ToSpaceContains(Object* o); |
2757 inline bool FromSpaceContains(Address address) { | 2718 inline bool FromSpaceContains(Object* o); |
2758 return from_space_.Contains(address); | |
2759 } | |
2760 | |
2761 // True if the object is a heap object in the address range of the | |
2762 // respective semispace (not necessarily below the allocation pointer of the | |
2763 // semispace). | |
2764 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } | |
2765 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } | |
2766 | 2719 |
2767 // Try to switch the active semispace to a new, empty, page. | 2720 // Try to switch the active semispace to a new, empty, page. |
2768 // Returns false if this isn't possible or reasonable (i.e., there | 2721 // Returns false if this isn't possible or reasonable (i.e., there |
2769 // are no pages, or the current page is already empty), or true | 2722 // are no pages, or the current page is already empty), or true |
2770 // if successful. | 2723 // if successful. |
2771 bool AddFreshPage(); | 2724 bool AddFreshPage(); |
2772 bool AddFreshPageSynchronized(); | 2725 bool AddFreshPageSynchronized(); |
2773 | 2726 |
2774 #ifdef VERIFY_HEAP | 2727 #ifdef VERIFY_HEAP |
2775 // Verify the active semispace. | 2728 // Verify the active semispace. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 uintptr_t chunk_size_; | 2772 uintptr_t chunk_size_; |
2820 | 2773 |
2821 // The semispaces. | 2774 // The semispaces. |
2822 SemiSpace to_space_; | 2775 SemiSpace to_space_; |
2823 SemiSpace from_space_; | 2776 SemiSpace from_space_; |
2824 base::VirtualMemory reservation_; | 2777 base::VirtualMemory reservation_; |
2825 int pages_used_; | 2778 int pages_used_; |
2826 | 2779 |
2827 // Start address and bit mask for containment testing. | 2780 // Start address and bit mask for containment testing. |
2828 Address start_; | 2781 Address start_; |
2829 uintptr_t address_mask_; | |
2830 uintptr_t object_mask_; | |
2831 uintptr_t object_expected_; | |
2832 | 2782 |
2833 // Allocation pointer and limit for normal allocation and allocation during | 2783 // Allocation pointer and limit for normal allocation and allocation during |
2834 // mark-compact collection. | 2784 // mark-compact collection. |
2835 AllocationInfo allocation_info_; | 2785 AllocationInfo allocation_info_; |
2836 | 2786 |
2837 // When inline allocation stepping is active, either because of incremental | 2787 // When inline allocation stepping is active, either because of incremental |
2838 // marking or because of idle scavenge, we 'interrupt' inline allocation every | 2788 // marking or because of idle scavenge, we 'interrupt' inline allocation every |
2839 // once in a while. This is done by setting allocation_info_.limit to be lower | 2789 // once in a while. This is done by setting allocation_info_.limit to be lower |
2840 // than the actual limit and and increasing it in steps to guarantee that the | 2790 // than the actual limit and and increasing it in steps to guarantee that the |
2841 // observers are notified periodically. | 2791 // observers are notified periodically. |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3117 count = 0; | 3067 count = 0; |
3118 } | 3068 } |
3119 // Must be small, since an iteration is used for lookup. | 3069 // Must be small, since an iteration is used for lookup. |
3120 static const int kMaxComments = 64; | 3070 static const int kMaxComments = 64; |
3121 }; | 3071 }; |
3122 #endif | 3072 #endif |
3123 } // namespace internal | 3073 } // namespace internal |
3124 } // namespace v8 | 3074 } // namespace v8 |
3125 | 3075 |
3126 #endif // V8_HEAP_SPACES_H_ | 3076 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |