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

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