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

Side by Side Diff: src/heap/mark-compact.cc

Issue 1772733002: [heap] Move to two-level free-list (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Speed up very slow FreeList::IsVeryLong which is used in a regular DCHECK Created 4 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/heap/mark-compact.h" 5 #include "src/heap/mark-compact.h"
6 6
7 #include "src/base/atomicops.h" 7 #include "src/base/atomicops.h"
8 #include "src/base/bits.h" 8 #include "src/base/bits.h"
9 #include "src/base/sys-info.h" 9 #include "src/base/sys-info.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 } 235 }
236 #endif // VERIFY_HEAP 236 #endif // VERIFY_HEAP
237 237
238 238
239 void MarkCompactCollector::SetUp() { 239 void MarkCompactCollector::SetUp() {
240 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 240 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
241 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 241 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
242 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 242 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0);
243 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 243 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
244 244
245 free_list_old_space_.Reset(new FreeList(heap_->old_space()));
246 free_list_code_space_.Reset(new FreeList(heap_->code_space()));
247 free_list_map_space_.Reset(new FreeList(heap_->map_space()));
248 EnsureMarkingDequeIsReserved(); 245 EnsureMarkingDequeIsReserved();
249 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); 246 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize);
250 247
251 if (FLAG_flush_code) { 248 if (FLAG_flush_code) {
252 code_flusher_ = new CodeFlusher(isolate()); 249 code_flusher_ = new CodeFlusher(isolate());
253 if (FLAG_trace_code_flushing) { 250 if (FLAG_trace_code_flushing) {
254 PrintF("[code-flushing is now on]\n"); 251 PrintF("[code-flushing is now on]\n");
255 } 252 }
256 } 253 }
257 } 254 }
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } 466 }
470 467
471 Heap* heap_; 468 Heap* heap_;
472 AllocationSpace space_to_start_; 469 AllocationSpace space_to_start_;
473 470
474 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 471 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
475 }; 472 };
476 473
477 474
478 void MarkCompactCollector::StartSweeperThreads() { 475 void MarkCompactCollector::StartSweeperThreads() {
479 DCHECK(free_list_old_space_.get()->IsEmpty());
480 DCHECK(free_list_code_space_.get()->IsEmpty());
481 DCHECK(free_list_map_space_.get()->IsEmpty());
482 V8::GetCurrentPlatform()->CallOnBackgroundThread( 476 V8::GetCurrentPlatform()->CallOnBackgroundThread(
483 new SweeperTask(heap(), OLD_SPACE), v8::Platform::kShortRunningTask); 477 new SweeperTask(heap(), OLD_SPACE), v8::Platform::kShortRunningTask);
484 V8::GetCurrentPlatform()->CallOnBackgroundThread( 478 V8::GetCurrentPlatform()->CallOnBackgroundThread(
485 new SweeperTask(heap(), CODE_SPACE), v8::Platform::kShortRunningTask); 479 new SweeperTask(heap(), CODE_SPACE), v8::Platform::kShortRunningTask);
486 V8::GetCurrentPlatform()->CallOnBackgroundThread( 480 V8::GetCurrentPlatform()->CallOnBackgroundThread(
487 new SweeperTask(heap(), MAP_SPACE), v8::Platform::kShortRunningTask); 481 new SweeperTask(heap(), MAP_SPACE), v8::Platform::kShortRunningTask);
488 } 482 }
489 483
490 484
491 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) { 485 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) {
(...skipping 2800 matching lines...) Expand 10 before | Expand all | Expand 10 after
3292 HeapObject* heap_object = HeapObject::cast(object); 3286 HeapObject* heap_object = HeapObject::cast(object);
3293 MapWord map_word = heap_object->map_word(); 3287 MapWord map_word = heap_object->map_word();
3294 if (map_word.IsForwardingAddress()) { 3288 if (map_word.IsForwardingAddress()) {
3295 return map_word.ToForwardingAddress(); 3289 return map_word.ToForwardingAddress();
3296 } 3290 }
3297 } 3291 }
3298 return object; 3292 return object;
3299 } 3293 }
3300 }; 3294 };
3301 3295
3302
3303 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; 3296 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS };
3304 3297
3305
3306 enum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST }; 3298 enum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST };
3307 3299
3308
3309 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; 3300 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE };
3310 3301
3311
3312 template <MarkCompactCollector::SweepingParallelism mode>
3313 static intptr_t Free(PagedSpace* space, FreeList* free_list, Address start,
3314 int size) {
3315 if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
3316 DCHECK(free_list == NULL);
3317 return space->Free(start, size);
3318 } else {
3319 return size - free_list->Free(start, size);
3320 }
3321 }
3322
3323
3324 // Sweeps a page. After sweeping the page can be iterated. 3302 // Sweeps a page. After sweeping the page can be iterated.
3325 // Slots in live objects pointing into evacuation candidates are updated 3303 // Slots in live objects pointing into evacuation candidates are updated
3326 // if requested. 3304 // if requested.
3327 // Returns the size of the biggest continuous freed memory chunk in bytes. 3305 // Returns the size of the biggest continuous freed memory chunk in bytes.
3328 template <SweepingMode sweeping_mode, 3306 template <SweepingMode sweeping_mode,
3329 MarkCompactCollector::SweepingParallelism parallelism, 3307 MarkCompactCollector::SweepingParallelism parallelism,
3330 SkipListRebuildingMode skip_list_mode, 3308 SkipListRebuildingMode skip_list_mode,
3331 FreeSpaceTreatmentMode free_space_mode> 3309 FreeSpaceTreatmentMode free_space_mode>
3332 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, 3310 static int Sweep(PagedSpace* space, Page* p, ObjectVisitor* v) {
3333 ObjectVisitor* v) {
3334 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); 3311 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
3335 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, 3312 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
3336 space->identity() == CODE_SPACE); 3313 space->identity() == CODE_SPACE);
3337 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); 3314 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
3338 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || 3315 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
3339 sweeping_mode == SWEEP_ONLY); 3316 sweeping_mode == SWEEP_ONLY);
3340 3317
3341 Address free_start = p->area_start(); 3318 Address free_start = p->area_start();
3342 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3319 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3343 3320
(...skipping 12 matching lines...) Expand all
3356 LiveObjectIterator<kBlackObjects> it(p); 3333 LiveObjectIterator<kBlackObjects> it(p);
3357 HeapObject* object = NULL; 3334 HeapObject* object = NULL;
3358 while ((object = it.Next()) != NULL) { 3335 while ((object = it.Next()) != NULL) {
3359 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); 3336 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
3360 Address free_end = object->address(); 3337 Address free_end = object->address();
3361 if (free_end != free_start) { 3338 if (free_end != free_start) {
3362 int size = static_cast<int>(free_end - free_start); 3339 int size = static_cast<int>(free_end - free_start);
3363 if (free_space_mode == ZAP_FREE_SPACE) { 3340 if (free_space_mode == ZAP_FREE_SPACE) {
3364 memset(free_start, 0xcc, size); 3341 memset(free_start, 0xcc, size);
3365 } 3342 }
3366 freed_bytes = Free<parallelism>(space, free_list, free_start, size); 3343 freed_bytes = space->UnaccountedFree(free_start, size);
3367 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3344 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3368 } 3345 }
3369 Map* map = object->synchronized_map(); 3346 Map* map = object->synchronized_map();
3370 int size = object->SizeFromMap(map); 3347 int size = object->SizeFromMap(map);
3371 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { 3348 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
3372 object->IterateBody(map->instance_type(), size, v); 3349 object->IterateBody(map->instance_type(), size, v);
3373 } 3350 }
3374 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { 3351 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) {
3375 int new_region_start = SkipList::RegionNumber(free_end); 3352 int new_region_start = SkipList::RegionNumber(free_end);
3376 int new_region_end = 3353 int new_region_end =
3377 SkipList::RegionNumber(free_end + size - kPointerSize); 3354 SkipList::RegionNumber(free_end + size - kPointerSize);
3378 if (new_region_start != curr_region || new_region_end != curr_region) { 3355 if (new_region_start != curr_region || new_region_end != curr_region) {
3379 skip_list->AddObject(free_end, size); 3356 skip_list->AddObject(free_end, size);
3380 curr_region = new_region_end; 3357 curr_region = new_region_end;
3381 } 3358 }
3382 } 3359 }
3383 free_start = free_end + size; 3360 free_start = free_end + size;
3384 } 3361 }
3385 3362
3386 // Clear the mark bits of that page and reset live bytes count. 3363 // Clear the mark bits of that page and reset live bytes count.
3387 Bitmap::Clear(p); 3364 Bitmap::Clear(p);
3388 3365
3389 if (free_start != p->area_end()) { 3366 if (free_start != p->area_end()) {
3390 int size = static_cast<int>(p->area_end() - free_start); 3367 int size = static_cast<int>(p->area_end() - free_start);
3391 if (free_space_mode == ZAP_FREE_SPACE) { 3368 if (free_space_mode == ZAP_FREE_SPACE) {
3392 memset(free_start, 0xcc, size); 3369 memset(free_start, 0xcc, size);
3393 } 3370 }
3394 freed_bytes = Free<parallelism>(space, free_list, free_start, size); 3371 freed_bytes = space->UnaccountedFree(free_start, size);
3395 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3372 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3396 } 3373 }
3397 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); 3374 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3398 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); 3375 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
3399 } 3376 }
3400 3377
3401 3378
3402 void MarkCompactCollector::InvalidateCode(Code* code) { 3379 void MarkCompactCollector::InvalidateCode(Code* code) {
3403 if (heap_->incremental_marking()->IsCompacting() && 3380 if (heap_->incremental_marking()->IsCompacting() &&
3404 !ShouldSkipEvacuationSlotRecording(code)) { 3381 !ShouldSkipEvacuationSlotRecording(code)) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
3499 void MarkCompactCollector::SweepAbortedPages() { 3476 void MarkCompactCollector::SweepAbortedPages() {
3500 // Second pass on aborted pages. 3477 // Second pass on aborted pages.
3501 for (Page* p : evacuation_candidates_) { 3478 for (Page* p : evacuation_candidates_) {
3502 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { 3479 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) {
3503 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED); 3480 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED);
3504 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3481 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3505 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3482 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3506 switch (space->identity()) { 3483 switch (space->identity()) {
3507 case OLD_SPACE: 3484 case OLD_SPACE:
3508 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, 3485 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
3509 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr); 3486 IGNORE_FREE_SPACE>(space, p, nullptr);
3510 break; 3487 break;
3511 case CODE_SPACE: 3488 case CODE_SPACE:
3512 if (FLAG_zap_code_space) { 3489 if (FLAG_zap_code_space) {
3513 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 3490 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
3514 ZAP_FREE_SPACE>(space, NULL, p, nullptr); 3491 ZAP_FREE_SPACE>(space, p, nullptr);
3515 } else { 3492 } else {
3516 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 3493 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
3517 IGNORE_FREE_SPACE>(space, NULL, p, nullptr); 3494 IGNORE_FREE_SPACE>(space, p, nullptr);
3518 } 3495 }
3519 break; 3496 break;
3520 default: 3497 default:
3521 UNREACHABLE(); 3498 UNREACHABLE();
3522 break; 3499 break;
3523 } 3500 }
3501 {
3502 base::LockGuard<base::Mutex> guard(&swept_pages_mutex_);
3503 swept_pages(space->identity())->Add(p);
3504 }
3524 } 3505 }
3525 } 3506 }
3526 } 3507 }
3527 3508
3528 3509
3529 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { 3510 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
3530 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_EVACUATE); 3511 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_EVACUATE);
3531 Heap::RelocationLock relocation_lock(heap()); 3512 Heap::RelocationLock relocation_lock(heap());
3532 3513
3533 { 3514 {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
3706 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n", 3687 PrintF("Sweeping 0x%" V8PRIxPTR " during evacuation.\n",
3707 reinterpret_cast<intptr_t>(p)); 3688 reinterpret_cast<intptr_t>(p));
3708 } 3689 }
3709 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3690 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3710 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION); 3691 p->ClearFlag(MemoryChunk::RESCAN_ON_EVACUATION);
3711 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3692 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3712 3693
3713 switch (space->identity()) { 3694 switch (space->identity()) {
3714 case OLD_SPACE: 3695 case OLD_SPACE:
3715 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3696 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3716 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3697 IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, p,
3717 &updating_visitor); 3698 &updating_visitor);
3718 break; 3699 break;
3719 case CODE_SPACE: 3700 case CODE_SPACE:
3720 if (FLAG_zap_code_space) { 3701 if (FLAG_zap_code_space) {
3721 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3702 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3722 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p, 3703 REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, p,
3723 &updating_visitor); 3704 &updating_visitor);
3724 } else { 3705 } else {
3725 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD, 3706 Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
3726 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p, 3707 REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, p,
3727 &updating_visitor); 3708 &updating_visitor);
3728 } 3709 }
3729 break; 3710 break;
3730 default: 3711 default:
3731 UNREACHABLE(); 3712 UNREACHABLE();
3732 break; 3713 break;
3733 } 3714 }
3734 } 3715 }
3735 } 3716 }
3736 } 3717 }
(...skipping 10 matching lines...) Expand all
3747 EvacuationWeakObjectRetainer evacuation_object_retainer; 3728 EvacuationWeakObjectRetainer evacuation_object_retainer;
3748 heap()->ProcessWeakListRoots(&evacuation_object_retainer); 3729 heap()->ProcessWeakListRoots(&evacuation_object_retainer);
3749 } 3730 }
3750 } 3731 }
3751 3732
3752 3733
3753 void MarkCompactCollector::ReleaseEvacuationCandidates() { 3734 void MarkCompactCollector::ReleaseEvacuationCandidates() {
3754 for (Page* p : evacuation_candidates_) { 3735 for (Page* p : evacuation_candidates_) {
3755 if (!p->IsEvacuationCandidate()) continue; 3736 if (!p->IsEvacuationCandidate()) continue;
3756 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); 3737 PagedSpace* space = static_cast<PagedSpace*>(p->owner());
3757 space->Free(p->area_start(), p->area_size());
3758 p->ResetLiveBytes(); 3738 p->ResetLiveBytes();
3759 CHECK(p->SweepingDone()); 3739 CHECK(p->SweepingDone());
3760 space->ReleasePage(p, true); 3740 space->ReleasePage(p);
3761 } 3741 }
3762 evacuation_candidates_.Rewind(0); 3742 evacuation_candidates_.Rewind(0);
3763 compacting_ = false; 3743 compacting_ = false;
3764 heap()->FreeQueuedChunks(); 3744 heap()->FreeQueuedChunks();
3765 } 3745 }
3766 3746
3767 3747
3768 int MarkCompactCollector::SweepInParallel(PagedSpace* space, 3748 int MarkCompactCollector::SweepInParallel(PagedSpace* space,
3769 int required_freed_bytes, 3749 int required_freed_bytes,
3770 int max_pages) { 3750 int max_pages) {
(...skipping 18 matching lines...) Expand all
3789 3769
3790 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { 3770 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
3791 int max_freed = 0; 3771 int max_freed = 0;
3792 if (page->mutex()->TryLock()) { 3772 if (page->mutex()->TryLock()) {
3793 // If this page was already swept in the meantime, we can return here. 3773 // If this page was already swept in the meantime, we can return here.
3794 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) { 3774 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) {
3795 page->mutex()->Unlock(); 3775 page->mutex()->Unlock();
3796 return 0; 3776 return 0;
3797 } 3777 }
3798 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3778 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3799 FreeList* free_list;
3800 FreeList private_free_list(space);
3801 if (space->identity() == OLD_SPACE) { 3779 if (space->identity() == OLD_SPACE) {
3802 free_list = free_list_old_space_.get(); 3780 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
3803 max_freed = 3781 IGNORE_FREE_SPACE>(space, page, NULL);
3804 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
3805 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
3806 } else if (space->identity() == CODE_SPACE) { 3782 } else if (space->identity() == CODE_SPACE) {
3807 free_list = free_list_code_space_.get(); 3783 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST,
3808 max_freed = 3784 IGNORE_FREE_SPACE>(space, page, NULL);
3809 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST,
3810 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
3811 } else { 3785 } else {
3812 free_list = free_list_map_space_.get(); 3786 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
3813 max_freed = 3787 IGNORE_FREE_SPACE>(space, page, NULL);
3814 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
3815 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
3816 } 3788 }
3817 free_list->Concatenate(&private_free_list); 3789 {
3790 base::LockGuard<base::Mutex> guard(&swept_pages_mutex_);
3791 swept_pages(space->identity())->Add(page);
3792 }
3818 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone); 3793 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3819 page->mutex()->Unlock(); 3794 page->mutex()->Unlock();
3820 } 3795 }
3821 return max_freed; 3796 return max_freed;
3822 } 3797 }
3823 3798
3824 3799
3825 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { 3800 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) {
3826 space->ClearStats(); 3801 space->ClearStats();
3827 3802
(...skipping 13 matching lines...) Expand all
3841 continue; 3816 continue;
3842 } 3817 }
3843 3818
3844 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { 3819 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) {
3845 // We need to sweep the page to get it into an iterable state again. Note 3820 // We need to sweep the page to get it into an iterable state again. Note
3846 // that this adds unusable memory into the free list that is later on 3821 // that this adds unusable memory into the free list that is later on
3847 // (in the free list) dropped again. Since we only use the flag for 3822 // (in the free list) dropped again. Since we only use the flag for
3848 // testing this is fine. 3823 // testing this is fine.
3849 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3824 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3850 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, 3825 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
3851 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr); 3826 IGNORE_FREE_SPACE>(space, p, nullptr);
3852 continue; 3827 continue;
3853 } 3828 }
3854 3829
3855 // One unused page is kept, all further are released before sweeping them. 3830 // One unused page is kept, all further are released before sweeping them.
3856 if (p->LiveBytes() == 0) { 3831 if (p->LiveBytes() == 0) {
3857 if (unused_page_present) { 3832 if (unused_page_present) {
3858 if (FLAG_gc_verbose) { 3833 if (FLAG_gc_verbose) {
3859 PrintIsolate(isolate(), "sweeping: released page: %p", p); 3834 PrintIsolate(isolate(), "sweeping: released page: %p", p);
3860 } 3835 }
3861 space->ReleasePage(p, false); 3836 space->ReleasePage(p);
3862 continue; 3837 continue;
3863 } 3838 }
3864 unused_page_present = true; 3839 unused_page_present = true;
3865 } 3840 }
3866 3841
3867 p->concurrent_sweeping_state().SetValue(Page::kSweepingPending); 3842 p->concurrent_sweeping_state().SetValue(Page::kSweepingPending);
3868 sweeping_list(space).push_back(p); 3843 sweeping_list(space).push_back(p);
3869 int to_sweep = p->area_size() - p->LiveBytes(); 3844 int to_sweep = p->area_size() - p->LiveBytes();
3870 space->accounting_stats_.ShrinkSpace(to_sweep); 3845 space->accounting_stats_.ShrinkSpace(to_sweep);
3871 will_be_swept++; 3846 will_be_swept++;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3957 MarkBit mark_bit = Marking::MarkBitFrom(host); 3932 MarkBit mark_bit = Marking::MarkBitFrom(host);
3958 if (Marking::IsBlack(mark_bit)) { 3933 if (Marking::IsBlack(mark_bit)) {
3959 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 3934 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
3960 RecordRelocSlot(host, &rinfo, target); 3935 RecordRelocSlot(host, &rinfo, target);
3961 } 3936 }
3962 } 3937 }
3963 } 3938 }
3964 3939
3965 } // namespace internal 3940 } // namespace internal
3966 } // namespace v8 3941 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/spaces.h » ('j') | src/heap/spaces.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698