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

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

Issue 2209583002: [heap] Remove border page (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Allow empty intermediate generation Created 4 years, 2 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/mark-compact.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 <list> 8 #include <list>
9 #include <memory> 9 #include <memory>
10 #include <unordered_set> 10 #include <unordered_set>
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 // It is divided into the header and the body. Chunk start is always 227 // It is divided into the header and the body. Chunk start is always
228 // 1MB aligned. Start of the body is aligned so it can accommodate 228 // 1MB aligned. Start of the body is aligned so it can accommodate
229 // any heap object. 229 // any heap object.
230 class MemoryChunk { 230 class MemoryChunk {
231 public: 231 public:
232 enum Flag { 232 enum Flag {
233 NO_FLAGS = 0u, 233 NO_FLAGS = 0u,
234 IS_EXECUTABLE = 1u << 0, 234 IS_EXECUTABLE = 1u << 0,
235 POINTERS_TO_HERE_ARE_INTERESTING = 1u << 1, 235 POINTERS_TO_HERE_ARE_INTERESTING = 1u << 1,
236 POINTERS_FROM_HERE_ARE_INTERESTING = 1u << 2, 236 POINTERS_FROM_HERE_ARE_INTERESTING = 1u << 2,
237
237 // A page in new space has one of the next to flags set. 238 // A page in new space has one of the next to flags set.
238 IN_FROM_SPACE = 1u << 3, 239 IN_FROM_SPACE = 1u << 3,
239 IN_TO_SPACE = 1u << 4, 240 IN_TO_SPACE = 1u << 4,
240 NEW_SPACE_BELOW_AGE_MARK = 1u << 5, 241 // |IN_INTERMEDIATE_GENERATION|: Flag indicates whether this page contains
242 // objects that have already been copied once.
243 IN_INTERMEDIATE_GENERATION = 1u << 5,
244
241 EVACUATION_CANDIDATE = 1u << 6, 245 EVACUATION_CANDIDATE = 1u << 6,
242 NEVER_EVACUATE = 1u << 7, 246 NEVER_EVACUATE = 1u << 7,
243 247
244 // Large objects can have a progress bar in their page header. These object 248 // Large objects can have a progress bar in their page header. These object
245 // are scanned in increments and will be kept black while being scanned. 249 // are scanned in increments and will be kept black while being scanned.
246 // Even if the mutator writes to them they will be kept black and a white 250 // Even if the mutator writes to them they will be kept black and a white
247 // to grey transition is performed in the value. 251 // to grey transition is performed in the value.
248 HAS_PROGRESS_BAR = 1u << 8, 252 HAS_PROGRESS_BAR = 1u << 8,
249 253
250 // |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted 254 // |PAGE_NEW_OLD_PROMOTION|: A page tagged with this flag has been promoted
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 Executability executable() { 556 Executability executable() {
553 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 557 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
554 } 558 }
555 559
556 bool InNewSpace() { return (flags_ & kIsInNewSpaceMask) != 0; } 560 bool InNewSpace() { return (flags_ & kIsInNewSpaceMask) != 0; }
557 561
558 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); } 562 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); }
559 563
560 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); } 564 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); }
561 565
566 bool InIntermediateGeneration() {
567 return IsFlagSet(IN_INTERMEDIATE_GENERATION);
568 }
569
562 MemoryChunk* next_chunk() { return next_chunk_.Value(); } 570 MemoryChunk* next_chunk() { return next_chunk_.Value(); }
563 571
564 MemoryChunk* prev_chunk() { return prev_chunk_.Value(); } 572 MemoryChunk* prev_chunk() { return prev_chunk_.Value(); }
565 573
566 void set_next_chunk(MemoryChunk* next) { next_chunk_.SetValue(next); } 574 void set_next_chunk(MemoryChunk* next) { next_chunk_.SetValue(next); }
567 575
568 void set_prev_chunk(MemoryChunk* prev) { prev_chunk_.SetValue(prev); } 576 void set_prev_chunk(MemoryChunk* prev) { prev_chunk_.SetValue(prev); }
569 577
570 Space* owner() const { 578 Space* owner() const {
571 if ((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) == 579 if ((reinterpret_cast<intptr_t>(owner_) & kPageHeaderTagMask) ==
(...skipping 1645 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 public: 2225 public:
2218 typedef PageIterator iterator; 2226 typedef PageIterator iterator;
2219 2227
2220 static void Swap(SemiSpace* from, SemiSpace* to); 2228 static void Swap(SemiSpace* from, SemiSpace* to);
2221 2229
2222 SemiSpace(Heap* heap, SemiSpaceId semispace) 2230 SemiSpace(Heap* heap, SemiSpaceId semispace)
2223 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2231 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2224 current_capacity_(0), 2232 current_capacity_(0),
2225 maximum_capacity_(0), 2233 maximum_capacity_(0),
2226 minimum_capacity_(0), 2234 minimum_capacity_(0),
2227 age_mark_(nullptr),
2228 committed_(false), 2235 committed_(false),
2229 id_(semispace), 2236 id_(semispace),
2230 anchor_(this), 2237 anchor_(this),
2231 current_page_(nullptr), 2238 current_page_(nullptr),
2232 pages_used_(0) {} 2239 pages_used_(0) {}
2233 2240
2234 inline bool Contains(HeapObject* o); 2241 inline bool Contains(HeapObject* o);
2235 inline bool Contains(Object* o); 2242 inline bool Contains(Object* o);
2236 inline bool ContainsSlow(Address a); 2243 inline bool ContainsSlow(Address a);
2237 2244
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 pages_used_++; 2293 pages_used_++;
2287 return true; 2294 return true;
2288 } 2295 }
2289 2296
2290 // Resets the space to using the first page. 2297 // Resets the space to using the first page.
2291 void Reset(); 2298 void Reset();
2292 2299
2293 void RemovePage(Page* page); 2300 void RemovePage(Page* page);
2294 void PrependPage(Page* page); 2301 void PrependPage(Page* page);
2295 2302
2296 // Age mark accessors.
2297 Address age_mark() { return age_mark_; }
2298 void set_age_mark(Address mark);
2299
2300 // Returns the current capacity of the semispace. 2303 // Returns the current capacity of the semispace.
2301 int current_capacity() { return current_capacity_; } 2304 int current_capacity() { return current_capacity_; }
2302 2305
2303 // Returns the maximum capacity of the semispace. 2306 // Returns the maximum capacity of the semispace.
2304 int maximum_capacity() { return maximum_capacity_; } 2307 int maximum_capacity() { return maximum_capacity_; }
2305 2308
2306 // Returns the initial capacity of the semispace. 2309 // Returns the initial capacity of the semispace.
2307 int minimum_capacity() { return minimum_capacity_; } 2310 int minimum_capacity() { return minimum_capacity_; }
2308 2311
2309 SemiSpaceId id() { return id_; } 2312 SemiSpaceId id() { return id_; }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 // The currently committed space capacity. 2359 // The currently committed space capacity.
2357 int current_capacity_; 2360 int current_capacity_;
2358 2361
2359 // The maximum capacity that can be used by this space. A space cannot grow 2362 // The maximum capacity that can be used by this space. A space cannot grow
2360 // beyond that size. 2363 // beyond that size.
2361 int maximum_capacity_; 2364 int maximum_capacity_;
2362 2365
2363 // The minimum capacity for the space. A space cannot shrink below this size. 2366 // The minimum capacity for the space. A space cannot shrink below this size.
2364 int minimum_capacity_; 2367 int minimum_capacity_;
2365 2368
2366 // Used to govern object promotion during mark-compact collection.
2367 Address age_mark_;
2368
2369 bool committed_; 2369 bool committed_;
2370 SemiSpaceId id_; 2370 SemiSpaceId id_;
2371 2371
2372 Page anchor_; 2372 Page anchor_;
2373 Page* current_page_; 2373 Page* current_page_;
2374 int pages_used_; 2374 int pages_used_;
2375 2375
2376 friend class NewSpace; 2376 friend class NewSpace;
2377 friend class SemiSpaceIterator; 2377 friend class SemiSpaceIterator;
2378 }; 2378 };
(...skipping 30 matching lines...) Expand all
2409 public: 2409 public:
2410 typedef PageIterator iterator; 2410 typedef PageIterator iterator;
2411 2411
2412 explicit NewSpace(Heap* heap) 2412 explicit NewSpace(Heap* heap)
2413 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2413 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2414 to_space_(heap, kToSpace), 2414 to_space_(heap, kToSpace),
2415 from_space_(heap, kFromSpace), 2415 from_space_(heap, kFromSpace),
2416 reservation_(), 2416 reservation_(),
2417 top_on_previous_step_(0), 2417 top_on_previous_step_(0),
2418 allocated_histogram_(nullptr), 2418 allocated_histogram_(nullptr),
2419 promoted_histogram_(nullptr) {} 2419 promoted_histogram_(nullptr),
2420 fragmentation_in_intermediate_generation_(0) {}
2420 2421
2421 inline bool Contains(HeapObject* o); 2422 inline bool Contains(HeapObject* o);
2422 inline bool ContainsSlow(Address a); 2423 inline bool ContainsSlow(Address a);
2423 inline bool Contains(Object* o); 2424 inline bool Contains(Object* o);
2424 2425
2425 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); 2426 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity);
2426 2427
2427 // Tears down the space. Heap memory was not allocated by the space, so it 2428 // Tears down the space. Heap memory was not allocated by the space, so it
2428 // is not deallocated here. 2429 // is not deallocated here.
2429 void TearDown(); 2430 void TearDown();
(...skipping 12 matching lines...) Expand all
2442 2443
2443 // Shrink the capacity of the semispaces. 2444 // Shrink the capacity of the semispaces.
2444 void Shrink(); 2445 void Shrink();
2445 2446
2446 // Return the allocated bytes in the active semispace. 2447 // Return the allocated bytes in the active semispace.
2447 intptr_t Size() override { 2448 intptr_t Size() override {
2448 return to_space_.pages_used() * Page::kAllocatableMemory + 2449 return to_space_.pages_used() * Page::kAllocatableMemory +
2449 static_cast<int>(top() - to_space_.page_low()); 2450 static_cast<int>(top() - to_space_.page_low());
2450 } 2451 }
2451 2452
2453 intptr_t SizeOfObjects() override {
2454 return Size() -
2455 static_cast<intptr_t>(fragmentation_in_intermediate_generation_);
2456 }
2457
2452 // The same, but returning an int. We have to have the one that returns 2458 // The same, but returning an int. We have to have the one that returns
2453 // intptr_t because it is inherited, but if we know we are dealing with the 2459 // intptr_t because it is inherited, but if we know we are dealing with the
2454 // new space, which can't get as big as the other spaces then this is useful: 2460 // new space, which can't get as big as the other spaces then this is useful:
2455 int SizeAsInt() { return static_cast<int>(Size()); } 2461 int SizeAsInt() { return static_cast<int>(Size()); }
2456 2462
2457 // Return the allocatable capacity of a semispace. 2463 // Return the allocatable capacity of a semispace.
2458 intptr_t Capacity() { 2464 intptr_t Capacity() {
2459 SLOW_DCHECK(to_space_.current_capacity() == from_space_.current_capacity()); 2465 SLOW_DCHECK(to_space_.current_capacity() == from_space_.current_capacity());
2460 return (to_space_.current_capacity() / Page::kPageSize) * 2466 return (to_space_.current_capacity() / Page::kPageSize) *
2461 Page::kAllocatableMemory; 2467 Page::kAllocatableMemory;
(...skipping 16 matching lines...) Expand all
2478 return from_space_.MaximumCommittedMemory() + 2484 return from_space_.MaximumCommittedMemory() +
2479 to_space_.MaximumCommittedMemory(); 2485 to_space_.MaximumCommittedMemory();
2480 } 2486 }
2481 2487
2482 // Approximate amount of physical memory committed for this space. 2488 // Approximate amount of physical memory committed for this space.
2483 size_t CommittedPhysicalMemory() override; 2489 size_t CommittedPhysicalMemory() override;
2484 2490
2485 // Return the available bytes without growing. 2491 // Return the available bytes without growing.
2486 intptr_t Available() override { return Capacity() - Size(); } 2492 intptr_t Available() override { return Capacity() - Size(); }
2487 2493
2488 size_t AllocatedSinceLastGC() { 2494 inline size_t AllocatedSinceLastGC();
2489 bool seen_age_mark = false;
2490 Address age_mark = to_space_.age_mark();
2491 Page* current_page = to_space_.first_page();
2492 Page* age_mark_page = Page::FromAddress(age_mark);
2493 Page* last_page = Page::FromAddress(top() - kPointerSize);
2494 if (age_mark_page == last_page) {
2495 if (top() - age_mark >= 0) {
2496 return top() - age_mark;
2497 }
2498 // Top was reset at some point, invalidating this metric.
2499 return 0;
2500 }
2501 while (current_page != last_page) {
2502 if (current_page == age_mark_page) {
2503 seen_age_mark = true;
2504 break;
2505 }
2506 current_page = current_page->next_page();
2507 }
2508 if (!seen_age_mark) {
2509 // Top was reset at some point, invalidating this metric.
2510 return 0;
2511 }
2512 intptr_t allocated = age_mark_page->area_end() - age_mark;
2513 DCHECK_EQ(current_page, age_mark_page);
2514 current_page = age_mark_page->next_page();
2515 while (current_page != last_page) {
2516 allocated += Page::kAllocatableMemory;
2517 current_page = current_page->next_page();
2518 }
2519 allocated += top() - current_page->area_start();
2520 DCHECK_LE(0, allocated);
2521 DCHECK_LE(allocated, Size());
2522 return static_cast<size_t>(allocated);
2523 }
2524 2495
2525 void MovePageFromSpaceToSpace(Page* page) { 2496 void MovePageFromSpaceToSpace(Page* page) {
2526 DCHECK(page->InFromSpace()); 2497 DCHECK(page->InFromSpace());
2527 from_space_.RemovePage(page); 2498 from_space_.RemovePage(page);
2528 to_space_.PrependPage(page); 2499 to_space_.PrependPage(page);
2529 } 2500 }
2530 2501
2531 bool Rebalance(); 2502 bool Rebalance();
2532 2503
2533 // Return the maximum capacity of a semispace. 2504 // Return the maximum capacity of a semispace.
(...skipping 18 matching lines...) Expand all
2552 2523
2553 // Return the address of the allocation pointer limit in the active semispace. 2524 // Return the address of the allocation pointer limit in the active semispace.
2554 Address limit() { 2525 Address limit() {
2555 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); 2526 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit()));
2556 return allocation_info_.limit(); 2527 return allocation_info_.limit();
2557 } 2528 }
2558 2529
2559 // Return the address of the first object in the active semispace. 2530 // Return the address of the first object in the active semispace.
2560 Address bottom() { return to_space_.space_start(); } 2531 Address bottom() { return to_space_.space_start(); }
2561 2532
2562 // Get the age mark of the inactive semispace. 2533 // Seal the intermediate generation of the active semispace.
2563 Address age_mark() { return from_space_.age_mark(); } 2534 void SealIntermediateGeneration();
2564 // Set the age mark in the active semispace.
2565 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); }
2566 2535
2567 // The allocation top and limit address. 2536 // The allocation top and limit address.
2568 Address* allocation_top_address() { return allocation_info_.top_address(); } 2537 Address* allocation_top_address() { return allocation_info_.top_address(); }
2569 2538
2570 // The allocation limit address. 2539 // The allocation limit address.
2571 Address* allocation_limit_address() { 2540 Address* allocation_limit_address() {
2572 return allocation_info_.limit_address(); 2541 return allocation_info_.limit_address();
2573 } 2542 }
2574 2543
2575 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( 2544 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned(
2576 int size_in_bytes, AllocationAlignment alignment)); 2545 int size_in_bytes, AllocationAlignment alignment));
2577 2546
2578 MUST_USE_RESULT INLINE( 2547 MUST_USE_RESULT INLINE(
2579 AllocationResult AllocateRawUnaligned(int size_in_bytes)); 2548 AllocationResult AllocateRawUnaligned(int size_in_bytes));
2580 2549
2581 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( 2550 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(
2582 int size_in_bytes, AllocationAlignment alignment)); 2551 int size_in_bytes, AllocationAlignment alignment));
2583 2552
2584 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( 2553 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized(
2585 int size_in_bytes, AllocationAlignment alignment); 2554 int size_in_bytes, AllocationAlignment alignment);
2586 2555
2587 // Reset the allocation pointer to the beginning of the active semispace. 2556 // Reset the allocation pointer to the beginning of the active semispace.
2588 void ResetAllocationInfo(); 2557 void ResetAllocationInfo();
2589 2558
2559 void SetAllocationInfo(Address top, Address limit) {
2560 allocation_info_.Reset(top, limit);
2561 }
2562
2590 // When inline allocation stepping is active, either because of incremental 2563 // When inline allocation stepping is active, either because of incremental
2591 // marking, idle scavenge, or allocation statistics gathering, we 'interrupt' 2564 // marking, idle scavenge, or allocation statistics gathering, we 'interrupt'
2592 // inline allocation every once in a while. This is done by setting 2565 // inline allocation every once in a while. This is done by setting
2593 // allocation_info_.limit to be lower than the actual limit and and increasing 2566 // allocation_info_.limit to be lower than the actual limit and and increasing
2594 // it in steps to guarantee that the observers are notified periodically. 2567 // it in steps to guarantee that the observers are notified periodically.
2595 void UpdateInlineAllocationLimit(int size_in_bytes); 2568 void UpdateInlineAllocationLimit(int size_in_bytes);
2596 2569
2597 void DisableInlineAllocationSteps() { 2570 void DisableInlineAllocationSteps() {
2598 top_on_previous_step_ = 0; 2571 top_on_previous_step_ = 0;
2599 UpdateInlineAllocationLimit(0); 2572 UpdateInlineAllocationLimit(0);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 2661
2689 // Allocation pointer and limit for normal allocation and allocation during 2662 // Allocation pointer and limit for normal allocation and allocation during
2690 // mark-compact collection. 2663 // mark-compact collection.
2691 AllocationInfo allocation_info_; 2664 AllocationInfo allocation_info_;
2692 2665
2693 Address top_on_previous_step_; 2666 Address top_on_previous_step_;
2694 2667
2695 HistogramInfo* allocated_histogram_; 2668 HistogramInfo* allocated_histogram_;
2696 HistogramInfo* promoted_histogram_; 2669 HistogramInfo* promoted_histogram_;
2697 2670
2671 size_t fragmentation_in_intermediate_generation_;
2672
2698 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); 2673 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment);
2699 2674
2700 // If we are doing inline allocation in steps, this method performs the 'step' 2675 // If we are doing inline allocation in steps, this method performs the 'step'
2701 // operation. top is the memory address of the bump pointer at the last 2676 // operation. top is the memory address of the bump pointer at the last
2702 // inline allocation (i.e. it determines the numbers of bytes actually 2677 // inline allocation (i.e. it determines the numbers of bytes actually
2703 // allocated since the last step.) new_top is the address of the bump pointer 2678 // allocated since the last step.) new_top is the address of the bump pointer
2704 // where the next byte is going to be allocated from. top and new_top may be 2679 // where the next byte is going to be allocated from. top and new_top may be
2705 // different when we cross a page boundary or reset the space. 2680 // different when we cross a page boundary or reset the space.
2706 void InlineAllocationStep(Address top, Address new_top, Address soon_object, 2681 void InlineAllocationStep(Address top, Address new_top, Address soon_object,
2707 size_t size); 2682 size_t size);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 PageIterator old_iterator_; 2917 PageIterator old_iterator_;
2943 PageIterator code_iterator_; 2918 PageIterator code_iterator_;
2944 PageIterator map_iterator_; 2919 PageIterator map_iterator_;
2945 LargePageIterator lo_iterator_; 2920 LargePageIterator lo_iterator_;
2946 }; 2921 };
2947 2922
2948 } // namespace internal 2923 } // namespace internal
2949 } // namespace v8 2924 } // namespace v8
2950 2925
2951 #endif // V8_HEAP_SPACES_H_ 2926 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698