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

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

Issue 1998213002: Workaround for glibc semaphore bug. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // The following has to hold in order for {Marking::MarkBitFrom} to not produce 42 // The following has to hold in order for {Marking::MarkBitFrom} to not produce
43 // invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. 43 // invalid {kImpossibleBitPattern} in the marking bitmap by overlapping.
44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); 44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2);
45 45
46 46
47 // ------------------------------------------------------------------------- 47 // -------------------------------------------------------------------------
48 // MarkCompactCollector 48 // MarkCompactCollector
49 49
50 MarkCompactCollector::MarkCompactCollector(Heap* heap) 50 MarkCompactCollector::MarkCompactCollector(Heap* heap)
51 : // NOLINT 51 : // NOLINT
52 heap_(heap),
53 page_parallel_job_semaphore_(0),
52 #ifdef DEBUG 54 #ifdef DEBUG
53 state_(IDLE), 55 state_(IDLE),
54 #endif 56 #endif
55 marking_parity_(ODD_MARKING_PARITY), 57 marking_parity_(ODD_MARKING_PARITY),
56 was_marked_incrementally_(false), 58 was_marked_incrementally_(false),
57 evacuation_(false), 59 evacuation_(false),
58 heap_(heap), 60 compacting_(false),
61 black_allocation_(false),
62 have_code_to_deoptimize_(false),
59 marking_deque_memory_(NULL), 63 marking_deque_memory_(NULL),
60 marking_deque_memory_committed_(0), 64 marking_deque_memory_committed_(0),
61 code_flusher_(nullptr), 65 code_flusher_(nullptr),
62 embedder_heap_tracer_(nullptr), 66 embedder_heap_tracer_(nullptr),
63 have_code_to_deoptimize_(false),
64 compacting_(false),
65 sweeper_(heap) { 67 sweeper_(heap) {
66 } 68 }
67 69
68 #ifdef VERIFY_HEAP 70 #ifdef VERIFY_HEAP
69 class VerifyMarkingVisitor : public ObjectVisitor { 71 class VerifyMarkingVisitor : public ObjectVisitor {
70 public: 72 public:
71 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} 73 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {}
72 74
73 void VisitPointers(Object** start, Object** end) override { 75 void VisitPointers(Object** start, Object** end) override {
74 for (Object** current = start; current < end; current++) { 76 for (Object** current = start; current < end; current++) {
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 DCHECK_GE(space_to_start_, FIRST_PAGED_SPACE); 475 DCHECK_GE(space_to_start_, FIRST_PAGED_SPACE);
474 DCHECK_LE(space_to_start_, LAST_PAGED_SPACE); 476 DCHECK_LE(space_to_start_, LAST_PAGED_SPACE);
475 const int offset = space_to_start_ - FIRST_PAGED_SPACE; 477 const int offset = space_to_start_ - FIRST_PAGED_SPACE;
476 const int num_spaces = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; 478 const int num_spaces = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
477 for (int i = 0; i < num_spaces; i++) { 479 for (int i = 0; i < num_spaces; i++) {
478 const int space_id = FIRST_PAGED_SPACE + ((i + offset) % num_spaces); 480 const int space_id = FIRST_PAGED_SPACE + ((i + offset) % num_spaces);
479 DCHECK_GE(space_id, FIRST_PAGED_SPACE); 481 DCHECK_GE(space_id, FIRST_PAGED_SPACE);
480 DCHECK_LE(space_id, LAST_PAGED_SPACE); 482 DCHECK_LE(space_id, LAST_PAGED_SPACE);
481 sweeper_->ParallelSweepSpace(static_cast<AllocationSpace>(space_id), 0); 483 sweeper_->ParallelSweepSpace(static_cast<AllocationSpace>(space_id), 0);
482 } 484 }
483 pending_sweeper_tasks_->Signal("SweeperTask::Run"); 485 pending_sweeper_tasks_->Signal();
484 } 486 }
485 487
486 Sweeper* sweeper_; 488 Sweeper* sweeper_;
487 base::Semaphore* pending_sweeper_tasks_; 489 base::Semaphore* pending_sweeper_tasks_;
488 AllocationSpace space_to_start_; 490 AllocationSpace space_to_start_;
489 491
490 DISALLOW_COPY_AND_ASSIGN(SweeperTask); 492 DISALLOW_COPY_AND_ASSIGN(SweeperTask);
491 }; 493 };
492 494
493 void MarkCompactCollector::Sweeper::StartSweeping() { 495 void MarkCompactCollector::Sweeper::StartSweeping() {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 VerifyEvacuation(heap_); 580 VerifyEvacuation(heap_);
579 } 581 }
580 #endif 582 #endif
581 } 583 }
582 584
583 bool MarkCompactCollector::Sweeper::IsSweepingCompleted() { 585 bool MarkCompactCollector::Sweeper::IsSweepingCompleted() {
584 if (!pending_sweeper_tasks_semaphore_.WaitFor( 586 if (!pending_sweeper_tasks_semaphore_.WaitFor(
585 base::TimeDelta::FromSeconds(0))) { 587 base::TimeDelta::FromSeconds(0))) {
586 return false; 588 return false;
587 } 589 }
588 pending_sweeper_tasks_semaphore_.Signal("Sweeper::IsSweepingCompleted"); 590 pending_sweeper_tasks_semaphore_.Signal();
589 return true; 591 return true;
590 } 592 }
591 593
592 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) { 594 void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) {
593 // This is only used when resizing an object. 595 // This is only used when resizing an object.
594 DCHECK(MemoryChunk::FromAddress(old_start) == 596 DCHECK(MemoryChunk::FromAddress(old_start) ==
595 MemoryChunk::FromAddress(new_start)); 597 MemoryChunk::FromAddress(new_start));
596 598
597 if (!heap->incremental_marking()->IsMarking() || 599 if (!heap->incremental_marking()->IsMarking() ||
598 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE)) 600 Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE))
(...skipping 2746 matching lines...) Expand 10 before | Expand all | Expand 10 after
3345 // Slots have already been recorded so we just need to add it to the 3347 // Slots have already been recorded so we just need to add it to the
3346 // sweeper. 3348 // sweeper.
3347 *data += 1; 3349 *data += 1;
3348 } 3350 }
3349 } 3351 }
3350 } 3352 }
3351 }; 3353 };
3352 3354
3353 void MarkCompactCollector::EvacuatePagesInParallel() { 3355 void MarkCompactCollector::EvacuatePagesInParallel() {
3354 PageParallelJob<EvacuationJobTraits> job( 3356 PageParallelJob<EvacuationJobTraits> job(
3355 heap_, heap_->isolate()->cancelable_task_manager()); 3357 heap_, heap_->isolate()->cancelable_task_manager(),
3358 &page_parallel_job_semaphore_);
3356 3359
3357 int abandoned_pages = 0; 3360 int abandoned_pages = 0;
3358 intptr_t live_bytes = 0; 3361 intptr_t live_bytes = 0;
3359 for (Page* page : evacuation_candidates_) { 3362 for (Page* page : evacuation_candidates_) {
3360 live_bytes += page->LiveBytes(); 3363 live_bytes += page->LiveBytes();
3361 job.AddPage(page, &abandoned_pages); 3364 job.AddPage(page, &abandoned_pages);
3362 } 3365 }
3363 3366
3364 const Address age_mark = heap()->new_space()->age_mark(); 3367 const Address age_mark = heap()->new_space()->age_mark();
3365 for (Page* page : newspace_evacuation_candidates_) { 3368 for (Page* page : newspace_evacuation_candidates_) {
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
3714 }; 3717 };
3715 3718
3716 int NumberOfPointerUpdateTasks(int pages) { 3719 int NumberOfPointerUpdateTasks(int pages) {
3717 if (!FLAG_parallel_pointer_update) return 1; 3720 if (!FLAG_parallel_pointer_update) return 1;
3718 const int kMaxTasks = 4; 3721 const int kMaxTasks = 4;
3719 const int kPagesPerTask = 4; 3722 const int kPagesPerTask = 4;
3720 return Min(kMaxTasks, (pages + kPagesPerTask - 1) / kPagesPerTask); 3723 return Min(kMaxTasks, (pages + kPagesPerTask - 1) / kPagesPerTask);
3721 } 3724 }
3722 3725
3723 template <PointerDirection direction> 3726 template <PointerDirection direction>
3724 void UpdatePointersInParallel(Heap* heap) { 3727 void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
3725 PageParallelJob<PointerUpdateJobTraits<direction> > job( 3728 PageParallelJob<PointerUpdateJobTraits<direction> > job(
3726 heap, heap->isolate()->cancelable_task_manager()); 3729 heap, heap->isolate()->cancelable_task_manager(), semaphore);
3727 RememberedSet<direction>::IterateMemoryChunks( 3730 RememberedSet<direction>::IterateMemoryChunks(
3728 heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); }); 3731 heap, [&job](MemoryChunk* chunk) { job.AddPage(chunk, 0); });
3729 int num_pages = job.NumberOfPages(); 3732 int num_pages = job.NumberOfPages();
3730 int num_tasks = NumberOfPointerUpdateTasks(num_pages); 3733 int num_tasks = NumberOfPointerUpdateTasks(num_pages);
3731 job.Run(num_tasks, [](int i) { return 0; }); 3734 job.Run(num_tasks, [](int i) { return 0; });
3732 } 3735 }
3733 3736
3734 class ToSpacePointerUpdateJobTraits { 3737 class ToSpacePointerUpdateJobTraits {
3735 public: 3738 public:
3736 typedef std::pair<Address, Address> PerPageData; 3739 typedef std::pair<Address, Address> PerPageData;
3737 typedef PointersUpdatingVisitor* PerTaskData; 3740 typedef PointersUpdatingVisitor* PerTaskData;
3738 3741
3739 static bool ProcessPageInParallel(Heap* heap, PerTaskData visitor, 3742 static bool ProcessPageInParallel(Heap* heap, PerTaskData visitor,
3740 MemoryChunk* chunk, PerPageData limits) { 3743 MemoryChunk* chunk, PerPageData limits) {
3741 for (Address cur = limits.first; cur < limits.second;) { 3744 for (Address cur = limits.first; cur < limits.second;) {
3742 HeapObject* object = HeapObject::FromAddress(cur); 3745 HeapObject* object = HeapObject::FromAddress(cur);
3743 Map* map = object->map(); 3746 Map* map = object->map();
3744 int size = object->SizeFromMap(map); 3747 int size = object->SizeFromMap(map);
3745 object->IterateBody(map->instance_type(), size, visitor); 3748 object->IterateBody(map->instance_type(), size, visitor);
3746 cur += size; 3749 cur += size;
3747 } 3750 }
3748 return true; 3751 return true;
3749 } 3752 }
3750 static const bool NeedSequentialFinalization = false; 3753 static const bool NeedSequentialFinalization = false;
3751 static void FinalizePageSequentially(Heap*, MemoryChunk*, bool, PerPageData) { 3754 static void FinalizePageSequentially(Heap*, MemoryChunk*, bool, PerPageData) {
3752 } 3755 }
3753 }; 3756 };
3754 3757
3755 void UpdateToSpacePointersInParallel(Heap* heap) { 3758 void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
3756 PageParallelJob<ToSpacePointerUpdateJobTraits> job( 3759 PageParallelJob<ToSpacePointerUpdateJobTraits> job(
3757 heap, heap->isolate()->cancelable_task_manager()); 3760 heap, heap->isolate()->cancelable_task_manager(), semaphore);
3758 Address space_start = heap->new_space()->bottom(); 3761 Address space_start = heap->new_space()->bottom();
3759 Address space_end = heap->new_space()->top(); 3762 Address space_end = heap->new_space()->top();
3760 NewSpacePageIterator it(space_start, space_end); 3763 NewSpacePageIterator it(space_start, space_end);
3761 while (it.has_next()) { 3764 while (it.has_next()) {
3762 Page* page = it.next(); 3765 Page* page = it.next();
3763 Address start = 3766 Address start =
3764 page->Contains(space_start) ? space_start : page->area_start(); 3767 page->Contains(space_start) ? space_start : page->area_start();
3765 Address end = page->Contains(space_end) ? space_end : page->area_end(); 3768 Address end = page->Contains(space_end) ? space_end : page->area_end();
3766 job.AddPage(page, std::make_pair(start, end)); 3769 job.AddPage(page, std::make_pair(start, end));
3767 } 3770 }
3768 PointersUpdatingVisitor visitor; 3771 PointersUpdatingVisitor visitor;
3769 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; 3772 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1;
3770 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); 3773 job.Run(num_tasks, [&visitor](int i) { return &visitor; });
3771 } 3774 }
3772 3775
3773 void MarkCompactCollector::UpdatePointersAfterEvacuation() { 3776 void MarkCompactCollector::UpdatePointersAfterEvacuation() {
3774 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS); 3777 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS);
3775 3778
3776 PointersUpdatingVisitor updating_visitor; 3779 PointersUpdatingVisitor updating_visitor;
3777 3780
3778 { 3781 {
3779 TRACE_GC(heap()->tracer(), 3782 TRACE_GC(heap()->tracer(),
3780 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW); 3783 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW);
3781 UpdateToSpacePointersInParallel(heap_); 3784 UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_);
3782 // Update roots. 3785 // Update roots.
3783 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); 3786 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
3784 UpdatePointersInParallel<OLD_TO_NEW>(heap_); 3787 UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_);
3785 } 3788 }
3786 3789
3787 { 3790 {
3788 Heap* heap = this->heap(); 3791 Heap* heap = this->heap();
3789 TRACE_GC(heap->tracer(), 3792 TRACE_GC(heap->tracer(),
3790 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); 3793 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED);
3791 UpdatePointersInParallel<OLD_TO_OLD>(heap_); 3794 UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_);
3792 } 3795 }
3793 3796
3794 { 3797 {
3795 TRACE_GC(heap()->tracer(), 3798 TRACE_GC(heap()->tracer(),
3796 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_WEAK); 3799 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_WEAK);
3797 // Update pointers from external string table. 3800 // Update pointers from external string table.
3798 heap_->UpdateReferencesInExternalStringTable( 3801 heap_->UpdateReferencesInExternalStringTable(
3799 &UpdateReferenceInExternalStringTableEntry); 3802 &UpdateReferenceInExternalStringTableEntry);
3800 3803
3801 EvacuationWeakObjectRetainer evacuation_object_retainer; 3804 EvacuationWeakObjectRetainer evacuation_object_retainer;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4033 MarkBit mark_bit = Marking::MarkBitFrom(host); 4036 MarkBit mark_bit = Marking::MarkBitFrom(host);
4034 if (Marking::IsBlack(mark_bit)) { 4037 if (Marking::IsBlack(mark_bit)) {
4035 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host); 4038 RelocInfo rinfo(isolate(), pc, RelocInfo::CODE_TARGET, 0, host);
4036 RecordRelocSlot(host, &rinfo, target); 4039 RecordRelocSlot(host, &rinfo, target);
4037 } 4040 }
4038 } 4041 }
4039 } 4042 }
4040 4043
4041 } // namespace internal 4044 } // namespace internal
4042 } // namespace v8 4045 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698