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

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

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

Powered by Google App Engine
This is Rietveld 408576698