| 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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 559 } |
| 560 | 560 |
| 561 if (heap()->concurrent_sweeping_enabled()) { | 561 if (heap()->concurrent_sweeping_enabled()) { |
| 562 pending_sweeper_tasks_semaphore_.Wait(); | 562 pending_sweeper_tasks_semaphore_.Wait(); |
| 563 pending_sweeper_tasks_semaphore_.Wait(); | 563 pending_sweeper_tasks_semaphore_.Wait(); |
| 564 pending_sweeper_tasks_semaphore_.Wait(); | 564 pending_sweeper_tasks_semaphore_.Wait(); |
| 565 } | 565 } |
| 566 | 566 |
| 567 ParallelSweepSpacesComplete(); | 567 ParallelSweepSpacesComplete(); |
| 568 sweeping_in_progress_ = false; | 568 sweeping_in_progress_ = false; |
| 569 heap()->old_space()->RefillFreeList(); | 569 RefillFreeList(heap()->paged_space(OLD_SPACE)); |
| 570 heap()->code_space()->RefillFreeList(); | 570 RefillFreeList(heap()->paged_space(CODE_SPACE)); |
| 571 heap()->map_space()->RefillFreeList(); | 571 RefillFreeList(heap()->paged_space(MAP_SPACE)); |
| 572 | 572 |
| 573 #ifdef VERIFY_HEAP | 573 #ifdef VERIFY_HEAP |
| 574 if (FLAG_verify_heap && !evacuation()) { | 574 if (FLAG_verify_heap && !evacuation()) { |
| 575 VerifyEvacuation(heap_); | 575 VerifyEvacuation(heap_); |
| 576 } | 576 } |
| 577 #endif | 577 #endif |
| 578 } | 578 } |
| 579 | 579 |
| 580 | 580 |
| 581 bool MarkCompactCollector::IsSweepingCompleted() { | 581 bool MarkCompactCollector::IsSweepingCompleted() { |
| 582 if (!pending_sweeper_tasks_semaphore_.WaitFor( | 582 if (!pending_sweeper_tasks_semaphore_.WaitFor( |
| 583 base::TimeDelta::FromSeconds(0))) { | 583 base::TimeDelta::FromSeconds(0))) { |
| 584 return false; | 584 return false; |
| 585 } | 585 } |
| 586 pending_sweeper_tasks_semaphore_.Signal(); | 586 pending_sweeper_tasks_semaphore_.Signal(); |
| 587 return true; | 587 return true; |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 void MarkCompactCollector::RefillFreeList(PagedSpace* space) { |
| 592 FreeList* free_list; |
| 593 |
| 594 if (space == heap()->old_space()) { |
| 595 free_list = free_list_old_space_.get(); |
| 596 } else if (space == heap()->code_space()) { |
| 597 free_list = free_list_code_space_.get(); |
| 598 } else if (space == heap()->map_space()) { |
| 599 free_list = free_list_map_space_.get(); |
| 600 } else { |
| 601 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure |
| 602 // to only refill them for the old space. |
| 603 return; |
| 604 } |
| 605 |
| 606 intptr_t added = space->free_list()->Concatenate(free_list); |
| 607 space->accounting_stats_.IncreaseCapacity(added); |
| 608 } |
| 609 |
| 610 |
| 591 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { | 611 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { |
| 592 // This is only used when resizing an object. | 612 // This is only used when resizing an object. |
| 593 DCHECK(MemoryChunk::FromAddress(old_start) == | 613 DCHECK(MemoryChunk::FromAddress(old_start) == |
| 594 MemoryChunk::FromAddress(new_start)); | 614 MemoryChunk::FromAddress(new_start)); |
| 595 | 615 |
| 596 if (!heap->incremental_marking()->IsMarking()) return; | 616 if (!heap->incremental_marking()->IsMarking()) return; |
| 597 | 617 |
| 598 // If the mark doesn't move, we don't check the color of the object. | 618 // If the mark doesn't move, we don't check the color of the object. |
| 599 // It doesn't matter whether the object is black, since it hasn't changed | 619 // It doesn't matter whether the object is black, since it hasn't changed |
| 600 // size, so the adjustment to the live data count will be zero anyway. | 620 // size, so the adjustment to the live data count will be zero anyway. |
| (...skipping 2807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3408 | 3428 |
| 3409 const int num_tasks = NumberOfParallelCompactionTasks(); | 3429 const int num_tasks = NumberOfParallelCompactionTasks(); |
| 3410 | 3430 |
| 3411 // Set up compaction spaces. | 3431 // Set up compaction spaces. |
| 3412 CompactionSpaceCollection** compaction_spaces_for_tasks = | 3432 CompactionSpaceCollection** compaction_spaces_for_tasks = |
| 3413 new CompactionSpaceCollection*[num_tasks]; | 3433 new CompactionSpaceCollection*[num_tasks]; |
| 3414 for (int i = 0; i < num_tasks; i++) { | 3434 for (int i = 0; i < num_tasks; i++) { |
| 3415 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap()); | 3435 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap()); |
| 3416 } | 3436 } |
| 3417 | 3437 |
| 3418 heap()->old_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks, | 3438 compaction_spaces_for_tasks[0]->Get(OLD_SPACE)->MoveOverFreeMemory( |
| 3419 num_tasks); | 3439 heap()->old_space()); |
| 3420 heap()->code_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks, | 3440 compaction_spaces_for_tasks[0] |
| 3421 num_tasks); | 3441 ->Get(CODE_SPACE) |
| 3442 ->MoveOverFreeMemory(heap()->code_space()); |
| 3422 | 3443 |
| 3423 compaction_in_progress_ = true; | 3444 compaction_in_progress_ = true; |
| 3424 // Kick off parallel tasks. | 3445 // Kick off parallel tasks. |
| 3425 for (int i = 1; i < num_tasks; i++) { | 3446 for (int i = 1; i < num_tasks; i++) { |
| 3426 concurrent_compaction_tasks_active_++; | 3447 concurrent_compaction_tasks_active_++; |
| 3427 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 3448 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 3428 new CompactionTask(heap(), compaction_spaces_for_tasks[i]), | 3449 new CompactionTask(heap(), compaction_spaces_for_tasks[i]), |
| 3429 v8::Platform::kShortRunningTask); | 3450 v8::Platform::kShortRunningTask); |
| 3430 } | 3451 } |
| 3431 | 3452 |
| 3432 // Contribute in main thread. Counter and signal are in principal not needed. | 3453 // Contribute in main thread. Counter and signal are in principal not needed. |
| 3454 concurrent_compaction_tasks_active_++; |
| 3433 EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_); | 3455 EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_); |
| 3456 pending_compaction_tasks_semaphore_.Signal(); |
| 3434 | 3457 |
| 3435 WaitUntilCompactionCompleted(); | 3458 WaitUntilCompactionCompleted(); |
| 3436 | 3459 |
| 3437 // Merge back memory (compacted and unused) from compaction spaces. | 3460 // Merge back memory (compacted and unused) from compaction spaces. |
| 3438 for (int i = 0; i < num_tasks; i++) { | 3461 for (int i = 0; i < num_tasks; i++) { |
| 3439 heap()->old_space()->MergeCompactionSpace( | 3462 heap()->old_space()->MergeCompactionSpace( |
| 3440 compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); | 3463 compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); |
| 3441 heap()->code_space()->MergeCompactionSpace( | 3464 heap()->code_space()->MergeCompactionSpace( |
| 3442 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); | 3465 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); |
| 3443 delete compaction_spaces_for_tasks[i]; | 3466 delete compaction_spaces_for_tasks[i]; |
| (...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4616 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4639 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4617 if (Marking::IsBlack(mark_bit)) { | 4640 if (Marking::IsBlack(mark_bit)) { |
| 4618 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4641 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
| 4619 RecordRelocSlot(&rinfo, target); | 4642 RecordRelocSlot(&rinfo, target); |
| 4620 } | 4643 } |
| 4621 } | 4644 } |
| 4622 } | 4645 } |
| 4623 | 4646 |
| 4624 } // namespace internal | 4647 } // namespace internal |
| 4625 } // namespace v8 | 4648 } // namespace v8 |
| OLD | NEW |