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

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

Issue 1212063005: Revert of Reland: Fix logic for incremental marking steps on tenured allocation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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/spaces.h ('k') | test/cctest/test-heap.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 #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 2195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 free_bytes += huge_list_.Concatenate(free_list->huge_list()); 2206 free_bytes += huge_list_.Concatenate(free_list->huge_list());
2207 return free_bytes; 2207 return free_bytes;
2208 } 2208 }
2209 2209
2210 2210
2211 void FreeList::Reset() { 2211 void FreeList::Reset() {
2212 small_list_.Reset(); 2212 small_list_.Reset();
2213 medium_list_.Reset(); 2213 medium_list_.Reset();
2214 large_list_.Reset(); 2214 large_list_.Reset();
2215 huge_list_.Reset(); 2215 huge_list_.Reset();
2216 unreported_allocation_ = 0;
2217 } 2216 }
2218 2217
2219 2218
2220 int FreeList::Free(Address start, int size_in_bytes) { 2219 int FreeList::Free(Address start, int size_in_bytes) {
2221 if (size_in_bytes == 0) return 0; 2220 if (size_in_bytes == 0) return 0;
2222 2221
2223 heap_->CreateFillerObjectAt(start, size_in_bytes); 2222 heap_->CreateFillerObjectAt(start, size_in_bytes);
2224 2223
2225 Page* page = Page::FromAddress(start); 2224 Page* page = Page::FromAddress(start);
2226 2225
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2354 page = Page::FromAddress(node->address()); 2353 page = Page::FromAddress(node->address());
2355 page->add_available_in_large_free_list(-(*node_size)); 2354 page->add_available_in_large_free_list(-(*node_size));
2356 } 2355 }
2357 } 2356 }
2358 2357
2359 DCHECK(IsVeryLong() || available() == SumFreeLists()); 2358 DCHECK(IsVeryLong() || available() == SumFreeLists());
2360 return node; 2359 return node;
2361 } 2360 }
2362 2361
2363 2362
2364 void PagedSpace::SetTopAndLimit(Address top, Address limit) {
2365 DCHECK(top == limit ||
2366 Page::FromAddress(top) == Page::FromAddress(limit - 1));
2367 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
2368 allocation_info_.set_top(top);
2369 allocation_info_.set_limit(limit);
2370 }
2371
2372
2373 void PagedSpace::ReturnLinearAllocationAreaToFreeList() {
2374 int old_linear_size = static_cast<int>(limit() - top());
2375 Free(top(), old_linear_size);
2376 SetTopAndLimit(NULL, NULL);
2377 }
2378
2379
2380 // Allocation on the old space free list. If it succeeds then a new linear 2363 // Allocation on the old space free list. If it succeeds then a new linear
2381 // allocation space has been set up with the top and limit of the space. If 2364 // allocation space has been set up with the top and limit of the space. If
2382 // the allocation fails then NULL is returned, and the caller can perform a GC 2365 // the allocation fails then NULL is returned, and the caller can perform a GC
2383 // or allocate a new page before retrying. 2366 // or allocate a new page before retrying.
2384 HeapObject* FreeList::Allocate(int size_in_bytes) { 2367 HeapObject* FreeList::Allocate(int size_in_bytes) {
2385 DCHECK(0 < size_in_bytes); 2368 DCHECK(0 < size_in_bytes);
2386 DCHECK(size_in_bytes <= kMaxBlockSize); 2369 DCHECK(size_in_bytes <= kMaxBlockSize);
2387 DCHECK(IsAligned(size_in_bytes, kPointerSize)); 2370 DCHECK(IsAligned(size_in_bytes, kPointerSize));
2388 // Don't free list allocate if there is linear space available. 2371 // Don't free list allocate if there is linear space available.
2389 DCHECK(owner_->limit() - owner_->top() < size_in_bytes); 2372 DCHECK(owner_->limit() - owner_->top() < size_in_bytes);
2390 2373
2391 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top()); 2374 int old_linear_size = static_cast<int>(owner_->limit() - owner_->top());
2392 // Mark the old linear allocation area with a free space map so it can be 2375 // Mark the old linear allocation area with a free space map so it can be
2393 // skipped when scanning the heap. This also puts it back in the free list 2376 // skipped when scanning the heap. This also puts it back in the free list
2394 // if it is big enough. 2377 // if it is big enough.
2395 owner_->Free(owner_->top(), old_linear_size); 2378 owner_->Free(owner_->top(), old_linear_size);
2396 2379
2380 owner_->heap()->incremental_marking()->OldSpaceStep(size_in_bytes -
2381 old_linear_size);
2382
2397 int new_node_size = 0; 2383 int new_node_size = 0;
2398 FreeSpace* new_node = FindNodeFor(size_in_bytes, &new_node_size); 2384 FreeSpace* new_node = FindNodeFor(size_in_bytes, &new_node_size);
2399 if (new_node == NULL) { 2385 if (new_node == NULL) {
2400 owner_->SetTopAndLimit(NULL, NULL); 2386 owner_->SetTopAndLimit(NULL, NULL);
2401 return NULL; 2387 return NULL;
2402 } 2388 }
2403 2389
2404 int bytes_left = new_node_size - size_in_bytes; 2390 int bytes_left = new_node_size - size_in_bytes;
2405 DCHECK(bytes_left >= 0); 2391 DCHECK(bytes_left >= 0);
2406 2392
2407 #ifdef DEBUG 2393 #ifdef DEBUG
2408 for (int i = 0; i < size_in_bytes / kPointerSize; i++) { 2394 for (int i = 0; i < size_in_bytes / kPointerSize; i++) {
2409 reinterpret_cast<Object**>(new_node->address())[i] = 2395 reinterpret_cast<Object**>(new_node->address())[i] =
2410 Smi::FromInt(kCodeZapValue); 2396 Smi::FromInt(kCodeZapValue);
2411 } 2397 }
2412 #endif 2398 #endif
2413 2399
2414 // The old-space-step might have finished sweeping and restarted marking. 2400 // The old-space-step might have finished sweeping and restarted marking.
2415 // Verify that it did not turn the page of the new node into an evacuation 2401 // Verify that it did not turn the page of the new node into an evacuation
2416 // candidate. 2402 // candidate.
2417 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_node)); 2403 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_node));
2418 2404
2419 // An old-space step will mark more data per byte allocated, because old space 2405 const int kThreshold = IncrementalMarking::kAllocatedThreshold;
2420 // allocation is more serious. We don't want the pause to be bigger, so we
2421 // do marking after a smaller amount of allocation.
2422 const int kThreshold = IncrementalMarking::kAllocatedThreshold *
2423 IncrementalMarking::kOldSpaceAllocationMarkingFactor;
2424 2406
2425 // Memory in the linear allocation area is counted as allocated. We may free 2407 // Memory in the linear allocation area is counted as allocated. We may free
2426 // a little of this again immediately - see below. 2408 // a little of this again immediately - see below.
2427 owner_->Allocate(new_node_size); 2409 owner_->Allocate(new_node_size);
2428 2410
2429 unreported_allocation_ += new_node_size;
2430
2431 if (owner_->heap()->inline_allocation_disabled()) { 2411 if (owner_->heap()->inline_allocation_disabled()) {
2432 // Keep the linear allocation area empty if requested to do so, just 2412 // Keep the linear allocation area empty if requested to do so, just
2433 // return area back to the free list instead. 2413 // return area back to the free list instead.
2434 owner_->Free(new_node->address() + size_in_bytes, bytes_left); 2414 owner_->Free(new_node->address() + size_in_bytes, bytes_left);
2435 DCHECK(owner_->top() == NULL && owner_->limit() == NULL); 2415 DCHECK(owner_->top() == NULL && owner_->limit() == NULL);
2436 } else if (bytes_left > kThreshold && 2416 } else if (bytes_left > kThreshold &&
2437 owner_->heap()->incremental_marking()->CanDoSteps()) { 2417 owner_->heap()->incremental_marking()->IsMarkingIncomplete() &&
2418 FLAG_incremental_marking_steps) {
2438 int linear_size = owner_->RoundSizeDownToObjectAlignment(kThreshold); 2419 int linear_size = owner_->RoundSizeDownToObjectAlignment(kThreshold);
2439
2440 // We don't want to give too large linear areas to the allocator while 2420 // We don't want to give too large linear areas to the allocator while
2441 // incremental marking is going on, because we won't check again whether 2421 // incremental marking is going on, because we won't check again whether
2442 // we want to do another increment until the linear area is used up. 2422 // we want to do another increment until the linear area is used up.
2443 owner_->Free(new_node->address() + size_in_bytes + linear_size, 2423 owner_->Free(new_node->address() + size_in_bytes + linear_size,
2444 new_node_size - size_in_bytes - linear_size); 2424 new_node_size - size_in_bytes - linear_size);
2445 owner_->SetTopAndLimit(new_node->address() + size_in_bytes, 2425 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2446 new_node->address() + size_in_bytes + linear_size); 2426 new_node->address() + size_in_bytes + linear_size);
2447 // It is important that we are done updating top and limit before we call 2427 } else if (bytes_left > 0) {
2448 // this, because it might add the free space between top and limit to the 2428 // Normally we give the rest of the node to the allocator as its new
2449 // free list, and that would be very bad if top and new_node were still 2429 // linear allocation area.
2450 // pointing to the same place. 2430 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2451 owner_->heap()->incremental_marking()->OldSpaceStep(size_in_bytes + 2431 new_node->address() + new_node_size);
2452 linear_size);
2453 unreported_allocation_ = 0;
2454 } else { 2432 } else {
2455 if (bytes_left > 0) { 2433 // TODO(gc) Try not freeing linear allocation region when bytes_left
2456 // Normally we give the rest of the node to the allocator as its new 2434 // are zero.
2457 // linear allocation area. 2435 owner_->SetTopAndLimit(NULL, NULL);
2458 owner_->SetTopAndLimit(new_node->address() + size_in_bytes,
2459 new_node->address() + new_node_size);
2460 } else {
2461 // TODO(gc) Try not freeing linear allocation region when bytes_left
2462 // are zero.
2463 owner_->SetTopAndLimit(NULL, NULL);
2464 }
2465 if (unreported_allocation_ > kThreshold) {
2466 // This may start the incremental marker, or do a little work if it's
2467 // already started. It is important that we are finished updating top
2468 // and limit before we call this (see above).
2469 owner_->heap()->incremental_marking()->OldSpaceStep(
2470 Min(kThreshold, unreported_allocation_));
2471 unreported_allocation_ = 0;
2472 }
2473 } 2436 }
2474 2437
2475 return new_node; 2438 return new_node;
2476 } 2439 }
2477 2440
2478 2441
2479 intptr_t FreeList::EvictFreeListItems(Page* p) { 2442 intptr_t FreeList::EvictFreeListItems(Page* p) {
2480 intptr_t sum = huge_list_.EvictFreeListItemsInList(p); 2443 intptr_t sum = huge_list_.EvictFreeListItemsInList(p);
2481 p->set_available_in_huge_free_list(0); 2444 p->set_available_in_huge_free_list(0);
2482 2445
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
2949 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), object_size); 2912 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), object_size);
2950 2913
2951 if (Heap::ShouldZapGarbage()) { 2914 if (Heap::ShouldZapGarbage()) {
2952 // Make the object consistent so the heap can be verified in OldSpaceStep. 2915 // Make the object consistent so the heap can be verified in OldSpaceStep.
2953 // We only need to do this in debug builds or if verify_heap is on. 2916 // We only need to do this in debug builds or if verify_heap is on.
2954 reinterpret_cast<Object**>(object->address())[0] = 2917 reinterpret_cast<Object**>(object->address())[0] =
2955 heap()->fixed_array_map(); 2918 heap()->fixed_array_map();
2956 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); 2919 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0);
2957 } 2920 }
2958 2921
2959 // We would like to tell the incremental marker to do a lot of work, since 2922 heap()->incremental_marking()->OldSpaceStep(object_size);
2960 // we just made a large allocation in old space, but that might cause a huge
2961 // pause. Underreporting here may cause the marker to speed up because it
2962 // will perceive that it is not keeping up with allocation. Although this
2963 // causes some big incremental marking steps they are not as big as this one
2964 // might have been. In testing, a very large pause was divided up into about
2965 // 12 parts.
2966 const int kThreshold = IncrementalMarking::kAllocatedThreshold *
2967 IncrementalMarking::kOldSpaceAllocationMarkingFactor;
2968 heap()->incremental_marking()->OldSpaceStep(kThreshold);
2969 return object; 2923 return object;
2970 } 2924 }
2971 2925
2972 2926
2973 size_t LargeObjectSpace::CommittedPhysicalMemory() { 2927 size_t LargeObjectSpace::CommittedPhysicalMemory() {
2974 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); 2928 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory();
2975 size_t size = 0; 2929 size_t size = 0;
2976 LargePage* current = first_page_; 2930 LargePage* current = first_page_;
2977 while (current != NULL) { 2931 while (current != NULL) {
2978 size += current->CommittedPhysicalMemory(); 2932 size += current->CommittedPhysicalMemory();
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
3180 object->ShortPrint(); 3134 object->ShortPrint();
3181 PrintF("\n"); 3135 PrintF("\n");
3182 } 3136 }
3183 printf(" --------------------------------------\n"); 3137 printf(" --------------------------------------\n");
3184 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3138 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3185 } 3139 }
3186 3140
3187 #endif // DEBUG 3141 #endif // DEBUG
3188 } // namespace internal 3142 } // namespace internal
3189 } // namespace v8 3143 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698