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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 247 } |
248 #endif // VERIFY_HEAP | 248 #endif // VERIFY_HEAP |
249 | 249 |
250 | 250 |
251 void MarkCompactCollector::SetUp() { | 251 void MarkCompactCollector::SetUp() { |
252 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 252 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
253 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); | 253 DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); |
254 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); | 254 DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); |
255 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 255 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
256 | 256 |
257 free_list_old_space_.Reset(new FreeList(heap_->old_space())); | |
258 free_list_code_space_.Reset(new FreeList(heap_->code_space())); | |
259 free_list_map_space_.Reset(new FreeList(heap_->map_space())); | |
260 EnsureMarkingDequeIsReserved(); | 257 EnsureMarkingDequeIsReserved(); |
261 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); | 258 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); |
262 | 259 |
263 if (FLAG_flush_code) { | 260 if (FLAG_flush_code) { |
264 code_flusher_ = new CodeFlusher(isolate()); | 261 code_flusher_ = new CodeFlusher(isolate()); |
265 if (FLAG_trace_code_flushing) { | 262 if (FLAG_trace_code_flushing) { |
266 PrintF("[code-flushing is now on]\n"); | 263 PrintF("[code-flushing is now on]\n"); |
267 } | 264 } |
268 } | 265 } |
269 } | 266 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 } | 486 } |
490 | 487 |
491 Heap* heap_; | 488 Heap* heap_; |
492 AllocationSpace space_to_start_; | 489 AllocationSpace space_to_start_; |
493 | 490 |
494 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 491 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
495 }; | 492 }; |
496 | 493 |
497 | 494 |
498 void MarkCompactCollector::StartSweeperThreads() { | 495 void MarkCompactCollector::StartSweeperThreads() { |
499 DCHECK(free_list_old_space_.get()->IsEmpty()); | |
500 DCHECK(free_list_code_space_.get()->IsEmpty()); | |
501 DCHECK(free_list_map_space_.get()->IsEmpty()); | |
502 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 496 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
503 new SweeperTask(heap(), OLD_SPACE), v8::Platform::kShortRunningTask); | 497 new SweeperTask(heap(), OLD_SPACE), v8::Platform::kShortRunningTask); |
504 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 498 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
505 new SweeperTask(heap(), CODE_SPACE), v8::Platform::kShortRunningTask); | 499 new SweeperTask(heap(), CODE_SPACE), v8::Platform::kShortRunningTask); |
506 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 500 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
507 new SweeperTask(heap(), MAP_SPACE), v8::Platform::kShortRunningTask); | 501 new SweeperTask(heap(), MAP_SPACE), v8::Platform::kShortRunningTask); |
508 } | 502 } |
509 | 503 |
510 | 504 |
511 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) { | 505 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) { |
(...skipping 2726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3238 HeapObject* heap_object = HeapObject::cast(object); | 3232 HeapObject* heap_object = HeapObject::cast(object); |
3239 MapWord map_word = heap_object->map_word(); | 3233 MapWord map_word = heap_object->map_word(); |
3240 if (map_word.IsForwardingAddress()) { | 3234 if (map_word.IsForwardingAddress()) { |
3241 return map_word.ToForwardingAddress(); | 3235 return map_word.ToForwardingAddress(); |
3242 } | 3236 } |
3243 } | 3237 } |
3244 return object; | 3238 return object; |
3245 } | 3239 } |
3246 }; | 3240 }; |
3247 | 3241 |
3248 | |
3249 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; | 3242 enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; |
3250 | 3243 |
3251 | |
3252 enum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST }; | 3244 enum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST }; |
3253 | 3245 |
3254 | |
3255 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; | 3246 enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; |
3256 | 3247 |
3257 | |
3258 template <MarkCompactCollector::SweepingParallelism mode> | |
3259 static intptr_t Free(PagedSpace* space, FreeList* free_list, Address start, | |
3260 int size) { | |
3261 if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) { | |
3262 DCHECK(free_list == NULL); | |
3263 return space->Free(start, size); | |
3264 } else { | |
3265 return size - free_list->Free(start, size); | |
3266 } | |
3267 } | |
3268 | |
3269 | |
3270 // Sweeps a page. After sweeping the page can be iterated. | 3248 // Sweeps a page. After sweeping the page can be iterated. |
3271 // Slots in live objects pointing into evacuation candidates are updated | 3249 // Slots in live objects pointing into evacuation candidates are updated |
3272 // if requested. | 3250 // if requested. |
3273 // Returns the size of the biggest continuous freed memory chunk in bytes. | 3251 // Returns the size of the biggest continuous freed memory chunk in bytes. |
3274 template <SweepingMode sweeping_mode, | 3252 template <SweepingMode sweeping_mode, |
3275 MarkCompactCollector::SweepingParallelism parallelism, | 3253 MarkCompactCollector::SweepingParallelism parallelism, |
3276 SkipListRebuildingMode skip_list_mode, | 3254 SkipListRebuildingMode skip_list_mode, |
3277 FreeSpaceTreatmentMode free_space_mode> | 3255 FreeSpaceTreatmentMode free_space_mode> |
3278 static int Sweep(PagedSpace* space, FreeList* free_list, Page* p, | 3256 static int Sweep(PagedSpace* space, Page* p, ObjectVisitor* v) { |
3279 ObjectVisitor* v) { | |
3280 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); | 3257 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
3281 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); | 3258 DCHECK(!p->IsFlagSet(Page::BLACK_PAGE)); |
3282 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3259 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
3283 space->identity() == CODE_SPACE); | 3260 space->identity() == CODE_SPACE); |
3284 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3261 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
3285 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3262 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
3286 sweeping_mode == SWEEP_ONLY); | 3263 sweeping_mode == SWEEP_ONLY); |
3287 | 3264 |
3288 Address free_start = p->area_start(); | 3265 Address free_start = p->area_start(); |
3289 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3266 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
(...skipping 13 matching lines...) Expand all Loading... |
3303 LiveObjectIterator<kBlackObjects> it(p); | 3280 LiveObjectIterator<kBlackObjects> it(p); |
3304 HeapObject* object = NULL; | 3281 HeapObject* object = NULL; |
3305 while ((object = it.Next()) != NULL) { | 3282 while ((object = it.Next()) != NULL) { |
3306 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 3283 DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
3307 Address free_end = object->address(); | 3284 Address free_end = object->address(); |
3308 if (free_end != free_start) { | 3285 if (free_end != free_start) { |
3309 int size = static_cast<int>(free_end - free_start); | 3286 int size = static_cast<int>(free_end - free_start); |
3310 if (free_space_mode == ZAP_FREE_SPACE) { | 3287 if (free_space_mode == ZAP_FREE_SPACE) { |
3311 memset(free_start, 0xcc, size); | 3288 memset(free_start, 0xcc, size); |
3312 } | 3289 } |
3313 freed_bytes = Free<parallelism>(space, free_list, free_start, size); | 3290 freed_bytes = space->UnaccountedFree(free_start, size); |
3314 max_freed_bytes = Max(freed_bytes, max_freed_bytes); | 3291 max_freed_bytes = Max(freed_bytes, max_freed_bytes); |
3315 } | 3292 } |
3316 Map* map = object->synchronized_map(); | 3293 Map* map = object->synchronized_map(); |
3317 int size = object->SizeFromMap(map); | 3294 int size = object->SizeFromMap(map); |
3318 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { | 3295 if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) { |
3319 object->IterateBody(map->instance_type(), size, v); | 3296 object->IterateBody(map->instance_type(), size, v); |
3320 } | 3297 } |
3321 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { | 3298 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list != NULL) { |
3322 int new_region_start = SkipList::RegionNumber(free_end); | 3299 int new_region_start = SkipList::RegionNumber(free_end); |
3323 int new_region_end = | 3300 int new_region_end = |
3324 SkipList::RegionNumber(free_end + size - kPointerSize); | 3301 SkipList::RegionNumber(free_end + size - kPointerSize); |
3325 if (new_region_start != curr_region || new_region_end != curr_region) { | 3302 if (new_region_start != curr_region || new_region_end != curr_region) { |
3326 skip_list->AddObject(free_end, size); | 3303 skip_list->AddObject(free_end, size); |
3327 curr_region = new_region_end; | 3304 curr_region = new_region_end; |
3328 } | 3305 } |
3329 } | 3306 } |
3330 free_start = free_end + size; | 3307 free_start = free_end + size; |
3331 } | 3308 } |
3332 | 3309 |
3333 // Clear the mark bits of that page and reset live bytes count. | 3310 // Clear the mark bits of that page and reset live bytes count. |
3334 Bitmap::Clear(p); | 3311 Bitmap::Clear(p); |
3335 | 3312 |
3336 if (free_start != p->area_end()) { | 3313 if (free_start != p->area_end()) { |
3337 int size = static_cast<int>(p->area_end() - free_start); | 3314 int size = static_cast<int>(p->area_end() - free_start); |
3338 if (free_space_mode == ZAP_FREE_SPACE) { | 3315 if (free_space_mode == ZAP_FREE_SPACE) { |
3339 memset(free_start, 0xcc, size); | 3316 memset(free_start, 0xcc, size); |
3340 } | 3317 } |
3341 freed_bytes = Free<parallelism>(space, free_list, free_start, size); | 3318 freed_bytes = space->UnaccountedFree(free_start, size); |
3342 max_freed_bytes = Max(freed_bytes, max_freed_bytes); | 3319 max_freed_bytes = Max(freed_bytes, max_freed_bytes); |
3343 } | 3320 } |
3344 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | 3321 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); |
3345 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); | 3322 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); |
3346 } | 3323 } |
3347 | 3324 |
3348 | 3325 |
3349 void MarkCompactCollector::InvalidateCode(Code* code) { | 3326 void MarkCompactCollector::InvalidateCode(Code* code) { |
3350 if (heap_->incremental_marking()->IsCompacting() && | 3327 if (heap_->incremental_marking()->IsCompacting() && |
3351 !ShouldSkipEvacuationSlotRecording(code)) { | 3328 !ShouldSkipEvacuationSlotRecording(code)) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3446 void MarkCompactCollector::SweepAbortedPages() { | 3423 void MarkCompactCollector::SweepAbortedPages() { |
3447 // Second pass on aborted pages. | 3424 // Second pass on aborted pages. |
3448 for (Page* p : evacuation_candidates_) { | 3425 for (Page* p : evacuation_candidates_) { |
3449 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { | 3426 if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { |
3450 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED); | 3427 p->ClearFlag(MemoryChunk::COMPACTION_WAS_ABORTED); |
3451 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3428 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
3452 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3429 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
3453 switch (space->identity()) { | 3430 switch (space->identity()) { |
3454 case OLD_SPACE: | 3431 case OLD_SPACE: |
3455 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | 3432 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
3456 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr); | 3433 IGNORE_FREE_SPACE>(space, p, nullptr); |
3457 break; | 3434 break; |
3458 case CODE_SPACE: | 3435 case CODE_SPACE: |
3459 if (FLAG_zap_code_space) { | 3436 if (FLAG_zap_code_space) { |
3460 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 3437 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
3461 ZAP_FREE_SPACE>(space, NULL, p, nullptr); | 3438 ZAP_FREE_SPACE>(space, p, nullptr); |
3462 } else { | 3439 } else { |
3463 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 3440 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
3464 IGNORE_FREE_SPACE>(space, NULL, p, nullptr); | 3441 IGNORE_FREE_SPACE>(space, p, nullptr); |
3465 } | 3442 } |
3466 break; | 3443 break; |
3467 default: | 3444 default: |
3468 UNREACHABLE(); | 3445 UNREACHABLE(); |
3469 break; | 3446 break; |
3470 } | 3447 } |
| 3448 { |
| 3449 base::LockGuard<base::Mutex> guard(&swept_pages_mutex_); |
| 3450 swept_pages(space->identity())->Add(p); |
| 3451 } |
3471 } | 3452 } |
3472 } | 3453 } |
3473 } | 3454 } |
3474 | 3455 |
3475 | 3456 |
3476 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { | 3457 void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
3477 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_EVACUATE); | 3458 GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_EVACUATE); |
3478 Heap::RelocationLock relocation_lock(heap()); | 3459 Heap::RelocationLock relocation_lock(heap()); |
3479 | 3460 |
3480 { | 3461 { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3658 EvacuationWeakObjectRetainer evacuation_object_retainer; | 3639 EvacuationWeakObjectRetainer evacuation_object_retainer; |
3659 heap()->ProcessWeakListRoots(&evacuation_object_retainer); | 3640 heap()->ProcessWeakListRoots(&evacuation_object_retainer); |
3660 } | 3641 } |
3661 } | 3642 } |
3662 | 3643 |
3663 | 3644 |
3664 void MarkCompactCollector::ReleaseEvacuationCandidates() { | 3645 void MarkCompactCollector::ReleaseEvacuationCandidates() { |
3665 for (Page* p : evacuation_candidates_) { | 3646 for (Page* p : evacuation_candidates_) { |
3666 if (!p->IsEvacuationCandidate()) continue; | 3647 if (!p->IsEvacuationCandidate()) continue; |
3667 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3648 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
3668 space->Free(p->area_start(), p->area_size()); | |
3669 p->ResetLiveBytes(); | 3649 p->ResetLiveBytes(); |
3670 CHECK(p->SweepingDone()); | 3650 CHECK(p->SweepingDone()); |
3671 space->ReleasePage(p, true); | 3651 space->ReleasePage(p); |
3672 } | 3652 } |
3673 evacuation_candidates_.Rewind(0); | 3653 evacuation_candidates_.Rewind(0); |
3674 compacting_ = false; | 3654 compacting_ = false; |
3675 heap()->FreeQueuedChunks(); | 3655 heap()->FreeQueuedChunks(); |
3676 } | 3656 } |
3677 | 3657 |
3678 | 3658 |
3679 int MarkCompactCollector::SweepInParallel(PagedSpace* space, | 3659 int MarkCompactCollector::SweepInParallel(PagedSpace* space, |
3680 int required_freed_bytes, | 3660 int required_freed_bytes, |
3681 int max_pages) { | 3661 int max_pages) { |
(...skipping 18 matching lines...) Expand all Loading... |
3700 | 3680 |
3701 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { | 3681 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { |
3702 int max_freed = 0; | 3682 int max_freed = 0; |
3703 if (page->mutex()->TryLock()) { | 3683 if (page->mutex()->TryLock()) { |
3704 // If this page was already swept in the meantime, we can return here. | 3684 // If this page was already swept in the meantime, we can return here. |
3705 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) { | 3685 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) { |
3706 page->mutex()->Unlock(); | 3686 page->mutex()->Unlock(); |
3707 return 0; | 3687 return 0; |
3708 } | 3688 } |
3709 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3689 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
3710 FreeList* free_list; | |
3711 FreeList private_free_list(space); | |
3712 if (space->identity() == OLD_SPACE) { | 3690 if (space->identity() == OLD_SPACE) { |
3713 free_list = free_list_old_space_.get(); | 3691 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, |
3714 max_freed = | 3692 IGNORE_FREE_SPACE>(space, page, NULL); |
3715 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, | |
3716 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
3717 } else if (space->identity() == CODE_SPACE) { | 3693 } else if (space->identity() == CODE_SPACE) { |
3718 free_list = free_list_code_space_.get(); | 3694 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST, |
3719 max_freed = | 3695 IGNORE_FREE_SPACE>(space, page, NULL); |
3720 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST, | |
3721 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
3722 } else { | 3696 } else { |
3723 free_list = free_list_map_space_.get(); | 3697 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, |
3724 max_freed = | 3698 IGNORE_FREE_SPACE>(space, page, NULL); |
3725 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, | |
3726 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
3727 } | 3699 } |
3728 free_list->Concatenate(&private_free_list); | 3700 { |
| 3701 base::LockGuard<base::Mutex> guard(&swept_pages_mutex_); |
| 3702 swept_pages(space->identity())->Add(page); |
| 3703 } |
3729 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone); | 3704 page->concurrent_sweeping_state().SetValue(Page::kSweepingDone); |
3730 page->mutex()->Unlock(); | 3705 page->mutex()->Unlock(); |
3731 } | 3706 } |
3732 return max_freed; | 3707 return max_freed; |
3733 } | 3708 } |
3734 | 3709 |
3735 | 3710 |
3736 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { | 3711 void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
3737 space->ClearStats(); | 3712 space->ClearStats(); |
3738 | 3713 |
(...skipping 22 matching lines...) Expand all Loading... |
3761 continue; | 3736 continue; |
3762 } | 3737 } |
3763 | 3738 |
3764 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { | 3739 if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) { |
3765 // We need to sweep the page to get it into an iterable state again. Note | 3740 // We need to sweep the page to get it into an iterable state again. Note |
3766 // that this adds unusable memory into the free list that is later on | 3741 // that this adds unusable memory into the free list that is later on |
3767 // (in the free list) dropped again. Since we only use the flag for | 3742 // (in the free list) dropped again. Since we only use the flag for |
3768 // testing this is fine. | 3743 // testing this is fine. |
3769 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); | 3744 p->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); |
3770 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | 3745 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
3771 IGNORE_FREE_SPACE>(space, nullptr, p, nullptr); | 3746 IGNORE_FREE_SPACE>(space, p, nullptr); |
3772 continue; | 3747 continue; |
3773 } | 3748 } |
3774 | 3749 |
3775 // One unused page is kept, all further are released before sweeping them. | 3750 // One unused page is kept, all further are released before sweeping them. |
3776 if (p->LiveBytes() == 0) { | 3751 if (p->LiveBytes() == 0) { |
3777 if (unused_page_present) { | 3752 if (unused_page_present) { |
3778 if (FLAG_gc_verbose) { | 3753 if (FLAG_gc_verbose) { |
3779 PrintIsolate(isolate(), "sweeping: released page: %p", p); | 3754 PrintIsolate(isolate(), "sweeping: released page: %p", p); |
3780 } | 3755 } |
3781 space->ReleasePage(p, false); | 3756 space->ReleasePage(p); |
3782 continue; | 3757 continue; |
3783 } | 3758 } |
3784 unused_page_present = true; | 3759 unused_page_present = true; |
3785 } | 3760 } |
3786 | 3761 |
3787 p->concurrent_sweeping_state().SetValue(Page::kSweepingPending); | 3762 p->concurrent_sweeping_state().SetValue(Page::kSweepingPending); |
3788 sweeping_list(space).push_back(p); | 3763 sweeping_list(space).push_back(p); |
3789 int to_sweep = p->area_size() - p->LiveBytes(); | 3764 int to_sweep = p->area_size() - p->LiveBytes(); |
3790 space->accounting_stats_.ShrinkSpace(to_sweep); | 3765 space->accounting_stats_.ShrinkSpace(to_sweep); |
3791 will_be_swept++; | 3766 will_be_swept++; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3877 MarkBit mark_bit = Marking::MarkBitFrom(host); | 3852 MarkBit mark_bit = Marking::MarkBitFrom(host); |
3878 if (Marking::IsBlack(mark_bit)) { | 3853 if (Marking::IsBlack(mark_bit)) { |
3879 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); | 3854 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); |
3880 RecordRelocSlot(host, &rinfo, target); | 3855 RecordRelocSlot(host, &rinfo, target); |
3881 } | 3856 } |
3882 } | 3857 } |
3883 } | 3858 } |
3884 | 3859 |
3885 } // namespace internal | 3860 } // namespace internal |
3886 } // namespace v8 | 3861 } // namespace v8 |
OLD | NEW |