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

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

Issue 2418773002: [heap] Move slot filtering logic into sweeper. (Closed)
Patch Set: remove prefree mode Created 4 years, 2 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 | « no previous file | src/heap/remembered-set.h » ('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 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 3301 matching lines...) Expand 10 before | Expand all | Expand 10 after
3312 } 3312 }
3313 } 3313 }
3314 return object; 3314 return object;
3315 } 3315 }
3316 }; 3316 };
3317 3317
3318 int MarkCompactCollector::Sweeper::RawSweep( 3318 int MarkCompactCollector::Sweeper::RawSweep(
3319 Page* p, FreeListRebuildingMode free_list_mode, 3319 Page* p, FreeListRebuildingMode free_list_mode,
3320 FreeSpaceTreatmentMode free_space_mode) { 3320 FreeSpaceTreatmentMode free_space_mode) {
3321 Space* space = p->owner(); 3321 Space* space = p->owner();
3322 AllocationSpace identity = space->identity();
3322 DCHECK_NOT_NULL(space); 3323 DCHECK_NOT_NULL(space);
3323 DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || 3324 DCHECK(free_list_mode == IGNORE_FREE_LIST || identity == OLD_SPACE ||
3324 space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); 3325 identity == CODE_SPACE || identity == MAP_SPACE);
3325 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); 3326 DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
3326 3327
3327 // Before we sweep objects on the page, we free dead array buffers which 3328 // Before we sweep objects on the page, we free dead array buffers which
3328 // requires valid mark bits. 3329 // requires valid mark bits.
3329 ArrayBufferTracker::FreeDead(p); 3330 ArrayBufferTracker::FreeDead(p);
3330 3331
3331 // We also release the black area markers here. 3332 // We also release the black area markers here.
3332 p->ReleaseBlackAreaEndMarkerMap(); 3333 p->ReleaseBlackAreaEndMarkerMap();
3333 3334
3334 Address free_start = p->area_start(); 3335 Address free_start = p->area_start();
3335 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); 3336 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
3336 3337
3337 // If we use the skip list for code space pages, we have to lock the skip 3338 // If we use the skip list for code space pages, we have to lock the skip
3338 // list because it could be accessed concurrently by the runtime or the 3339 // list because it could be accessed concurrently by the runtime or the
3339 // deoptimizer. 3340 // deoptimizer.
3340 const bool rebuild_skip_list = 3341 const bool rebuild_skip_list =
3341 space->identity() == CODE_SPACE && p->skip_list() != nullptr; 3342 space->identity() == CODE_SPACE && p->skip_list() != nullptr;
3342 SkipList* skip_list = p->skip_list(); 3343 SkipList* skip_list = p->skip_list();
3343 if (rebuild_skip_list) { 3344 if (rebuild_skip_list) {
3344 skip_list->Clear(); 3345 skip_list->Clear();
3345 } 3346 }
3346 3347
3347 intptr_t freed_bytes = 0; 3348 intptr_t freed_bytes = 0;
3348 intptr_t max_freed_bytes = 0; 3349 intptr_t max_freed_bytes = 0;
3349 int curr_region = -1; 3350 int curr_region = -1;
3350 3351
3351 LiveObjectIterator<kBlackObjects> it(p); 3352 LiveObjectIterator<kBlackObjects> it(p);
3352 HeapObject* object = NULL; 3353 HeapObject* object = NULL;
3354 bool clear_slots =
3355 p->old_to_new_slots() && (identity == OLD_SPACE || identity == MAP_SPACE);
3353 while ((object = it.Next()) != NULL) { 3356 while ((object = it.Next()) != NULL) {
3354 DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); 3357 DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object)));
3355 Address free_end = object->address(); 3358 Address free_end = object->address();
3356 if (free_end != free_start) { 3359 if (free_end != free_start) {
3357 int size = static_cast<int>(free_end - free_start); 3360 int size = static_cast<int>(free_end - free_start);
3358 if (free_space_mode == ZAP_FREE_SPACE) { 3361 if (free_space_mode == ZAP_FREE_SPACE) {
3359 memset(free_start, 0xcc, size); 3362 memset(free_start, 0xcc, size);
3360 } 3363 }
3361 if (free_list_mode == REBUILD_FREE_LIST) { 3364 if (free_list_mode == REBUILD_FREE_LIST) {
3362 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree( 3365 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree(
3363 free_start, size); 3366 free_start, size);
3364 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3367 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3365 } else { 3368 } else {
3366 p->heap()->CreateFillerObjectAt(free_start, size, 3369 p->heap()->CreateFillerObjectAt(free_start, size,
3367 ClearRecordedSlots::kNo); 3370 ClearRecordedSlots::kNo);
3368 } 3371 }
3372
3373 if (clear_slots) {
3374 RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, free_end,
3375 SlotSet::KEEP_EMPTY_BUCKETS);
3376 }
3369 } 3377 }
3370 Map* map = object->synchronized_map(); 3378 Map* map = object->synchronized_map();
3371 int size = object->SizeFromMap(map); 3379 int size = object->SizeFromMap(map);
3372 if (rebuild_skip_list) { 3380 if (rebuild_skip_list) {
3373 int new_region_start = SkipList::RegionNumber(free_end); 3381 int new_region_start = SkipList::RegionNumber(free_end);
3374 int new_region_end = 3382 int new_region_end =
3375 SkipList::RegionNumber(free_end + size - kPointerSize); 3383 SkipList::RegionNumber(free_end + size - kPointerSize);
3376 if (new_region_start != curr_region || new_region_end != curr_region) { 3384 if (new_region_start != curr_region || new_region_end != curr_region) {
3377 skip_list->AddObject(free_end, size); 3385 skip_list->AddObject(free_end, size);
3378 curr_region = new_region_end; 3386 curr_region = new_region_end;
3379 } 3387 }
3380 } 3388 }
3381 free_start = free_end + size; 3389 free_start = free_end + size;
3382 } 3390 }
3383 3391
3384 // Clear the mark bits of that page and reset live bytes count.
3385 p->ClearLiveness();
3386
3387 if (free_start != p->area_end()) { 3392 if (free_start != p->area_end()) {
3388 int size = static_cast<int>(p->area_end() - free_start); 3393 int size = static_cast<int>(p->area_end() - free_start);
3389 if (free_space_mode == ZAP_FREE_SPACE) { 3394 if (free_space_mode == ZAP_FREE_SPACE) {
3390 memset(free_start, 0xcc, size); 3395 memset(free_start, 0xcc, size);
3391 } 3396 }
3392 if (free_list_mode == REBUILD_FREE_LIST) { 3397 if (free_list_mode == REBUILD_FREE_LIST) {
3393 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree( 3398 freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree(
3394 free_start, size); 3399 free_start, size);
3395 max_freed_bytes = Max(freed_bytes, max_freed_bytes); 3400 max_freed_bytes = Max(freed_bytes, max_freed_bytes);
3396 } else { 3401 } else {
3397 p->heap()->CreateFillerObjectAt(free_start, size, 3402 p->heap()->CreateFillerObjectAt(free_start, size,
3398 ClearRecordedSlots::kNo); 3403 ClearRecordedSlots::kNo);
3399 } 3404 }
3405
3406 if (clear_slots) {
3407 RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, p->area_end(),
3408 SlotSet::KEEP_EMPTY_BUCKETS);
3409 }
3400 } 3410 }
3411
3412 // Clear the mark bits of that page and reset live bytes count.
3413 p->ClearLiveness();
3414
3401 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone); 3415 p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
3402 if (free_list_mode == IGNORE_FREE_LIST) return 0; 3416 if (free_list_mode == IGNORE_FREE_LIST) return 0;
3403 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); 3417 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
3404 } 3418 }
3405 3419
3406 void MarkCompactCollector::InvalidateCode(Code* code) { 3420 void MarkCompactCollector::InvalidateCode(Code* code) {
3407 Page* page = Page::FromAddress(code->address()); 3421 Page* page = Page::FromAddress(code->address());
3408 Address start = code->instruction_start(); 3422 Address start = code->instruction_start();
3409 Address end = code->address() + code->Size(); 3423 Address end = code->address() + code->Size();
3410 3424
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
3806 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) { 3820 if (page->concurrent_sweeping_state().Value() != Page::kSweepingPending) {
3807 page->mutex()->Unlock(); 3821 page->mutex()->Unlock();
3808 return 0; 3822 return 0;
3809 } 3823 }
3810 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress); 3824 page->concurrent_sweeping_state().SetValue(Page::kSweepingInProgress);
3811 const Sweeper::FreeSpaceTreatmentMode free_space_mode = 3825 const Sweeper::FreeSpaceTreatmentMode free_space_mode =
3812 Heap::ShouldZapGarbage() ? ZAP_FREE_SPACE : IGNORE_FREE_SPACE; 3826 Heap::ShouldZapGarbage() ? ZAP_FREE_SPACE : IGNORE_FREE_SPACE;
3813 if (identity == NEW_SPACE) { 3827 if (identity == NEW_SPACE) {
3814 RawSweep(page, IGNORE_FREE_LIST, free_space_mode); 3828 RawSweep(page, IGNORE_FREE_LIST, free_space_mode);
3815 } else { 3829 } else {
3816 if (identity == OLD_SPACE || identity == MAP_SPACE) { 3830 if (identity == CODE_SPACE) {
3817 RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(heap_, page);
3818 } else {
3819 RememberedSet<OLD_TO_NEW>::ClearInvalidTypedSlots(heap_, page); 3831 RememberedSet<OLD_TO_NEW>::ClearInvalidTypedSlots(heap_, page);
3820 } 3832 }
3821 max_freed = RawSweep(page, REBUILD_FREE_LIST, free_space_mode); 3833 max_freed = RawSweep(page, REBUILD_FREE_LIST, free_space_mode);
3822 } 3834 }
3823 3835
3824 // After finishing sweeping of a page we clean up its remembered set. 3836 // After finishing sweeping of a page we clean up its remembered set.
3825 if (page->typed_old_to_new_slots()) { 3837 if (page->typed_old_to_new_slots()) {
3826 page->typed_old_to_new_slots()->FreeToBeFreedChunks(); 3838 page->typed_old_to_new_slots()->FreeToBeFreedChunks();
3827 } 3839 }
3828 if (page->old_to_new_slots()) { 3840 if (page->old_to_new_slots()) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3996 // The target is always in old space, we don't have to record the slot in 4008 // The target is always in old space, we don't have to record the slot in
3997 // the old-to-new remembered set. 4009 // the old-to-new remembered set.
3998 DCHECK(!heap()->InNewSpace(target)); 4010 DCHECK(!heap()->InNewSpace(target));
3999 RecordRelocSlot(host, &rinfo, target); 4011 RecordRelocSlot(host, &rinfo, target);
4000 } 4012 }
4001 } 4013 }
4002 } 4014 }
4003 4015
4004 } // namespace internal 4016 } // namespace internal
4005 } // namespace v8 4017 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/heap/remembered-set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698