Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/heap/spaces.h

Issue 1632913003: [heap] Move to page lookups for SemiSpace, NewSpace, and Heap containment methods (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 // addresses is not big enough to contain a single page-aligned page, a 1934 // addresses is not big enough to contain a single page-aligned page, a
1935 // fresh chunk will be allocated. 1935 // fresh chunk will be allocated.
1936 bool SetUp(); 1936 bool SetUp();
1937 1937
1938 // Returns true if the space has been successfully set up and not 1938 // Returns true if the space has been successfully set up and not
1939 // subsequently torn down. 1939 // subsequently torn down.
1940 bool HasBeenSetUp(); 1940 bool HasBeenSetUp();
1941 1941
1942 // Checks whether an object/address is in this space. 1942 // Checks whether an object/address is in this space.
1943 inline bool Contains(Address a); 1943 inline bool Contains(Address a);
1944 inline bool Contains(HeapObject* o); 1944 inline bool Contains(Object* o);
1945 // Unlike Contains() methods it is safe to call this one even for addresses 1945 bool ContainsSlow(Address addr);
1946 // of unmapped memory.
1947 bool ContainsSafe(Address addr);
1948 1946
1949 // Given an address occupied by a live object, return that object if it is 1947 // Given an address occupied by a live object, return that object if it is
1950 // in this space, or a Smi if it is not. The implementation iterates over 1948 // in this space, or a Smi if it is not. The implementation iterates over
1951 // objects in the page containing the address, the cost is linear in the 1949 // objects in the page containing the address, the cost is linear in the
1952 // number of objects in the page. It may be slow. 1950 // number of objects in the page. It may be slow.
1953 Object* FindObject(Address addr); 1951 Object* FindObject(Address addr);
1954 1952
1955 // During boot the free_space_map is created, and afterwards we may need 1953 // During boot the free_space_map is created, and afterwards we may need
1956 // to write it into the free list nodes that were already created. 1954 // to write it into the free list nodes that were already created.
1957 void RepairFreeListsAfterDeserialization(); 1955 void RepairFreeListsAfterDeserialization();
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 public: 2312 public:
2315 static void Swap(SemiSpace* from, SemiSpace* to); 2313 static void Swap(SemiSpace* from, SemiSpace* to);
2316 2314
2317 SemiSpace(Heap* heap, SemiSpaceId semispace) 2315 SemiSpace(Heap* heap, SemiSpaceId semispace)
2318 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2316 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2319 current_capacity_(0), 2317 current_capacity_(0),
2320 maximum_capacity_(0), 2318 maximum_capacity_(0),
2321 minimum_capacity_(0), 2319 minimum_capacity_(0),
2322 start_(nullptr), 2320 start_(nullptr),
2323 age_mark_(nullptr), 2321 age_mark_(nullptr),
2324 address_mask_(0),
2325 object_mask_(0),
2326 object_expected_(0),
2327 committed_(false), 2322 committed_(false),
2328 id_(semispace), 2323 id_(semispace),
2329 anchor_(this), 2324 anchor_(this),
2330 current_page_(nullptr) {} 2325 current_page_(nullptr) {}
2331 2326
2327 inline bool Contains(HeapObject* o);
2328 inline bool Contains(Object* o);
2329 inline bool ContainsSlow(Address a);
2330
2332 // Creates a space in the young generation. The constructor does not 2331 // 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 2332 // 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); 2333 void SetUp(Address start, int initial_capacity, int maximum_capacity);
2336 2334
2337 // Tear down the space. Heap memory was not allocated by the space, so it 2335 // Tear down the space. Heap memory was not allocated by the space, so it
2338 // is not deallocated here. 2336 // is not deallocated here.
2339 void TearDown(); 2337 void TearDown();
2340 2338
2341 // True if the space has been set up but not torn down. 2339 // True if the space has been set up but not torn down.
2342 bool HasBeenSetUp() { return start_ != nullptr; } 2340 bool HasBeenSetUp() { return start_ != nullptr; }
2343 2341
2344 // Grow the semispace to the new capacity. The new capacity 2342 // Grow the semispace to the new capacity. The new capacity
(...skipping 28 matching lines...) Expand all
2373 return true; 2371 return true;
2374 } 2372 }
2375 2373
2376 // Resets the space to using the first page. 2374 // Resets the space to using the first page.
2377 void Reset(); 2375 void Reset();
2378 2376
2379 // Age mark accessors. 2377 // Age mark accessors.
2380 Address age_mark() { return age_mark_; } 2378 Address age_mark() { return age_mark_; }
2381 void set_age_mark(Address mark); 2379 void set_age_mark(Address mark);
2382 2380
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_; } 2381 bool is_committed() { return committed_; }
2397 bool Commit(); 2382 bool Commit();
2398 bool Uncommit(); 2383 bool Uncommit();
2399 2384
2400 NewSpacePage* first_page() { return anchor_.next_page(); } 2385 NewSpacePage* first_page() { return anchor_.next_page(); }
2401 NewSpacePage* current_page() { return current_page_; } 2386 NewSpacePage* current_page() { return current_page_; }
2402 2387
2403 // Returns the current total capacity of the semispace. 2388 // Returns the current total capacity of the semispace.
2404 int current_capacity() { return current_capacity_; } 2389 int current_capacity() { return current_capacity_; }
2405 2390
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2444 virtual void Verify(); 2429 virtual void Verify();
2445 #endif 2430 #endif
2446 2431
2447 private: 2432 private:
2448 NewSpacePage* anchor() { return &anchor_; } 2433 NewSpacePage* anchor() { return &anchor_; }
2449 2434
2450 void set_current_capacity(int new_capacity) { 2435 void set_current_capacity(int new_capacity) {
2451 current_capacity_ = new_capacity; 2436 current_capacity_ = new_capacity;
2452 } 2437 }
2453 2438
2454 // Flips the semispace between being from-space and to-space. Copies the flags 2439 // Copies the flags into the masked positions on all pages in the space.
2455 // into the masked positions on all pages in the space. 2440 void FixPagesFlags(intptr_t flags, intptr_t flag_mask);
2456 void FlipPages(intptr_t flags, intptr_t flag_mask);
2457 2441
2458 // The currently committed space capacity. 2442 // The currently committed space capacity.
2459 int current_capacity_; 2443 int current_capacity_;
2460 2444
2461 // The maximum capacity that can be used by this space. 2445 // The maximum capacity that can be used by this space.
2462 int maximum_capacity_; 2446 int maximum_capacity_;
2463 2447
2464 // The mimnimum capacity for the space. A space cannot shrink below this size. 2448 // The mimnimum capacity for the space. A space cannot shrink below this size.
2465 int minimum_capacity_; 2449 int minimum_capacity_;
2466 2450
2467 // The start address of the space. 2451 // The start address of the space.
2468 Address start_; 2452 Address start_;
2469 // Used to govern object promotion during mark-compact collection. 2453 // Used to govern object promotion during mark-compact collection.
2470 Address age_mark_; 2454 Address age_mark_;
2471 2455
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_; 2456 bool committed_;
2478 SemiSpaceId id_; 2457 SemiSpaceId id_;
2479 2458
2480 NewSpacePage anchor_; 2459 NewSpacePage anchor_;
2481 NewSpacePage* current_page_; 2460 NewSpacePage* current_page_;
2482 2461
2483 friend class SemiSpaceIterator; 2462 friend class SemiSpaceIterator;
2484 friend class NewSpacePageIterator; 2463 friend class NewSpacePageIterator;
2485 }; 2464 };
2486 2465
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 public: 2527 public:
2549 // Constructor. 2528 // Constructor.
2550 explicit NewSpace(Heap* heap) 2529 explicit NewSpace(Heap* heap)
2551 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2530 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2552 to_space_(heap, kToSpace), 2531 to_space_(heap, kToSpace),
2553 from_space_(heap, kFromSpace), 2532 from_space_(heap, kFromSpace),
2554 reservation_(), 2533 reservation_(),
2555 top_on_previous_step_(0), 2534 top_on_previous_step_(0),
2556 inline_allocation_observers_paused_(false) {} 2535 inline_allocation_observers_paused_(false) {}
2557 2536
2537 inline bool Contains(HeapObject* o);
2538 inline bool ContainsSlow(Address a);
2539 inline bool Contains(Object* o);
2540
2558 // Sets up the new space using the given chunk. 2541 // Sets up the new space using the given chunk.
2559 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); 2542 bool SetUp(int reserved_semispace_size_, int max_semi_space_size);
2560 2543
2561 // Tears down the space. Heap memory was not allocated by the space, so it 2544 // Tears down the space. Heap memory was not allocated by the space, so it
2562 // is not deallocated here. 2545 // is not deallocated here.
2563 void TearDown(); 2546 void TearDown();
2564 2547
2565 // True if the space has been set up but not torn down. 2548 // True if the space has been set up but not torn down.
2566 bool HasBeenSetUp() { 2549 bool HasBeenSetUp() {
2567 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp(); 2550 return to_space_.HasBeenSetUp() && from_space_.HasBeenSetUp();
2568 } 2551 }
2569 2552
2570 // Flip the pair of spaces. 2553 // Flip the pair of spaces.
2571 void Flip(); 2554 void Flip();
2572 2555
2573 // Grow the capacity of the semispaces. Assumes that they are not at 2556 // Grow the capacity of the semispaces. Assumes that they are not at
2574 // their maximum capacity. 2557 // their maximum capacity.
2575 void Grow(); 2558 void Grow();
2576 2559
2577 // Shrink the capacity of the semispaces. 2560 // Shrink the capacity of the semispaces.
2578 void Shrink(); 2561 void Shrink();
2579 2562
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. 2563 // Return the allocated bytes in the active semispace.
2593 intptr_t Size() override { 2564 intptr_t Size() override {
2594 return pages_used_ * NewSpacePage::kAreaSize + 2565 return pages_used_ * NewSpacePage::kAreaSize +
2595 static_cast<int>(top() - to_space_.page_low()); 2566 static_cast<int>(top() - to_space_.page_low());
2596 } 2567 }
2597 2568
2598 // The same, but returning an int. We have to have the one that returns 2569 // 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 2570 // 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: 2571 // new space, which can't get as big as the other spaces then this is useful:
2601 int SizeAsInt() { return static_cast<int>(Size()); } 2572 int SizeAsInt() { return static_cast<int>(Size()); }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2680 Address bottom() { return to_space_.space_start(); } 2651 Address bottom() { return to_space_.space_start(); }
2681 2652
2682 // Get the age mark of the inactive semispace. 2653 // Get the age mark of the inactive semispace.
2683 Address age_mark() { return from_space_.age_mark(); } 2654 Address age_mark() { return from_space_.age_mark(); }
2684 // Set the age mark in the active semispace. 2655 // Set the age mark in the active semispace.
2685 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } 2656 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
2686 2657
2687 // The start address of the space and a bit mask. Anding an address in the 2658 // 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. 2659 // new space with the mask will result in the start address.
2689 Address start() { return start_; } 2660 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 2661
2703 // The allocation top and limit address. 2662 // The allocation top and limit address.
2704 Address* allocation_top_address() { return allocation_info_.top_address(); } 2663 Address* allocation_top_address() { return allocation_info_.top_address(); }
2705 2664
2706 // The allocation limit address. 2665 // The allocation limit address.
2707 Address* allocation_limit_address() { 2666 Address* allocation_limit_address() {
2708 return allocation_info_.limit_address(); 2667 return allocation_info_.limit_address();
2709 } 2668 }
2710 2669
2711 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( 2670 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 // same page, so FromSpaceStart() might be above FromSpaceEnd(). 2703 // same page, so FromSpaceStart() might be above FromSpaceEnd().
2745 Address FromSpacePageLow() { return from_space_.page_low(); } 2704 Address FromSpacePageLow() { return from_space_.page_low(); }
2746 Address FromSpacePageHigh() { return from_space_.page_high(); } 2705 Address FromSpacePageHigh() { return from_space_.page_high(); }
2747 Address FromSpaceStart() { return from_space_.space_start(); } 2706 Address FromSpaceStart() { return from_space_.space_start(); }
2748 Address FromSpaceEnd() { return from_space_.space_end(); } 2707 Address FromSpaceEnd() { return from_space_.space_end(); }
2749 2708
2750 // Get the extent of the active semispace's pages' memory. 2709 // Get the extent of the active semispace's pages' memory.
2751 Address ToSpaceStart() { return to_space_.space_start(); } 2710 Address ToSpaceStart() { return to_space_.space_start(); }
2752 Address ToSpaceEnd() { return to_space_.space_end(); } 2711 Address ToSpaceEnd() { return to_space_.space_end(); }
2753 2712
2754 inline bool ToSpaceContains(Address address) { 2713 inline bool ToSpaceContainsSlow(Address a);
2755 return to_space_.Contains(address); 2714 inline bool FromSpaceContainsSlow(Address a);
2756 } 2715 inline bool ToSpaceContains(Object* o);
2757 inline bool FromSpaceContains(Address address) { 2716 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 2717
2767 // Try to switch the active semispace to a new, empty, page. 2718 // Try to switch the active semispace to a new, empty, page.
2768 // Returns false if this isn't possible or reasonable (i.e., there 2719 // 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 2720 // are no pages, or the current page is already empty), or true
2770 // if successful. 2721 // if successful.
2771 bool AddFreshPage(); 2722 bool AddFreshPage();
2772 bool AddFreshPageSynchronized(); 2723 bool AddFreshPageSynchronized();
2773 2724
2774 #ifdef VERIFY_HEAP 2725 #ifdef VERIFY_HEAP
2775 // Verify the active semispace. 2726 // Verify the active semispace.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2819 uintptr_t chunk_size_; 2770 uintptr_t chunk_size_;
2820 2771
2821 // The semispaces. 2772 // The semispaces.
2822 SemiSpace to_space_; 2773 SemiSpace to_space_;
2823 SemiSpace from_space_; 2774 SemiSpace from_space_;
2824 base::VirtualMemory reservation_; 2775 base::VirtualMemory reservation_;
2825 int pages_used_; 2776 int pages_used_;
2826 2777
2827 // Start address and bit mask for containment testing. 2778 // Start address and bit mask for containment testing.
2828 Address start_; 2779 Address start_;
2829 uintptr_t address_mask_;
2830 uintptr_t object_mask_;
2831 uintptr_t object_expected_;
2832 2780
2833 // Allocation pointer and limit for normal allocation and allocation during 2781 // Allocation pointer and limit for normal allocation and allocation during
2834 // mark-compact collection. 2782 // mark-compact collection.
2835 AllocationInfo allocation_info_; 2783 AllocationInfo allocation_info_;
2836 2784
2837 // When inline allocation stepping is active, either because of incremental 2785 // When inline allocation stepping is active, either because of incremental
2838 // marking or because of idle scavenge, we 'interrupt' inline allocation every 2786 // 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 2787 // 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 2788 // than the actual limit and and increasing it in steps to guarantee that the
2841 // observers are notified periodically. 2789 // observers are notified periodically.
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 LargePage* FindPage(Address a); 2982 LargePage* FindPage(Address a);
3035 2983
3036 // Clears the marking state of live objects. 2984 // Clears the marking state of live objects.
3037 void ClearMarkingStateOfLiveObjects(); 2985 void ClearMarkingStateOfLiveObjects();
3038 2986
3039 // Frees unmarked objects. 2987 // Frees unmarked objects.
3040 void FreeUnmarkedObjects(); 2988 void FreeUnmarkedObjects();
3041 2989
3042 // Checks whether a heap object is in this space; O(1). 2990 // Checks whether a heap object is in this space; O(1).
3043 bool Contains(HeapObject* obj); 2991 bool Contains(HeapObject* obj);
3044 bool Contains(Address address); 2992 // Checks whether an address is in the object area in this space. Iterates
2993 // all objects in the space. May be slow.
2994 bool ContainsSlow(Address addr) { return FindObject(addr)->IsHeapObject(); }
3045 2995
3046 // Checks whether the space is empty. 2996 // Checks whether the space is empty.
3047 bool IsEmpty() { return first_page_ == NULL; } 2997 bool IsEmpty() { return first_page_ == NULL; }
3048 2998
3049 LargePage* first_page() { return first_page_; } 2999 LargePage* first_page() { return first_page_; }
3050 3000
3051 #ifdef VERIFY_HEAP 3001 #ifdef VERIFY_HEAP
3052 virtual void Verify(); 3002 virtual void Verify();
3053 #endif 3003 #endif
3054 3004
3055 #ifdef DEBUG 3005 #ifdef DEBUG
3056 void Print() override; 3006 void Print() override;
3057 void ReportStatistics(); 3007 void ReportStatistics();
3058 void CollectCodeStatistics(); 3008 void CollectCodeStatistics();
3059 #endif 3009 #endif
3060 // Checks whether an address is in the object area in this space. It
3061 // iterates all objects in the space. May be slow.
3062 bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); }
3063 3010
3064 private: 3011 private:
3065 // The head of the linked list of large object chunks. 3012 // The head of the linked list of large object chunks.
3066 LargePage* first_page_; 3013 LargePage* first_page_;
3067 intptr_t size_; // allocated bytes 3014 intptr_t size_; // allocated bytes
3068 int page_count_; // number of chunks 3015 int page_count_; // number of chunks
3069 intptr_t objects_size_; // size of objects 3016 intptr_t objects_size_; // size of objects
3070 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them 3017 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them
3071 HashMap chunk_map_; 3018 HashMap chunk_map_;
3072 3019
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 count = 0; 3064 count = 0;
3118 } 3065 }
3119 // Must be small, since an iteration is used for lookup. 3066 // Must be small, since an iteration is used for lookup.
3120 static const int kMaxComments = 64; 3067 static const int kMaxComments = 64;
3121 }; 3068 };
3122 #endif 3069 #endif
3123 } // namespace internal 3070 } // namespace internal
3124 } // namespace v8 3071 } // namespace v8
3125 3072
3126 #endif // V8_HEAP_SPACES_H_ 3073 #endif // V8_HEAP_SPACES_H_
OLDNEW
« src/frames.cc ('K') | « src/heap/slots-buffer.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698