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.cc

Issue 1040233003: Fix logic for doing incremental marking steps on tenured allocation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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
« src/heap/incremental-marking.cc ('K') | « src/heap/spaces.h ('k') | no next file » | 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/full-codegen.h" 9 #include "src/full-codegen.h"
10 #include "src/heap/mark-compact.h" 10 #include "src/heap/mark-compact.h"
(...skipping 2340 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 page = Page::FromAddress(node->address()); 2351 page = Page::FromAddress(node->address());
2352 page->add_available_in_large_free_list(-(*node_size)); 2352 page->add_available_in_large_free_list(-(*node_size));
2353 } 2353 }
2354 } 2354 }
2355 2355
2356 DCHECK(IsVeryLong() || available() == SumFreeLists()); 2356 DCHECK(IsVeryLong() || available() == SumFreeLists());
2357 return node; 2357 return node;
2358 } 2358 }
2359 2359
2360 2360
2361 void PagedSpace::SetTopAndLimit(Address top, Address limit) {
2362 DCHECK(top == limit ||
2363 Page::FromAddress(top) == Page::FromAddress(limit - 1));
2364 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
2365 allocation_info_.set_top(top);
2366 allocation_info_.set_limit(limit);
2367 }
2368
2369
2361 // Allocation on the old space free list. If it succeeds then a new linear 2370 // Allocation on the old space free list. If it succeeds then a new linear
2362 // allocation space has been set up with the top and limit of the space. If 2371 // allocation space has been set up with the top and limit of the space. If
2363 // the allocation fails then NULL is returned, and the caller can perform a GC 2372 // the allocation fails then NULL is returned, and the caller can perform a GC
2364 // or allocate a new page before retrying. 2373 // or allocate a new page before retrying.
2365 HeapObject* FreeList::Allocate(int size_in_bytes) { 2374 HeapObject* FreeList::Allocate(int size_in_bytes) {
2366 DCHECK(0 < size_in_bytes); 2375 DCHECK(0 < size_in_bytes);
2367 DCHECK(size_in_bytes <= kMaxBlockSize); 2376 DCHECK(size_in_bytes <= kMaxBlockSize);
2368 DCHECK(IsAligned(size_in_bytes, kPointerSize)); 2377 DCHECK(IsAligned(size_in_bytes, kPointerSize));
2369 // Don't free list allocate if there is linear space available. 2378 // Don't free list allocate if there is linear space available.
2370 DCHECK(owner_->limit() - owner_->top() < size_in_bytes); 2379 DCHECK(owner_->limit() - owner_->top() < size_in_bytes);
2371 2380
2372 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top()); 2381 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top());
2373 // Mark the old linear allocation area with a free space map so it can be 2382 // Mark the old linear allocation area with a free space map so it can be
2374 // skipped when scanning the heap. This also puts it back in the free list 2383 // skipped when scanning the heap. This also puts it back in the free list
2375 // if it is big enough. 2384 // if it is big enough.
2376 owner_->Free(owner_->top(), old_linear_size); 2385 owner_->Free(owner_->top(), old_linear_size);
2377 2386
2378 owner_->heap()->incremental_marking()->OldSpaceStep(size_in_bytes -
2379 old_linear_size);
Erik Corry Chromium.org 2015/03/31 13:11:32 This was basically wrong, basing the step on the s
2380
2381 int new_node_size = 0; 2387 int new_node_size = 0;
2382 FreeSpace* new_node = FindNodeFor(size_in_bytes, &new_node_size); 2388 FreeSpace* new_node = FindNodeFor(size_in_bytes, &new_node_size);
2383 if (new_node == NULL) { 2389 if (new_node == NULL) {
2384 owner_->SetTopAndLimit(NULL, NULL); 2390 owner_->SetTopAndLimit(NULL, NULL);
2385 return NULL; 2391 return NULL;
2386 } 2392 }
2387 2393
2388 int bytes_left = new_node_size - size_in_bytes; 2394 int bytes_left = new_node_size - size_in_bytes;
2389 DCHECK(bytes_left >= 0); 2395 DCHECK(bytes_left >= 0);
2390 2396
2391 #ifdef DEBUG 2397 #ifdef DEBUG
2392 for (int i = 0; i < size_in_bytes / kPointerSize; i++) { 2398 for (int i = 0; i < size_in_bytes / kPointerSize; i++) {
2393 reinterpret_cast<Object**>(new_node->address())[i] = 2399 reinterpret_cast<Object**>(new_node->address())[i] =
2394 Smi::FromInt(kCodeZapValue); 2400 Smi::FromInt(kCodeZapValue);
2395 } 2401 }
2396 #endif 2402 #endif
2397 2403
2398 // The old-space-step might have finished sweeping and restarted marking. 2404 // The old-space-step might have finished sweeping and restarted marking.
2399 // Verify that it did not turn the page of the new node into an evacuation 2405 // Verify that it did not turn the page of the new node into an evacuation
2400 // candidate. 2406 // candidate.
2401 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_node)); 2407 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_node));
2402 2408
2403 const int kThreshold = IncrementalMarking::kAllocatedThreshold; 2409 // An old-space step will mark more data per byte allocated, because old space
2410 // allocation is more serious. We don't want the pause to be bigger, so we
2411 // do marking after a smaller amount of allocation.
2412 const int kThreshold = IncrementalMarking::kAllocatedThreshold *
2413 IncrementalMarking::kOldSpaceAllocationMarkingFactor;
2404 2414
2405 // Memory in the linear allocation area is counted as allocated. We may free 2415 // Memory in the linear allocation area is counted as allocated. We may free
2406 // a little of this again immediately - see below. 2416 // a little of this again immediately - see below.
2407 owner_->Allocate(new_node_size); 2417 owner_->Allocate(new_node_size);
2408 2418
2409 if (owner_->heap()->inline_allocation_disabled()) { 2419 if (owner_->heap()->inline_allocation_disabled()) {
2410 // Keep the linear allocation area empty if requested to do so, just 2420 // Keep the linear allocation area empty if requested to do so, just
2411 // return area back to the free list instead. 2421 // return area back to the free list instead.
2412 owner_->Free(new_node->address() + size_in_bytes, bytes_left); 2422 owner_->Free(new_node->address() + size_in_bytes, bytes_left);
2413 DCHECK(owner_->top() == NULL && owner_->limit() == NULL); 2423 DCHECK(owner_->top() == NULL && owner_->limit() == NULL);
2414 } else if (bytes_left > kThreshold && 2424 } else if (bytes_left > kThreshold &&
2415 owner_->heap()->incremental_marking()->IsMarkingIncomplete() && 2425 owner_->heap()->incremental_marking()->CanDoSteps()) {
2416 FLAG_incremental_marking_steps) {
2417 int linear_size = owner_->RoundSizeDownToObjectAlignment(kThreshold); 2426 int linear_size = owner_->RoundSizeDownToObjectAlignment(kThreshold);
2427
2418 // We don't want to give too large linear areas to the allocator while 2428 // We don't want to give too large linear areas to the allocator while
2419 // incremental marking is going on, because we won't check again whether 2429 // incremental marking is going on, because we won't check again whether
2420 // we want to do another increment until the linear area is used up. 2430 // we want to do another increment until the linear area is used up.
2421 owner_->Free(new_node->address() + size_in_bytes + linear_size, 2431 owner_->Free(new_node->address() + size_in_bytes + linear_size,
2422 new_node_size - size_in_bytes - linear_size); 2432 new_node_size - size_in_bytes - linear_size);
2423 owner_->SetTopAndLimit(new_node->address() + size_in_bytes, 2433 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2424 new_node->address() + size_in_bytes + linear_size); 2434 new_node->address() + size_in_bytes + linear_size);
2425 } else if (bytes_left > 0) { 2435 owner_->heap()->incremental_marking()->OldSpaceStep(size_in_bytes +
2426 // Normally we give the rest of the node to the allocator as its new 2436 linear_size);
2427 // linear allocation area.
2428 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2429 new_node->address() + new_node_size);
2430 } else { 2437 } else {
2431 // TODO(gc) Try not freeing linear allocation region when bytes_left 2438 if (owner_->heap()->incremental_marking()->CanDoSteps()) {
2432 // are zero. 2439 owner_->heap()->incremental_marking()->OldSpaceStep(new_node_size);
2433 owner_->SetTopAndLimit(NULL, NULL); 2440 } else if (new_node_size > kThreshold) {
2441 // When we give big chunks to the old space allocator we do a little
2442 // step in case the incremental marker wants to start.
2443 owner_->heap()->incremental_marking()->OldSpaceStep(kThreshold);
2444 }
2445 if (bytes_left > 0) {
2446 // Normally we give the rest of the node to the allocator as its new
2447 // linear allocation area.
2448 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2449 new_node->address() + new_node_size);
2450 } else {
2451 // TODO(gc) Try not freeing linear allocation region when bytes_left
2452 // are zero.
2453 owner_->SetTopAndLimit(NULL, NULL);
2454 }
2434 } 2455 }
2435 2456
2436 return new_node; 2457 return new_node;
2437 } 2458 }
2438 2459
2439 2460
2440 intptr_t FreeList::EvictFreeListItems(Page* p) { 2461 intptr_t FreeList::EvictFreeListItems(Page* p) {
2441 intptr_t sum = huge_list_.EvictFreeListItemsInList(p); 2462 intptr_t sum = huge_list_.EvictFreeListItemsInList(p);
2442 p->set_available_in_huge_free_list(0); 2463 p->set_available_in_huge_free_list(0);
2443 2464
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 mark_size += heap()->GcSafeSizeOfOldObjectFunction()(object); 3161 mark_size += heap()->GcSafeSizeOfOldObjectFunction()(object);
3141 } 3162 }
3142 object->ShortPrint(); 3163 object->ShortPrint();
3143 PrintF("\n"); 3164 PrintF("\n");
3144 } 3165 }
3145 printf(" --------------------------------------\n"); 3166 printf(" --------------------------------------\n");
3146 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3167 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3147 } 3168 }
3148 3169
3149 #endif // DEBUG 3170 #endif // DEBUG
3171
3150 } 3172 }
3151 } // namespace v8::internal 3173 } // namespace v8::internal
OLDNEW
« src/heap/incremental-marking.cc ('K') | « src/heap/spaces.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698