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 |