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