| 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/v8.h" | 5 #include "src/v8.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/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 VerifyEvacuation(heap->new_space()); | 219 VerifyEvacuation(heap->new_space()); |
| 220 | 220 |
| 221 VerifyEvacuationVisitor visitor; | 221 VerifyEvacuationVisitor visitor; |
| 222 heap->IterateStrongRoots(&visitor, VISIT_ALL); | 222 heap->IterateStrongRoots(&visitor, VISIT_ALL); |
| 223 } | 223 } |
| 224 #endif // VERIFY_HEAP | 224 #endif // VERIFY_HEAP |
| 225 | 225 |
| 226 | 226 |
| 227 void MarkCompactCollector::SetUp() { | 227 void MarkCompactCollector::SetUp() { |
| 228 free_list_old_space_.Reset(new FreeList(heap_->old_space())); | 228 free_list_old_space_.Reset(new FreeList(heap_->old_space())); |
| 229 free_list_code_space_.Reset(new FreeList(heap_->code_space())); | |
| 230 EnsureMarkingDequeIsReserved(); | 229 EnsureMarkingDequeIsReserved(); |
| 231 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); | 230 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); |
| 232 } | 231 } |
| 233 | 232 |
| 234 | 233 |
| 235 void MarkCompactCollector::TearDown() { | 234 void MarkCompactCollector::TearDown() { |
| 236 AbortCompaction(); | 235 AbortCompaction(); |
| 237 delete marking_deque_memory_; | 236 delete marking_deque_memory_; |
| 238 } | 237 } |
| 239 | 238 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 ClearInvalidStoreAndSlotsBufferEntries(); | 359 ClearInvalidStoreAndSlotsBufferEntries(); |
| 361 | 360 |
| 362 #ifdef VERIFY_HEAP | 361 #ifdef VERIFY_HEAP |
| 363 if (FLAG_verify_heap) { | 362 if (FLAG_verify_heap) { |
| 364 VerifyValidStoreAndSlotsBufferEntries(heap_); | 363 VerifyValidStoreAndSlotsBufferEntries(heap_); |
| 365 } | 364 } |
| 366 #endif | 365 #endif |
| 367 | 366 |
| 368 SweepSpaces(); | 367 SweepSpaces(); |
| 369 | 368 |
| 369 #ifdef VERIFY_HEAP |
| 370 VerifyWeakEmbeddedObjectsInCode(); |
| 371 if (FLAG_omit_map_checks_for_leaf_maps) { |
| 372 VerifyOmittedMapChecks(); |
| 373 } |
| 374 #endif |
| 375 |
| 370 Finish(); | 376 Finish(); |
| 371 | 377 |
| 372 if (marking_parity_ == EVEN_MARKING_PARITY) { | 378 if (marking_parity_ == EVEN_MARKING_PARITY) { |
| 373 marking_parity_ = ODD_MARKING_PARITY; | 379 marking_parity_ = ODD_MARKING_PARITY; |
| 374 } else { | 380 } else { |
| 375 DCHECK(marking_parity_ == ODD_MARKING_PARITY); | 381 DCHECK(marking_parity_ == ODD_MARKING_PARITY); |
| 376 marking_parity_ = EVEN_MARKING_PARITY; | 382 marking_parity_ = EVEN_MARKING_PARITY; |
| 377 } | 383 } |
| 378 } | 384 } |
| 379 | 385 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 | 492 |
| 487 Heap* heap_; | 493 Heap* heap_; |
| 488 PagedSpace* space_; | 494 PagedSpace* space_; |
| 489 | 495 |
| 490 DISALLOW_COPY_AND_ASSIGN(SweeperTask); | 496 DISALLOW_COPY_AND_ASSIGN(SweeperTask); |
| 491 }; | 497 }; |
| 492 | 498 |
| 493 | 499 |
| 494 void MarkCompactCollector::StartSweeperThreads() { | 500 void MarkCompactCollector::StartSweeperThreads() { |
| 495 DCHECK(free_list_old_space_.get()->IsEmpty()); | 501 DCHECK(free_list_old_space_.get()->IsEmpty()); |
| 496 DCHECK(free_list_code_space_.get()->IsEmpty()); | |
| 497 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 502 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 498 new SweeperTask(heap(), heap()->old_space()), | 503 new SweeperTask(heap(), heap()->old_space()), |
| 499 v8::Platform::kShortRunningTask); | 504 v8::Platform::kShortRunningTask); |
| 500 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
| 501 new SweeperTask(heap(), heap()->code_space()), | |
| 502 v8::Platform::kShortRunningTask); | |
| 503 } | 505 } |
| 504 | 506 |
| 505 | 507 |
| 506 void MarkCompactCollector::EnsureSweepingCompleted() { | 508 void MarkCompactCollector::EnsureSweepingCompleted() { |
| 507 DCHECK(sweeping_in_progress_ == true); | 509 DCHECK(sweeping_in_progress_ == true); |
| 508 | 510 |
| 509 // If sweeping is not completed or not running at all, we try to complete it | 511 // If sweeping is not completed or not running at all, we try to complete it |
| 510 // here. | 512 // here. |
| 511 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { | 513 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { |
| 512 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); | 514 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); |
| 513 SweepInParallel(heap()->paged_space(CODE_SPACE), 0); | |
| 514 } | 515 } |
| 515 // Wait twice for both jobs. | 516 // Wait twice for both jobs. |
| 516 if (heap()->concurrent_sweeping_enabled()) { | 517 if (heap()->concurrent_sweeping_enabled()) { |
| 517 pending_sweeper_jobs_semaphore_.Wait(); | 518 pending_sweeper_jobs_semaphore_.Wait(); |
| 518 pending_sweeper_jobs_semaphore_.Wait(); | |
| 519 } | 519 } |
| 520 ParallelSweepSpacesComplete(); | 520 ParallelSweepSpacesComplete(); |
| 521 sweeping_in_progress_ = false; | 521 sweeping_in_progress_ = false; |
| 522 RefillFreeList(heap()->paged_space(OLD_SPACE)); | 522 RefillFreeList(heap()->paged_space(OLD_SPACE)); |
| 523 RefillFreeList(heap()->paged_space(CODE_SPACE)); | |
| 524 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); | 523 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); |
| 525 heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes(); | |
| 526 | 524 |
| 527 #ifdef VERIFY_HEAP | 525 #ifdef VERIFY_HEAP |
| 528 if (FLAG_verify_heap && !evacuation()) { | 526 if (FLAG_verify_heap && !evacuation()) { |
| 529 VerifyEvacuation(heap_); | 527 VerifyEvacuation(heap_); |
| 530 } | 528 } |
| 531 #endif | 529 #endif |
| 532 } | 530 } |
| 533 | 531 |
| 534 | 532 |
| 535 bool MarkCompactCollector::IsSweepingCompleted() { | 533 bool MarkCompactCollector::IsSweepingCompleted() { |
| 536 if (!pending_sweeper_jobs_semaphore_.WaitFor( | 534 if (!pending_sweeper_jobs_semaphore_.WaitFor( |
| 537 base::TimeDelta::FromSeconds(0))) { | 535 base::TimeDelta::FromSeconds(0))) { |
| 538 return false; | 536 return false; |
| 539 } | 537 } |
| 540 pending_sweeper_jobs_semaphore_.Signal(); | 538 pending_sweeper_jobs_semaphore_.Signal(); |
| 541 return true; | 539 return true; |
| 542 } | 540 } |
| 543 | 541 |
| 544 | 542 |
| 545 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { | 543 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { |
| 546 FreeList* free_list; | 544 FreeList* free_list; |
| 547 | 545 |
| 548 if (space == heap()->old_space()) { | 546 if (space == heap()->old_space()) { |
| 549 free_list = free_list_old_space_.get(); | 547 free_list = free_list_old_space_.get(); |
| 550 } else if (space == heap()->code_space()) { | |
| 551 free_list = free_list_code_space_.get(); | |
| 552 } else { | 548 } else { |
| 553 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure | 549 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure |
| 554 // to only refill them for the old space. | 550 // to only refill them for the old space. |
| 555 return; | 551 return; |
| 556 } | 552 } |
| 557 | 553 |
| 558 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); | 554 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); |
| 559 space->AddToAccountingStats(freed_bytes); | 555 space->AddToAccountingStats(freed_bytes); |
| 560 space->DecrementUnsweptFreeBytes(freed_bytes); | 556 space->DecrementUnsweptFreeBytes(freed_bytes); |
| 561 } | 557 } |
| (...skipping 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, | 3490 DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST, |
| 3495 space->identity() == CODE_SPACE); | 3491 space->identity() == CODE_SPACE); |
| 3496 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); | 3492 DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST)); |
| 3497 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || | 3493 DCHECK(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD || |
| 3498 sweeping_mode == SWEEP_ONLY); | 3494 sweeping_mode == SWEEP_ONLY); |
| 3499 | 3495 |
| 3500 Address free_start = p->area_start(); | 3496 Address free_start = p->area_start(); |
| 3501 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); | 3497 DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| 3502 int offsets[16]; | 3498 int offsets[16]; |
| 3503 | 3499 |
| 3504 // If we use the skip list for code space pages, we have to lock the skip | |
| 3505 // list because it could be accessed concurrently by the runtime or the | |
| 3506 // deoptimizer. | |
| 3507 bool skip_list_locked = false; | |
| 3508 SkipList* skip_list = p->skip_list(); | 3500 SkipList* skip_list = p->skip_list(); |
| 3501 int curr_region = -1; |
| 3509 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { | 3502 if ((skip_list_mode == REBUILD_SKIP_LIST) && skip_list) { |
| 3510 skip_list->Lock(); | |
| 3511 skip_list_locked = true; | |
| 3512 skip_list->Clear(); | 3503 skip_list->Clear(); |
| 3513 } | 3504 } |
| 3514 | 3505 |
| 3515 intptr_t freed_bytes = 0; | 3506 intptr_t freed_bytes = 0; |
| 3516 intptr_t max_freed_bytes = 0; | 3507 intptr_t max_freed_bytes = 0; |
| 3517 int curr_region = -1; | |
| 3518 | 3508 |
| 3519 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 3509 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 3520 Address cell_base = it.CurrentCellBase(); | 3510 Address cell_base = it.CurrentCellBase(); |
| 3521 MarkBit::CellType* cell = it.CurrentCell(); | 3511 MarkBit::CellType* cell = it.CurrentCell(); |
| 3522 int live_objects = MarkWordToObjectStarts(*cell, offsets); | 3512 int live_objects = MarkWordToObjectStarts(*cell, offsets); |
| 3523 int live_index = 0; | 3513 int live_index = 0; |
| 3524 for (; live_objects != 0; live_objects--) { | 3514 for (; live_objects != 0; live_objects--) { |
| 3525 Address free_end = cell_base + offsets[live_index++] * kPointerSize; | 3515 Address free_end = cell_base + offsets[live_index++] * kPointerSize; |
| 3526 if (free_end != free_start) { | 3516 if (free_end != free_start) { |
| 3527 int size = static_cast<int>(free_end - free_start); | 3517 int size = static_cast<int>(free_end - free_start); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3562 } | 3552 } |
| 3563 p->ResetLiveBytes(); | 3553 p->ResetLiveBytes(); |
| 3564 | 3554 |
| 3565 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) { | 3555 if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) { |
| 3566 // When concurrent sweeping is active, the page will be marked after | 3556 // When concurrent sweeping is active, the page will be marked after |
| 3567 // sweeping by the main thread. | 3557 // sweeping by the main thread. |
| 3568 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); | 3558 p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE); |
| 3569 } else { | 3559 } else { |
| 3570 p->SetWasSwept(); | 3560 p->SetWasSwept(); |
| 3571 } | 3561 } |
| 3572 if (skip_list_locked) { | |
| 3573 DCHECK(skip_list && skip_list_mode == REBUILD_SKIP_LIST); | |
| 3574 skip_list->Unlock(); | |
| 3575 } | |
| 3576 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); | 3562 return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes)); |
| 3577 } | 3563 } |
| 3578 | 3564 |
| 3579 | 3565 |
| 3580 // Return true if the given code is deoptimized or will be deoptimized. | 3566 // Return true if the given code is deoptimized or will be deoptimized. |
| 3581 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { | 3567 bool MarkCompactCollector::WillBeDeoptimized(Code* code) { |
| 3582 return code->is_optimized_code() && code->marked_for_deoptimization(); | 3568 return code->is_optimized_code() && code->marked_for_deoptimization(); |
| 3583 } | 3569 } |
| 3584 | 3570 |
| 3585 | 3571 |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4175 max_freed_overall = Max(max_freed, max_freed_overall); | 4161 max_freed_overall = Max(max_freed, max_freed_overall); |
| 4176 if (p == space->end_of_unswept_pages()) break; | 4162 if (p == space->end_of_unswept_pages()) break; |
| 4177 } | 4163 } |
| 4178 return max_freed_overall; | 4164 return max_freed_overall; |
| 4179 } | 4165 } |
| 4180 | 4166 |
| 4181 | 4167 |
| 4182 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { | 4168 int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) { |
| 4183 int max_freed = 0; | 4169 int max_freed = 0; |
| 4184 if (page->TryParallelSweeping()) { | 4170 if (page->TryParallelSweeping()) { |
| 4185 FreeList* free_list; | 4171 FreeList* free_list = free_list_old_space_.get(); |
| 4186 FreeList private_free_list(space); | 4172 FreeList private_free_list(space); |
| 4187 if (space->identity() == CODE_SPACE) { | 4173 max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, |
| 4188 free_list = free_list_code_space_.get(); | 4174 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); |
| 4189 max_freed = | |
| 4190 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST, | |
| 4191 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
| 4192 } else { | |
| 4193 free_list = free_list_old_space_.get(); | |
| 4194 max_freed = | |
| 4195 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, | |
| 4196 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); | |
| 4197 } | |
| 4198 free_list->Concatenate(&private_free_list); | 4175 free_list->Concatenate(&private_free_list); |
| 4199 } | 4176 } |
| 4200 return max_freed; | 4177 return max_freed; |
| 4201 } | 4178 } |
| 4202 | 4179 |
| 4203 | 4180 |
| 4204 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { | 4181 void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
| 4205 space->ClearStats(); | 4182 space->ClearStats(); |
| 4206 | 4183 |
| 4207 // We defensively initialize end_of_unswept_pages_ here with the first page | 4184 // We defensively initialize end_of_unswept_pages_ here with the first page |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4244 unused_page_present = true; | 4221 unused_page_present = true; |
| 4245 } | 4222 } |
| 4246 | 4223 |
| 4247 switch (sweeper) { | 4224 switch (sweeper) { |
| 4248 case CONCURRENT_SWEEPING: | 4225 case CONCURRENT_SWEEPING: |
| 4249 if (!parallel_sweeping_active) { | 4226 if (!parallel_sweeping_active) { |
| 4250 if (FLAG_gc_verbose) { | 4227 if (FLAG_gc_verbose) { |
| 4251 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", | 4228 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", |
| 4252 reinterpret_cast<intptr_t>(p)); | 4229 reinterpret_cast<intptr_t>(p)); |
| 4253 } | 4230 } |
| 4254 if (space->identity() == CODE_SPACE) { | 4231 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
| 4255 if (FLAG_zap_code_space) { | 4232 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4256 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | |
| 4257 ZAP_FREE_SPACE>(space, NULL, p, NULL); | |
| 4258 } else { | |
| 4259 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | |
| 4260 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4261 } | |
| 4262 } else { | |
| 4263 DCHECK(space->identity() == OLD_SPACE); | |
| 4264 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | |
| 4265 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4266 } | |
| 4267 pages_swept++; | 4233 pages_swept++; |
| 4268 parallel_sweeping_active = true; | 4234 parallel_sweeping_active = true; |
| 4269 } else { | 4235 } else { |
| 4270 if (FLAG_gc_verbose) { | 4236 if (FLAG_gc_verbose) { |
| 4271 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", | 4237 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", |
| 4272 reinterpret_cast<intptr_t>(p)); | 4238 reinterpret_cast<intptr_t>(p)); |
| 4273 } | 4239 } |
| 4274 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING); | 4240 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING); |
| 4275 space->IncreaseUnsweptFreeBytes(p); | 4241 space->IncreaseUnsweptFreeBytes(p); |
| 4276 } | 4242 } |
| 4277 space->set_end_of_unswept_pages(p); | 4243 space->set_end_of_unswept_pages(p); |
| 4278 break; | 4244 break; |
| 4279 case SEQUENTIAL_SWEEPING: { | 4245 case SEQUENTIAL_SWEEPING: { |
| 4280 if (FLAG_gc_verbose) { | 4246 if (FLAG_gc_verbose) { |
| 4281 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); | 4247 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); |
| 4282 } | 4248 } |
| 4283 if (space->identity() == CODE_SPACE) { | 4249 if (space->identity() == CODE_SPACE && FLAG_zap_code_space) { |
| 4284 if (FLAG_zap_code_space) { | 4250 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
| 4285 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 4251 ZAP_FREE_SPACE>(space, NULL, p, NULL); |
| 4286 ZAP_FREE_SPACE>(space, NULL, p, NULL); | 4252 } else if (space->identity() == CODE_SPACE) { |
| 4287 } else { | 4253 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
| 4288 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 4254 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4289 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | |
| 4290 } | |
| 4291 } else { | 4255 } else { |
| 4292 DCHECK(space->identity() == OLD_SPACE || | |
| 4293 space->identity() == MAP_SPACE); | |
| 4294 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, | 4256 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, |
| 4295 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | 4257 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4296 } | 4258 } |
| 4297 pages_swept++; | 4259 pages_swept++; |
| 4298 break; | 4260 break; |
| 4299 } | 4261 } |
| 4300 default: { UNREACHABLE(); } | 4262 default: { UNREACHABLE(); } |
| 4301 } | 4263 } |
| 4302 } | 4264 } |
| 4303 | 4265 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4323 #endif | 4285 #endif |
| 4324 | 4286 |
| 4325 MoveEvacuationCandidatesToEndOfPagesList(); | 4287 MoveEvacuationCandidatesToEndOfPagesList(); |
| 4326 | 4288 |
| 4327 // Noncompacting collections simply sweep the spaces to clear the mark | 4289 // Noncompacting collections simply sweep the spaces to clear the mark |
| 4328 // bits and free the nonlive blocks (for old and map spaces). We sweep | 4290 // bits and free the nonlive blocks (for old and map spaces). We sweep |
| 4329 // the map space last because freeing non-live maps overwrites them and | 4291 // the map space last because freeing non-live maps overwrites them and |
| 4330 // the other spaces rely on possibly non-live maps to get the sizes for | 4292 // the other spaces rely on possibly non-live maps to get the sizes for |
| 4331 // non-live objects. | 4293 // non-live objects. |
| 4332 { | 4294 { |
| 4333 { | 4295 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4334 GCTracer::Scope sweep_scope(heap()->tracer(), | 4296 GCTracer::Scope::MC_SWEEP_OLDSPACE); |
| 4335 GCTracer::Scope::MC_SWEEP_OLDSPACE); | 4297 { SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); } |
| 4336 SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); | |
| 4337 } | |
| 4338 { | |
| 4339 GCTracer::Scope sweep_scope(heap()->tracer(), | |
| 4340 GCTracer::Scope::MC_SWEEP_CODE); | |
| 4341 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); | |
| 4342 } | |
| 4343 | |
| 4344 sweeping_in_progress_ = true; | 4298 sweeping_in_progress_ = true; |
| 4345 if (heap()->concurrent_sweeping_enabled()) { | 4299 if (heap()->concurrent_sweeping_enabled()) { |
| 4346 StartSweeperThreads(); | 4300 StartSweeperThreads(); |
| 4347 } | 4301 } |
| 4348 } | 4302 } |
| 4303 { |
| 4304 GCTracer::Scope sweep_scope(heap()->tracer(), |
| 4305 GCTracer::Scope::MC_SWEEP_CODE); |
| 4306 SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING); |
| 4307 } |
| 4349 | 4308 |
| 4350 EvacuateNewSpaceAndCandidates(); | 4309 EvacuateNewSpaceAndCandidates(); |
| 4351 | 4310 |
| 4352 heap()->FreeDeadArrayBuffers(false); | 4311 heap()->FreeDeadArrayBuffers(false); |
| 4353 | 4312 |
| 4354 // ClearNonLiveReferences depends on precise sweeping of map space to | 4313 // ClearNonLiveReferences depends on precise sweeping of map space to |
| 4355 // detect whether unmarked map became dead in this collection or in one | 4314 // detect whether unmarked map became dead in this collection or in one |
| 4356 // of the previous ones. | 4315 // of the previous ones. |
| 4357 { | 4316 { |
| 4358 GCTracer::Scope sweep_scope(heap()->tracer(), | 4317 GCTracer::Scope sweep_scope(heap()->tracer(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4391 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); | 4350 p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE); |
| 4392 p->SetWasSwept(); | 4351 p->SetWasSwept(); |
| 4393 } | 4352 } |
| 4394 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); | 4353 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); |
| 4395 } | 4354 } |
| 4396 } | 4355 } |
| 4397 | 4356 |
| 4398 | 4357 |
| 4399 void MarkCompactCollector::ParallelSweepSpacesComplete() { | 4358 void MarkCompactCollector::ParallelSweepSpacesComplete() { |
| 4400 ParallelSweepSpaceComplete(heap()->old_space()); | 4359 ParallelSweepSpaceComplete(heap()->old_space()); |
| 4401 ParallelSweepSpaceComplete(heap()->code_space()); | |
| 4402 } | 4360 } |
| 4403 | 4361 |
| 4404 | 4362 |
| 4405 void MarkCompactCollector::EnableCodeFlushing(bool enable) { | 4363 void MarkCompactCollector::EnableCodeFlushing(bool enable) { |
| 4406 if (isolate()->debug()->is_loaded() || | 4364 if (isolate()->debug()->is_loaded() || |
| 4407 isolate()->debug()->has_break_points()) { | 4365 isolate()->debug()->has_break_points()) { |
| 4408 enable = false; | 4366 enable = false; |
| 4409 } | 4367 } |
| 4410 | 4368 |
| 4411 if (enable) { | 4369 if (enable) { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4695 SlotsBuffer* buffer = *buffer_address; | 4653 SlotsBuffer* buffer = *buffer_address; |
| 4696 while (buffer != NULL) { | 4654 while (buffer != NULL) { |
| 4697 SlotsBuffer* next_buffer = buffer->next(); | 4655 SlotsBuffer* next_buffer = buffer->next(); |
| 4698 DeallocateBuffer(buffer); | 4656 DeallocateBuffer(buffer); |
| 4699 buffer = next_buffer; | 4657 buffer = next_buffer; |
| 4700 } | 4658 } |
| 4701 *buffer_address = NULL; | 4659 *buffer_address = NULL; |
| 4702 } | 4660 } |
| 4703 } // namespace internal | 4661 } // namespace internal |
| 4704 } // namespace v8 | 4662 } // namespace v8 |
| OLD | NEW |