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

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

Issue 1226773003: Sweep map space concurrently. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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 | « src/heap/mark-compact.h ('k') | no next file » | 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/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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
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())); 229 free_list_code_space_.Reset(new FreeList(heap_->code_space()));
230 free_list_map_space_.Reset(new FreeList(heap_->map_space()));
230 EnsureMarkingDequeIsReserved(); 231 EnsureMarkingDequeIsReserved();
231 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize); 232 EnsureMarkingDequeIsCommitted(kMinMarkingDequeSize);
232 } 233 }
233 234
234 235
235 void MarkCompactCollector::TearDown() { 236 void MarkCompactCollector::TearDown() {
236 AbortCompaction(); 237 AbortCompaction();
237 delete marking_deque_memory_; 238 delete marking_deque_memory_;
238 } 239 }
239 240
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 Heap* heap_; 490 Heap* heap_;
490 PagedSpace* space_; 491 PagedSpace* space_;
491 492
492 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 493 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
493 }; 494 };
494 495
495 496
496 void MarkCompactCollector::StartSweeperThreads() { 497 void MarkCompactCollector::StartSweeperThreads() {
497 DCHECK(free_list_old_space_.get()->IsEmpty()); 498 DCHECK(free_list_old_space_.get()->IsEmpty());
498 DCHECK(free_list_code_space_.get()->IsEmpty()); 499 DCHECK(free_list_code_space_.get()->IsEmpty());
500 DCHECK(free_list_map_space_.get()->IsEmpty());
499 V8::GetCurrentPlatform()->CallOnBackgroundThread( 501 V8::GetCurrentPlatform()->CallOnBackgroundThread(
500 new SweeperTask(heap(), heap()->old_space()), 502 new SweeperTask(heap(), heap()->old_space()),
501 v8::Platform::kShortRunningTask); 503 v8::Platform::kShortRunningTask);
502 V8::GetCurrentPlatform()->CallOnBackgroundThread( 504 V8::GetCurrentPlatform()->CallOnBackgroundThread(
503 new SweeperTask(heap(), heap()->code_space()), 505 new SweeperTask(heap(), heap()->code_space()),
504 v8::Platform::kShortRunningTask); 506 v8::Platform::kShortRunningTask);
507 V8::GetCurrentPlatform()->CallOnBackgroundThread(
508 new SweeperTask(heap(), heap()->map_space()),
509 v8::Platform::kShortRunningTask);
505 } 510 }
506 511
507 512
508 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) { 513 void MarkCompactCollector::SweepOrWaitUntilSweepingCompleted(Page* page) {
509 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner()); 514 PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
510 if (!page->SweepingCompleted()) { 515 if (!page->SweepingCompleted()) {
511 SweepInParallel(page, owner); 516 SweepInParallel(page, owner);
512 if (!page->SweepingCompleted()) { 517 if (!page->SweepingCompleted()) {
513 // We were not able to sweep that page, i.e., a concurrent 518 // We were not able to sweep that page, i.e., a concurrent
514 // sweeper thread currently owns this page. Wait for the sweeper 519 // sweeper thread currently owns this page. Wait for the sweeper
515 // thread to be done with this page. 520 // thread to be done with this page.
516 page->WaitUntilSweepingCompleted(); 521 page->WaitUntilSweepingCompleted();
517 } 522 }
518 } 523 }
519 } 524 }
520 525
521 526
522 void MarkCompactCollector::EnsureSweepingCompleted() { 527 void MarkCompactCollector::EnsureSweepingCompleted() {
523 DCHECK(sweeping_in_progress_ == true); 528 DCHECK(sweeping_in_progress_ == true);
524 529
525 // If sweeping is not completed or not running at all, we try to complete it 530 // If sweeping is not completed or not running at all, we try to complete it
526 // here. 531 // here.
527 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) { 532 if (!heap()->concurrent_sweeping_enabled() || !IsSweepingCompleted()) {
528 SweepInParallel(heap()->paged_space(OLD_SPACE), 0); 533 SweepInParallel(heap()->paged_space(OLD_SPACE), 0);
529 SweepInParallel(heap()->paged_space(CODE_SPACE), 0); 534 SweepInParallel(heap()->paged_space(CODE_SPACE), 0);
535 SweepInParallel(heap()->paged_space(MAP_SPACE), 0);
530 } 536 }
531 // Wait twice for both jobs. 537 // Wait twice for both jobs.
532 if (heap()->concurrent_sweeping_enabled()) { 538 if (heap()->concurrent_sweeping_enabled()) {
533 pending_sweeper_jobs_semaphore_.Wait(); 539 pending_sweeper_jobs_semaphore_.Wait();
534 pending_sweeper_jobs_semaphore_.Wait(); 540 pending_sweeper_jobs_semaphore_.Wait();
541 pending_sweeper_jobs_semaphore_.Wait();
535 } 542 }
536 ParallelSweepSpacesComplete(); 543 ParallelSweepSpacesComplete();
537 sweeping_in_progress_ = false; 544 sweeping_in_progress_ = false;
538 RefillFreeList(heap()->paged_space(OLD_SPACE)); 545 RefillFreeList(heap()->paged_space(OLD_SPACE));
539 RefillFreeList(heap()->paged_space(CODE_SPACE)); 546 RefillFreeList(heap()->paged_space(CODE_SPACE));
547 RefillFreeList(heap()->paged_space(MAP_SPACE));
540 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); 548 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes();
541 heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes(); 549 heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes();
550 heap()->paged_space(MAP_SPACE)->ResetUnsweptFreeBytes();
542 551
543 #ifdef VERIFY_HEAP 552 #ifdef VERIFY_HEAP
544 if (FLAG_verify_heap && !evacuation()) { 553 if (FLAG_verify_heap && !evacuation()) {
545 VerifyEvacuation(heap_); 554 VerifyEvacuation(heap_);
546 } 555 }
547 #endif 556 #endif
548 } 557 }
549 558
550 559
551 bool MarkCompactCollector::IsSweepingCompleted() { 560 bool MarkCompactCollector::IsSweepingCompleted() {
552 if (!pending_sweeper_jobs_semaphore_.WaitFor( 561 if (!pending_sweeper_jobs_semaphore_.WaitFor(
553 base::TimeDelta::FromSeconds(0))) { 562 base::TimeDelta::FromSeconds(0))) {
554 return false; 563 return false;
555 } 564 }
556 pending_sweeper_jobs_semaphore_.Signal(); 565 pending_sweeper_jobs_semaphore_.Signal();
557 return true; 566 return true;
558 } 567 }
559 568
560 569
561 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { 570 void MarkCompactCollector::RefillFreeList(PagedSpace* space) {
562 FreeList* free_list; 571 FreeList* free_list;
563 572
564 if (space == heap()->old_space()) { 573 if (space == heap()->old_space()) {
565 free_list = free_list_old_space_.get(); 574 free_list = free_list_old_space_.get();
566 } else if (space == heap()->code_space()) { 575 } else if (space == heap()->code_space()) {
567 free_list = free_list_code_space_.get(); 576 free_list = free_list_code_space_.get();
577 } else if (space == heap()->map_space()) {
578 free_list = free_list_map_space_.get();
568 } else { 579 } else {
569 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure 580 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure
570 // to only refill them for the old space. 581 // to only refill them for the old space.
571 return; 582 return;
572 } 583 }
573 584
574 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); 585 intptr_t freed_bytes = space->free_list()->Concatenate(free_list);
575 space->AddToAccountingStats(freed_bytes); 586 space->AddToAccountingStats(freed_bytes);
576 space->DecrementUnsweptFreeBytes(freed_bytes); 587 space->DecrementUnsweptFreeBytes(freed_bytes);
577 } 588 }
(...skipping 3650 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 int max_freed = 0; 4239 int max_freed = 0;
4229 if (page->TryLock()) { 4240 if (page->TryLock()) {
4230 // If this page was already swept in the meantime, we can return here. 4241 // If this page was already swept in the meantime, we can return here.
4231 if (page->parallel_sweeping() != MemoryChunk::SWEEPING_PENDING) { 4242 if (page->parallel_sweeping() != MemoryChunk::SWEEPING_PENDING) {
4232 page->mutex()->Unlock(); 4243 page->mutex()->Unlock();
4233 return 0; 4244 return 0;
4234 } 4245 }
4235 page->set_parallel_sweeping(MemoryChunk::SWEEPING_IN_PROGRESS); 4246 page->set_parallel_sweeping(MemoryChunk::SWEEPING_IN_PROGRESS);
4236 FreeList* free_list; 4247 FreeList* free_list;
4237 FreeList private_free_list(space); 4248 FreeList private_free_list(space);
4238 if (space->identity() == CODE_SPACE) { 4249 if (space->identity() == OLD_SPACE) {
4250 free_list = free_list_old_space_.get();
4251 max_freed =
4252 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
4253 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
4254 } else if (space->identity() == CODE_SPACE) {
4239 free_list = free_list_code_space_.get(); 4255 free_list = free_list_code_space_.get();
4240 max_freed = 4256 max_freed =
4241 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST, 4257 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, REBUILD_SKIP_LIST,
4242 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); 4258 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
4243 } else { 4259 } else {
4244 free_list = free_list_old_space_.get(); 4260 free_list = free_list_map_space_.get();
4245 max_freed = 4261 max_freed =
4246 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST, 4262 Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
4247 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL); 4263 IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
4248 } 4264 }
4249 free_list->Concatenate(&private_free_list); 4265 free_list->Concatenate(&private_free_list);
4250 page->mutex()->Unlock(); 4266 page->mutex()->Unlock();
4251 } 4267 }
4252 return max_freed; 4268 return max_freed;
4253 } 4269 }
4254 4270
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 } 4321 }
4306 if (space->identity() == CODE_SPACE) { 4322 if (space->identity() == CODE_SPACE) {
4307 if (FLAG_zap_code_space) { 4323 if (FLAG_zap_code_space) {
4308 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 4324 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4309 ZAP_FREE_SPACE>(space, NULL, p, NULL); 4325 ZAP_FREE_SPACE>(space, NULL, p, NULL);
4310 } else { 4326 } else {
4311 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 4327 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4312 IGNORE_FREE_SPACE>(space, NULL, p, NULL); 4328 IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4313 } 4329 }
4314 } else { 4330 } else {
4315 DCHECK(space->identity() == OLD_SPACE);
4316 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, 4331 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
4317 IGNORE_FREE_SPACE>(space, NULL, p, NULL); 4332 IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4318 } 4333 }
4319 pages_swept++; 4334 pages_swept++;
4320 parallel_sweeping_active = true; 4335 parallel_sweeping_active = true;
4321 } else { 4336 } else {
4322 if (FLAG_gc_verbose) { 4337 if (FLAG_gc_verbose) {
4323 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", 4338 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n",
4324 reinterpret_cast<intptr_t>(p)); 4339 reinterpret_cast<intptr_t>(p));
4325 } 4340 }
4326 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING); 4341 p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING);
4327 space->IncreaseUnsweptFreeBytes(p); 4342 space->IncreaseUnsweptFreeBytes(p);
4328 } 4343 }
4329 space->set_end_of_unswept_pages(p); 4344 space->set_end_of_unswept_pages(p);
4330 break; 4345 break;
4331 case SEQUENTIAL_SWEEPING: { 4346 case SEQUENTIAL_SWEEPING: {
4332 if (FLAG_gc_verbose) { 4347 if (FLAG_gc_verbose) {
4333 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); 4348 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p));
4334 } 4349 }
4335 if (space->identity() == CODE_SPACE) { 4350 if (space->identity() == CODE_SPACE) {
4336 if (FLAG_zap_code_space) { 4351 if (FLAG_zap_code_space) {
4337 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 4352 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4338 ZAP_FREE_SPACE>(space, NULL, p, NULL); 4353 ZAP_FREE_SPACE>(space, NULL, p, NULL);
4339 } else { 4354 } else {
4340 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, 4355 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
4341 IGNORE_FREE_SPACE>(space, NULL, p, NULL); 4356 IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4342 } 4357 }
4343 } else { 4358 } else {
4344 DCHECK(space->identity() == OLD_SPACE ||
4345 space->identity() == MAP_SPACE);
4346 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST, 4359 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
4347 IGNORE_FREE_SPACE>(space, NULL, p, NULL); 4360 IGNORE_FREE_SPACE>(space, NULL, p, NULL);
4348 } 4361 }
4349 pages_swept++; 4362 pages_swept++;
4350 break; 4363 break;
4351 } 4364 }
4352 default: { UNREACHABLE(); } 4365 default: { UNREACHABLE(); }
4353 } 4366 }
4354 } 4367 }
4355 4368
(...skipping 29 matching lines...) Expand all
4385 { 4398 {
4386 GCTracer::Scope sweep_scope(heap()->tracer(), 4399 GCTracer::Scope sweep_scope(heap()->tracer(),
4387 GCTracer::Scope::MC_SWEEP_OLDSPACE); 4400 GCTracer::Scope::MC_SWEEP_OLDSPACE);
4388 SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING); 4401 SweepSpace(heap()->old_space(), CONCURRENT_SWEEPING);
4389 } 4402 }
4390 { 4403 {
4391 GCTracer::Scope sweep_scope(heap()->tracer(), 4404 GCTracer::Scope sweep_scope(heap()->tracer(),
4392 GCTracer::Scope::MC_SWEEP_CODE); 4405 GCTracer::Scope::MC_SWEEP_CODE);
4393 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING); 4406 SweepSpace(heap()->code_space(), CONCURRENT_SWEEPING);
4394 } 4407 }
4395 4408 {
4409 GCTracer::Scope sweep_scope(heap()->tracer(),
4410 GCTracer::Scope::MC_SWEEP_MAP);
4411 SweepSpace(heap()->map_space(), CONCURRENT_SWEEPING);
4412 }
4396 sweeping_in_progress_ = true; 4413 sweeping_in_progress_ = true;
4397 if (heap()->concurrent_sweeping_enabled()) { 4414 if (heap()->concurrent_sweeping_enabled()) {
4398 StartSweeperThreads(); 4415 StartSweeperThreads();
4399 } 4416 }
4400 } 4417 }
4401 4418
4402 RemoveDeadInvalidatedCode(); 4419 RemoveDeadInvalidatedCode();
4403 4420
4404 EvacuateNewSpaceAndCandidates(); 4421 EvacuateNewSpaceAndCandidates();
4405 4422
4406 heap()->FreeDeadArrayBuffers(false); 4423 heap()->FreeDeadArrayBuffers(false);
4407 4424
4408 // ClearNonLiveReferences depends on precise sweeping of map space to
4409 // detect whether unmarked map became dead in this collection or in one
4410 // of the previous ones.
4411 {
4412 GCTracer::Scope sweep_scope(heap()->tracer(),
4413 GCTracer::Scope::MC_SWEEP_MAP);
4414 SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING);
4415 }
4416
4417 // Deallocate unmarked objects and clear marked bits for marked objects. 4425 // Deallocate unmarked objects and clear marked bits for marked objects.
4418 heap_->lo_space()->FreeUnmarkedObjects(); 4426 heap_->lo_space()->FreeUnmarkedObjects();
4419 4427
4420 // Deallocate evacuated candidate pages. 4428 // Deallocate evacuated candidate pages.
4421 ReleaseEvacuationCandidates(); 4429 ReleaseEvacuationCandidates();
4422 CodeRange* code_range = heap()->isolate()->code_range(); 4430 CodeRange* code_range = heap()->isolate()->code_range();
4423 if (code_range != NULL && code_range->valid()) { 4431 if (code_range != NULL && code_range->valid()) {
4424 code_range->ReserveEmergencyBlock(); 4432 code_range->ReserveEmergencyBlock();
4425 } 4433 }
4426 4434
(...skipping 19 matching lines...) Expand all
4446 p->SetWasSwept(); 4454 p->SetWasSwept();
4447 } 4455 }
4448 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE); 4456 DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
4449 } 4457 }
4450 } 4458 }
4451 4459
4452 4460
4453 void MarkCompactCollector::ParallelSweepSpacesComplete() { 4461 void MarkCompactCollector::ParallelSweepSpacesComplete() {
4454 ParallelSweepSpaceComplete(heap()->old_space()); 4462 ParallelSweepSpaceComplete(heap()->old_space());
4455 ParallelSweepSpaceComplete(heap()->code_space()); 4463 ParallelSweepSpaceComplete(heap()->code_space());
4464 ParallelSweepSpaceComplete(heap()->map_space());
4456 } 4465 }
4457 4466
4458 4467
4459 void MarkCompactCollector::EnableCodeFlushing(bool enable) { 4468 void MarkCompactCollector::EnableCodeFlushing(bool enable) {
4460 if (isolate()->debug()->is_active()) enable = false; 4469 if (isolate()->debug()->is_active()) enable = false;
4461 4470
4462 if (enable) { 4471 if (enable) {
4463 if (code_flusher_ != NULL) return; 4472 if (code_flusher_ != NULL) return;
4464 code_flusher_ = new CodeFlusher(isolate()); 4473 code_flusher_ = new CodeFlusher(isolate());
4465 } else { 4474 } else {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 SlotsBuffer* buffer = *buffer_address; 4775 SlotsBuffer* buffer = *buffer_address;
4767 while (buffer != NULL) { 4776 while (buffer != NULL) {
4768 SlotsBuffer* next_buffer = buffer->next(); 4777 SlotsBuffer* next_buffer = buffer->next();
4769 DeallocateBuffer(buffer); 4778 DeallocateBuffer(buffer);
4770 buffer = next_buffer; 4779 buffer = next_buffer;
4771 } 4780 }
4772 *buffer_address = NULL; 4781 *buffer_address = NULL;
4773 } 4782 }
4774 } // namespace internal 4783 } // namespace internal
4775 } // namespace v8 4784 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698