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

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

Issue 1446523003: [heap] Use cancelable tasks during compaction. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added StartParallelCompaction Created 5 years, 1 month 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/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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 migration_slots_buffer_(nullptr), 58 migration_slots_buffer_(nullptr),
59 heap_(heap), 59 heap_(heap),
60 marking_deque_memory_(NULL), 60 marking_deque_memory_(NULL),
61 marking_deque_memory_committed_(0), 61 marking_deque_memory_committed_(0),
62 code_flusher_(NULL), 62 code_flusher_(NULL),
63 have_code_to_deoptimize_(false), 63 have_code_to_deoptimize_(false),
64 compacting_(false), 64 compacting_(false),
65 sweeping_in_progress_(false), 65 sweeping_in_progress_(false),
66 compaction_in_progress_(false), 66 compaction_in_progress_(false),
67 pending_sweeper_tasks_semaphore_(0), 67 pending_sweeper_tasks_semaphore_(0),
68 pending_compaction_tasks_semaphore_(0), 68 pending_compaction_tasks_semaphore_(0) {
69 concurrent_compaction_tasks_active_(0) {
70 } 69 }
71 70
72 #ifdef VERIFY_HEAP 71 #ifdef VERIFY_HEAP
73 class VerifyMarkingVisitor : public ObjectVisitor { 72 class VerifyMarkingVisitor : public ObjectVisitor {
74 public: 73 public:
75 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} 74 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {}
76 75
77 void VisitPointers(Object** start, Object** end) override { 76 void VisitPointers(Object** start, Object** end) override {
78 for (Object** current = start; current < end; current++) { 77 for (Object** current = start; current < end; current++) {
79 if ((*current)->IsHeapObject()) { 78 if ((*current)->IsHeapObject()) {
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 473
475 LargeObjectIterator it(heap_->lo_space()); 474 LargeObjectIterator it(heap_->lo_space());
476 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 475 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
477 Marking::MarkWhite(Marking::MarkBitFrom(obj)); 476 Marking::MarkWhite(Marking::MarkBitFrom(obj));
478 Page::FromAddress(obj->address())->ResetProgressBar(); 477 Page::FromAddress(obj->address())->ResetProgressBar();
479 Page::FromAddress(obj->address())->ResetLiveBytes(); 478 Page::FromAddress(obj->address())->ResetLiveBytes();
480 } 479 }
481 } 480 }
482 481
483 482
484 class MarkCompactCollector::CompactionTask : public v8::Task { 483 class MarkCompactCollector::CompactionTask : public CancelableTask {
485 public: 484 public:
486 explicit CompactionTask(Heap* heap, CompactionSpaceCollection* spaces) 485 explicit CompactionTask(Heap* heap, CompactionSpaceCollection* spaces)
487 : heap_(heap), spaces_(spaces) {} 486 : CancelableTask(heap->isolate()), spaces_(spaces) {}
488 487
489 virtual ~CompactionTask() {} 488 virtual ~CompactionTask() {}
490 489
491 private: 490 private:
492 // v8::Task overrides. 491 // v8::internal::CancelableTask overrides.
493 void Run() override { 492 void RunInternal() override {
494 MarkCompactCollector* mark_compact = heap_->mark_compact_collector(); 493 MarkCompactCollector* mark_compact =
494 isolate()->heap()->mark_compact_collector();
495 SlotsBuffer* evacuation_slots_buffer = nullptr; 495 SlotsBuffer* evacuation_slots_buffer = nullptr;
496 mark_compact->EvacuatePages(spaces_, &evacuation_slots_buffer); 496 mark_compact->EvacuatePages(spaces_, &evacuation_slots_buffer);
497 mark_compact->AddEvacuationSlotsBufferSynchronized(evacuation_slots_buffer); 497 mark_compact->AddEvacuationSlotsBufferSynchronized(evacuation_slots_buffer);
498 mark_compact->pending_compaction_tasks_semaphore_.Signal(); 498 mark_compact->pending_compaction_tasks_semaphore_.Signal();
499 } 499 }
500 500
501 Heap* heap_;
502 CompactionSpaceCollection* spaces_; 501 CompactionSpaceCollection* spaces_;
503 502
504 DISALLOW_COPY_AND_ASSIGN(CompactionTask); 503 DISALLOW_COPY_AND_ASSIGN(CompactionTask);
505 }; 504 };
506 505
507 506
508 class MarkCompactCollector::SweeperTask : public v8::Task { 507 class MarkCompactCollector::SweeperTask : public v8::Task {
509 public: 508 public:
510 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {} 509 SweeperTask(Heap* heap, PagedSpace* space) : heap_(heap), space_(space) {}
511 510
(...skipping 2680 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 intptr_t live_bytes = 0; 3191 intptr_t live_bytes = 0;
3193 intptr_t compaction_speed = 0; 3192 intptr_t compaction_speed = 0;
3194 if (FLAG_trace_fragmentation) { 3193 if (FLAG_trace_fragmentation) {
3195 for (Page* page : evacuation_candidates_) { 3194 for (Page* page : evacuation_candidates_) {
3196 live_bytes += page->LiveBytes(); 3195 live_bytes += page->LiveBytes();
3197 } 3196 }
3198 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond(); 3197 compaction_speed = heap()->tracer()->CompactionSpeedInBytesPerMillisecond();
3199 } 3198 }
3200 const int num_tasks = NumberOfParallelCompactionTasks(); 3199 const int num_tasks = NumberOfParallelCompactionTasks();
3201 3200
3202
3203 // Set up compaction spaces. 3201 // Set up compaction spaces.
3204 CompactionSpaceCollection** compaction_spaces_for_tasks = 3202 CompactionSpaceCollection** compaction_spaces_for_tasks =
3205 new CompactionSpaceCollection*[num_tasks]; 3203 new CompactionSpaceCollection*[num_tasks];
3206 for (int i = 0; i < num_tasks; i++) { 3204 for (int i = 0; i < num_tasks; i++) {
3207 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap()); 3205 compaction_spaces_for_tasks[i] = new CompactionSpaceCollection(heap());
3208 } 3206 }
3209 3207
3210 heap()->old_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks, 3208 heap()->old_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks,
3211 num_tasks); 3209 num_tasks);
3212 heap()->code_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks, 3210 heap()->code_space()->DivideUponCompactionSpaces(compaction_spaces_for_tasks,
3213 num_tasks); 3211 num_tasks);
3214 3212
3215 compaction_in_progress_ = true; 3213 uint32_t* task_ids = new uint32_t[num_tasks - 1];
3216 // Kick off parallel tasks. 3214 // Kick off parallel tasks.
3217 for (int i = 1; i < num_tasks; i++) { 3215 StartParallelCompaction(compaction_spaces_for_tasks, task_ids, num_tasks);
3218 concurrent_compaction_tasks_active_++; 3216 // Wait for unfinished and not-yet-started tasks.
3219 V8::GetCurrentPlatform()->CallOnBackgroundThread( 3217 WaitUntilCompactionCompleted(task_ids, num_tasks - 1);
3220 new CompactionTask(heap(), compaction_spaces_for_tasks[i]), 3218 delete[] task_ids;
3221 v8::Platform::kShortRunningTask);
3222 }
3223
3224 // Contribute in main thread. Counter and signal are in principal not needed.
3225 EvacuatePages(compaction_spaces_for_tasks[0], &migration_slots_buffer_);
3226
3227 WaitUntilCompactionCompleted();
3228 3219
3229 double compaction_duration = 0.0; 3220 double compaction_duration = 0.0;
3230 intptr_t compacted_memory = 0; 3221 intptr_t compacted_memory = 0;
3231 // Merge back memory (compacted and unused) from compaction spaces. 3222 // Merge back memory (compacted and unused) from compaction spaces.
3232 for (int i = 0; i < num_tasks; i++) { 3223 for (int i = 0; i < num_tasks; i++) {
3233 heap()->old_space()->MergeCompactionSpace( 3224 heap()->old_space()->MergeCompactionSpace(
3234 compaction_spaces_for_tasks[i]->Get(OLD_SPACE)); 3225 compaction_spaces_for_tasks[i]->Get(OLD_SPACE));
3235 heap()->code_space()->MergeCompactionSpace( 3226 heap()->code_space()->MergeCompactionSpace(
3236 compaction_spaces_for_tasks[i]->Get(CODE_SPACE)); 3227 compaction_spaces_for_tasks[i]->Get(CODE_SPACE));
3237 compacted_memory += compaction_spaces_for_tasks[i]->bytes_compacted(); 3228 compacted_memory += compaction_spaces_for_tasks[i]->bytes_compacted();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 "tasks=%d cores=%d live_bytes=%" V8_PTR_PREFIX 3274 "tasks=%d cores=%d live_bytes=%" V8_PTR_PREFIX
3284 "d compaction_speed=%" V8_PTR_PREFIX "d\n", 3275 "d compaction_speed=%" V8_PTR_PREFIX "d\n",
3285 isolate()->time_millis_since_init(), FLAG_parallel_compaction, 3276 isolate()->time_millis_since_init(), FLAG_parallel_compaction,
3286 num_pages, abandoned_pages, num_tasks, 3277 num_pages, abandoned_pages, num_tasks,
3287 base::SysInfo::NumberOfProcessors(), live_bytes, 3278 base::SysInfo::NumberOfProcessors(), live_bytes,
3288 compaction_speed); 3279 compaction_speed);
3289 } 3280 }
3290 } 3281 }
3291 3282
3292 3283
3293 void MarkCompactCollector::WaitUntilCompactionCompleted() { 3284 void MarkCompactCollector::StartParallelCompaction(
3294 while (concurrent_compaction_tasks_active_ > 0) { 3285 CompactionSpaceCollection** compaction_spaces, uint32_t* task_ids,
3295 pending_compaction_tasks_semaphore_.Wait(); 3286 int len) {
3296 concurrent_compaction_tasks_active_--; 3287 compaction_in_progress_ = true;
3288 for (int i = 1; i < len; i++) {
3289 CompactionTask* task = new CompactionTask(heap(), compaction_spaces[i]);
3290 task_ids[i - 1] = task->id();
3291 V8::GetCurrentPlatform()->CallOnBackgroundThread(
3292 task, v8::Platform::kShortRunningTask);
3293 }
3294
3295 // Contribute in main thread.
3296 EvacuatePages(compaction_spaces[0], &migration_slots_buffer_);
3297 }
3298
3299
3300 void MarkCompactCollector::WaitUntilCompactionCompleted(uint32_t* task_ids,
3301 int len) {
3302 // Try to cancel compaction tasks that have not been run (as they might be
3303 // stuck in a worker queue). Tasks that cannot be canceled, have either
3304 // already completed or are still running, hence we need to wait for their
3305 // semaphore signal.
3306 for (int i = 0; i < len; i++) {
3307 if (!heap()->isolate()->cancelable_task_manager()->TryAbort(task_ids[i])) {
3308 pending_compaction_tasks_semaphore_.Wait();
3309 }
3297 } 3310 }
3298 compaction_in_progress_ = false; 3311 compaction_in_progress_ = false;
3299 } 3312 }
3300 3313
3301 3314
3302 void MarkCompactCollector::EvacuatePages( 3315 void MarkCompactCollector::EvacuatePages(
3303 CompactionSpaceCollection* compaction_spaces, 3316 CompactionSpaceCollection* compaction_spaces,
3304 SlotsBuffer** evacuation_slots_buffer) { 3317 SlotsBuffer** evacuation_slots_buffer) {
3305 for (int i = 0; i < evacuation_candidates_.length(); i++) { 3318 for (int i = 0; i < evacuation_candidates_.length(); i++) {
3306 Page* p = evacuation_candidates_[i]; 3319 Page* p = evacuation_candidates_[i];
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4476 MarkBit mark_bit = Marking::MarkBitFrom(host); 4489 MarkBit mark_bit = Marking::MarkBitFrom(host);
4477 if (Marking::IsBlack(mark_bit)) { 4490 if (Marking::IsBlack(mark_bit)) {
4478 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); 4491 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host);
4479 RecordRelocSlot(&rinfo, target); 4492 RecordRelocSlot(&rinfo, target);
4480 } 4493 }
4481 } 4494 }
4482 } 4495 }
4483 4496
4484 } // namespace internal 4497 } // namespace internal
4485 } // namespace v8 4498 } // 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