| 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 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 RefillFreeList(heap()->paged_space(OLD_SPACE)); | 569 RefillFreeList(heap()->paged_space(OLD_SPACE)); |
| 570 RefillFreeList(heap()->paged_space(CODE_SPACE)); | 570 RefillFreeList(heap()->paged_space(CODE_SPACE)); |
| 571 RefillFreeList(heap()->paged_space(MAP_SPACE)); | 571 RefillFreeList(heap()->paged_space(MAP_SPACE)); |
| 572 heap()->paged_space(OLD_SPACE)->ResetUnsweptFreeBytes(); | |
| 573 heap()->paged_space(CODE_SPACE)->ResetUnsweptFreeBytes(); | |
| 574 heap()->paged_space(MAP_SPACE)->ResetUnsweptFreeBytes(); | |
| 575 | 572 |
| 576 #ifdef VERIFY_HEAP | 573 #ifdef VERIFY_HEAP |
| 577 if (FLAG_verify_heap && !evacuation()) { | 574 if (FLAG_verify_heap && !evacuation()) { |
| 578 VerifyEvacuation(heap_); | 575 VerifyEvacuation(heap_); |
| 579 } | 576 } |
| 580 #endif | 577 #endif |
| 581 } | 578 } |
| 582 | 579 |
| 583 | 580 |
| 584 bool MarkCompactCollector::IsSweepingCompleted() { | 581 bool MarkCompactCollector::IsSweepingCompleted() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 599 } else if (space == heap()->code_space()) { | 596 } else if (space == heap()->code_space()) { |
| 600 free_list = free_list_code_space_.get(); | 597 free_list = free_list_code_space_.get(); |
| 601 } else if (space == heap()->map_space()) { | 598 } else if (space == heap()->map_space()) { |
| 602 free_list = free_list_map_space_.get(); | 599 free_list = free_list_map_space_.get(); |
| 603 } else { | 600 } else { |
| 604 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure | 601 // Any PagedSpace might invoke RefillFreeLists, so we need to make sure |
| 605 // to only refill them for the old space. | 602 // to only refill them for the old space. |
| 606 return; | 603 return; |
| 607 } | 604 } |
| 608 | 605 |
| 609 intptr_t freed_bytes = space->free_list()->Concatenate(free_list); | 606 intptr_t added = space->free_list()->Concatenate(free_list); |
| 610 space->AddToAccountingStats(freed_bytes); | 607 space->accounting_stats_.IncreaseCapacity(added); |
| 611 space->DecrementUnsweptFreeBytes(freed_bytes); | |
| 612 } | 608 } |
| 613 | 609 |
| 614 | 610 |
| 615 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { | 611 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { |
| 616 // This is only used when resizing an object. | 612 // This is only used when resizing an object. |
| 617 DCHECK(MemoryChunk::FromAddress(old_start) == | 613 DCHECK(MemoryChunk::FromAddress(old_start) == |
| 618 MemoryChunk::FromAddress(new_start)); | 614 MemoryChunk::FromAddress(new_start)); |
| 619 | 615 |
| 620 if (!heap->incremental_marking()->IsMarking()) return; | 616 if (!heap->incremental_marking()->IsMarking()) return; |
| 621 | 617 |
| (...skipping 3235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3857 | 3853 |
| 3858 void MarkCompactCollector::ReleaseEvacuationCandidates() { | 3854 void MarkCompactCollector::ReleaseEvacuationCandidates() { |
| 3859 int npages = evacuation_candidates_.length(); | 3855 int npages = evacuation_candidates_.length(); |
| 3860 for (int i = 0; i < npages; i++) { | 3856 for (int i = 0; i < npages; i++) { |
| 3861 Page* p = evacuation_candidates_[i]; | 3857 Page* p = evacuation_candidates_[i]; |
| 3862 if (!p->IsEvacuationCandidate()) continue; | 3858 if (!p->IsEvacuationCandidate()) continue; |
| 3863 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); | 3859 PagedSpace* space = static_cast<PagedSpace*>(p->owner()); |
| 3864 space->Free(p->area_start(), p->area_size()); | 3860 space->Free(p->area_start(), p->area_size()); |
| 3865 p->set_scan_on_scavenge(false); | 3861 p->set_scan_on_scavenge(false); |
| 3866 p->ResetLiveBytes(); | 3862 p->ResetLiveBytes(); |
| 3863 CHECK(p->WasSwept()); |
| 3867 space->ReleasePage(p); | 3864 space->ReleasePage(p); |
| 3868 } | 3865 } |
| 3869 evacuation_candidates_.Rewind(0); | 3866 evacuation_candidates_.Rewind(0); |
| 3870 compacting_ = false; | 3867 compacting_ = false; |
| 3871 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages(); | 3868 heap()->FilterStoreBufferEntriesOnAboutToBeFreedPages(); |
| 3872 heap()->FreeQueuedChunks(); | 3869 heap()->FreeQueuedChunks(); |
| 3873 } | 3870 } |
| 3874 | 3871 |
| 3875 | 3872 |
| 3876 static const int kStartTableEntriesPerLine = 5; | 3873 static const int kStartTableEntriesPerLine = 5; |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4348 continue; | 4345 continue; |
| 4349 } | 4346 } |
| 4350 | 4347 |
| 4351 // One unused page is kept, all further are released before sweeping them. | 4348 // One unused page is kept, all further are released before sweeping them. |
| 4352 if (p->LiveBytes() == 0) { | 4349 if (p->LiveBytes() == 0) { |
| 4353 if (unused_page_present) { | 4350 if (unused_page_present) { |
| 4354 if (FLAG_gc_verbose) { | 4351 if (FLAG_gc_verbose) { |
| 4355 PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n", | 4352 PrintF("Sweeping 0x%" V8PRIxPTR " released page.\n", |
| 4356 reinterpret_cast<intptr_t>(p)); | 4353 reinterpret_cast<intptr_t>(p)); |
| 4357 } | 4354 } |
| 4358 // Adjust unswept free bytes because releasing a page expects said | |
| 4359 // counter to be accurate for unswept pages. | |
| 4360 space->IncreaseUnsweptFreeBytes(p); | |
| 4361 space->ReleasePage(p); | 4355 space->ReleasePage(p); |
| 4362 continue; | 4356 continue; |
| 4363 } | 4357 } |
| 4364 unused_page_present = true; | 4358 unused_page_present = true; |
| 4365 } | 4359 } |
| 4366 | 4360 |
| 4367 switch (sweeper) { | 4361 switch (sweeper) { |
| 4368 case CONCURRENT_SWEEPING: | 4362 case CONCURRENT_SWEEPING: |
| 4369 if (!parallel_sweeping_active) { | 4363 if (!parallel_sweeping_active) { |
| 4370 if (FLAG_gc_verbose) { | 4364 if (FLAG_gc_verbose) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4384 IGNORE_FREE_SPACE>(space, NULL, p, NULL); | 4378 IGNORE_FREE_SPACE>(space, NULL, p, NULL); |
| 4385 } | 4379 } |
| 4386 pages_swept++; | 4380 pages_swept++; |
| 4387 parallel_sweeping_active = true; | 4381 parallel_sweeping_active = true; |
| 4388 } else { | 4382 } else { |
| 4389 if (FLAG_gc_verbose) { | 4383 if (FLAG_gc_verbose) { |
| 4390 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", | 4384 PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n", |
| 4391 reinterpret_cast<intptr_t>(p)); | 4385 reinterpret_cast<intptr_t>(p)); |
| 4392 } | 4386 } |
| 4393 p->parallel_sweeping_state().SetValue(MemoryChunk::kSweepingPending); | 4387 p->parallel_sweeping_state().SetValue(MemoryChunk::kSweepingPending); |
| 4394 space->IncreaseUnsweptFreeBytes(p); | 4388 int to_sweep = p->area_size() - p->LiveBytes(); |
| 4389 space->accounting_stats_.ShrinkSpace(to_sweep); |
| 4395 } | 4390 } |
| 4396 space->set_end_of_unswept_pages(p); | 4391 space->set_end_of_unswept_pages(p); |
| 4397 break; | 4392 break; |
| 4398 case SEQUENTIAL_SWEEPING: { | 4393 case SEQUENTIAL_SWEEPING: { |
| 4399 if (FLAG_gc_verbose) { | 4394 if (FLAG_gc_verbose) { |
| 4400 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); | 4395 PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p)); |
| 4401 } | 4396 } |
| 4402 if (space->identity() == CODE_SPACE) { | 4397 if (space->identity() == CODE_SPACE) { |
| 4403 if (FLAG_zap_code_space) { | 4398 if (FLAG_zap_code_space) { |
| 4404 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, | 4399 Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST, |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4600 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4595 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4601 if (Marking::IsBlack(mark_bit)) { | 4596 if (Marking::IsBlack(mark_bit)) { |
| 4602 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4597 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
| 4603 RecordRelocSlot(&rinfo, target); | 4598 RecordRelocSlot(&rinfo, target); |
| 4604 } | 4599 } |
| 4605 } | 4600 } |
| 4606 } | 4601 } |
| 4607 | 4602 |
| 4608 } // namespace internal | 4603 } // namespace internal |
| 4609 } // namespace v8 | 4604 } // namespace v8 |
| OLD | NEW |