 Chromium Code Reviews
 Chromium Code Reviews Issue 2735803005:
  [heap] Start concurrent marking simultaneously with incremental marking.  (Closed)
    
  
    Issue 2735803005:
  [heap] Start concurrent marking simultaneously with incremental marking.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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/concurrent-marking.h" | 5 #include "src/heap/concurrent-marking.h" | 
| 6 | 6 | 
| 7 #include <stack> | 7 #include <stack> | 
| 8 #include <unordered_map> | 8 #include <unordered_map> | 
| 9 | 9 | 
| 10 #include "src/heap/heap-inl.h" | 10 #include "src/heap/heap-inl.h" | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 } | 43 } | 
| 44 | 44 | 
| 45 void FreeBitmap(Bitmap* bitmap) { free(bitmap); } | 45 void FreeBitmap(Bitmap* bitmap) { free(bitmap); } | 
| 46 | 46 | 
| 47 private: | 47 private: | 
| 48 std::unordered_map<MemoryChunk*, Bitmap*> bitmap_; | 48 std::unordered_map<MemoryChunk*, Bitmap*> bitmap_; | 
| 49 }; | 49 }; | 
| 50 | 50 | 
| 51 class ConcurrentMarkingVisitor : public ObjectVisitor { | 51 class ConcurrentMarkingVisitor : public ObjectVisitor { | 
| 52 public: | 52 public: | 
| 53 ConcurrentMarkingVisitor() {} | 53 ConcurrentMarkingVisitor() : bytes_marked_(0) {} | 
| 54 | 54 | 
| 55 void VisitPointers(Object** start, Object** end) override { | 55 void VisitPointers(Object** start, Object** end) override { | 
| 56 for (Object** p = start; p < end; p++) { | 56 for (Object** p = start; p < end; p++) { | 
| 57 if (!(*p)->IsHeapObject()) continue; | 57 if (!(*p)->IsHeapObject()) continue; | 
| 58 MarkObject(HeapObject::cast(*p)); | 58 MarkObject(HeapObject::cast(*p)); | 
| 59 } | 59 } | 
| 60 } | 60 } | 
| 61 | 61 | 
| 62 void MarkObject(HeapObject* obj) { | 62 void MarkObject(HeapObject* obj) { | 
| 63 if (markbits_.Mark(obj)) { | 63 if (markbits_.Mark(obj)) { | 
| 64 bytes_marked_ += obj->Size(); | |
| 64 marking_stack_.push(obj); | 65 marking_stack_.push(obj); | 
| 65 } | 66 } | 
| 66 } | 67 } | 
| 67 | 68 | 
| 68 void MarkTransitively() { | 69 void MarkTransitively() { | 
| 69 while (!marking_stack_.empty()) { | 70 while (!marking_stack_.empty()) { | 
| 70 HeapObject* obj = marking_stack_.top(); | 71 HeapObject* obj = marking_stack_.top(); | 
| 71 marking_stack_.pop(); | 72 marking_stack_.pop(); | 
| 72 obj->Iterate(this); | 73 obj->Iterate(this); | 
| 73 } | 74 } | 
| 74 } | 75 } | 
| 75 | 76 | 
| 77 size_t bytes_marked() { return bytes_marked_; } | |
| 78 | |
| 76 private: | 79 private: | 
| 80 size_t bytes_marked_; | |
| 77 std::stack<HeapObject*> marking_stack_; | 81 std::stack<HeapObject*> marking_stack_; | 
| 78 ConcurrentMarkingMarkbits markbits_; | 82 ConcurrentMarkingMarkbits markbits_; | 
| 79 }; | 83 }; | 
| 80 | 84 | 
| 81 class ConcurrentMarking::Task : public CancelableTask { | 85 class ConcurrentMarking::Task : public CancelableTask { | 
| 82 public: | 86 public: | 
| 83 Task(Heap* heap, std::vector<HeapObject*>* root_set, | 87 Task(Heap* heap, std::vector<HeapObject*>* root_set, | 
| 84 base::Semaphore* on_finish) | 88 base::Semaphore* on_finish) | 
| 85 : CancelableTask(heap->isolate()), | 89 : CancelableTask(heap->isolate()), | 
| 86 heap_(heap), | 90 heap_(heap), | 
| 87 on_finish_(on_finish), | 91 on_finish_(on_finish), | 
| 88 root_set_(root_set) {} | 92 root_set_(root_set) {} | 
| 89 | 93 | 
| 90 virtual ~Task() {} | 94 virtual ~Task() {} | 
| 91 | 95 | 
| 92 private: | 96 private: | 
| 93 // v8::internal::CancelableTask overrides. | 97 // v8::internal::CancelableTask overrides. | 
| 94 void RunInternal() override { | 98 void RunInternal() override { | 
| 95 USE(heap_); | 99 double start_time_ms = heap_->MonotonicallyIncreasingTimeInMs(); | 
| 
Michael Lippautz
2017/03/08 19:14:34
nit: There's TimedScope in utils-inl.h
e.g.
  doub
 
ulan
2017/03/10 16:45:26
Done.
 | |
| 96 for (HeapObject* obj : *root_set_) { | 100 for (HeapObject* obj : *root_set_) { | 
| 97 marking_visitor_.MarkObject(obj); | 101 marking_visitor_.MarkObject(obj); | 
| 98 } | 102 } | 
| 99 marking_visitor_.MarkTransitively(); | 103 marking_visitor_.MarkTransitively(); | 
| 104 double end_time_ms = heap_->MonotonicallyIncreasingTimeInMs(); | |
| 105 if (FLAG_trace_concurrent_marking) { | |
| 106 heap_->isolate()->PrintWithTimestamp( | |
| 107 "concurrently marked %dKB in %.2fms\n", | |
| 108 static_cast<int>(marking_visitor_.bytes_marked() / KB), | |
| 109 end_time_ms - start_time_ms); | |
| 110 } | |
| 100 on_finish_->Signal(); | 111 on_finish_->Signal(); | 
| 101 } | 112 } | 
| 102 | 113 | 
| 103 Heap* heap_; | 114 Heap* heap_; | 
| 104 base::Semaphore* on_finish_; | 115 base::Semaphore* on_finish_; | 
| 105 ConcurrentMarkingVisitor marking_visitor_; | 116 ConcurrentMarkingVisitor marking_visitor_; | 
| 106 std::vector<HeapObject*>* root_set_; | 117 std::vector<HeapObject*>* root_set_; | 
| 107 DISALLOW_COPY_AND_ASSIGN(Task); | 118 DISALLOW_COPY_AND_ASSIGN(Task); | 
| 108 }; | 119 }; | 
| 109 | 120 | 
| 110 ConcurrentMarking::ConcurrentMarking(Heap* heap) | 121 ConcurrentMarking::ConcurrentMarking(Heap* heap) | 
| 111 : heap_(heap), pending_task_(0) {} | 122 : heap_(heap), pending_task_semaphore_(0), is_task_pending_(false) { | 
| 123 // Concurrent marking does not work with double unboxing. | |
| 124 STATIC_ASSERT(!(V8_CONCURRENT_MARKING && V8_DOUBLE_FIELDS_UNBOXING)); | |
| 125 // The runtime flag should be set only if the compile time flag was set. | |
| 126 CHECK(!FLAG_concurrent_marking || V8_CONCURRENT_MARKING); | |
| 127 } | |
| 112 | 128 | 
| 113 ConcurrentMarking::~ConcurrentMarking() {} | 129 ConcurrentMarking::~ConcurrentMarking() {} | 
| 114 | 130 | 
| 115 void ConcurrentMarking::AddRoot(HeapObject* object) { | 131 void ConcurrentMarking::AddRoot(HeapObject* object) { | 
| 116 root_set_.push_back(object); | 132 root_set_.push_back(object); | 
| 117 } | 133 } | 
| 118 | 134 | 
| 119 void ConcurrentMarking::StartMarkingTask() { | 135 void ConcurrentMarking::StartMarkingTask() { | 
| 120 if (!FLAG_concurrent_marking) return; | 136 if (!FLAG_concurrent_marking) return; | 
| 137 is_task_pending_ = true; | |
| 121 | 138 | 
| 122 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 139 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 
| 123 new Task(heap_, &root_set_, &pending_task_), | 140 new Task(heap_, &root_set_, &pending_task_semaphore_), | 
| 124 v8::Platform::kShortRunningTask); | 141 v8::Platform::kShortRunningTask); | 
| 125 } | 142 } | 
| 126 | 143 | 
| 127 void ConcurrentMarking::WaitForTaskToComplete() { | 144 void ConcurrentMarking::WaitForTaskToComplete() { | 
| 128 if (!FLAG_concurrent_marking) return; | 145 if (!FLAG_concurrent_marking) return; | 
| 129 pending_task_.Wait(); | 146 pending_task_semaphore_.Wait(); | 
| 147 is_task_pending_ = false; | |
| 148 root_set_.clear(); | |
| 130 } | 149 } | 
| 131 | 150 | 
| 132 } // namespace internal | 151 } // namespace internal | 
| 133 } // namespace v8 | 152 } // namespace v8 | 
| OLD | NEW |