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