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 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |