Index: src/heap/concurrent-marking.cc |
diff --git a/src/heap/concurrent-marking.cc b/src/heap/concurrent-marking.cc |
index d47eea01153ae0610c43323e038a25e24810da98..c29e23c4c298d29c32a0fc02279d626632178219 100644 |
--- a/src/heap/concurrent-marking.cc |
+++ b/src/heap/concurrent-marking.cc |
@@ -12,6 +12,8 @@ |
#include "src/heap/marking.h" |
#include "src/isolate.h" |
#include "src/locked-queue-inl.h" |
+#include "src/utils-inl.h" |
+#include "src/utils.h" |
#include "src/v8.h" |
namespace v8 { |
@@ -50,7 +52,7 @@ class ConcurrentMarkingMarkbits { |
class ConcurrentMarkingVisitor : public ObjectVisitor { |
public: |
- ConcurrentMarkingVisitor() {} |
+ ConcurrentMarkingVisitor() : bytes_marked_(0) {} |
void VisitPointers(Object** start, Object** end) override { |
for (Object** p = start; p < end; p++) { |
@@ -61,6 +63,7 @@ class ConcurrentMarkingVisitor : public ObjectVisitor { |
void MarkObject(HeapObject* obj) { |
if (markbits_.Mark(obj)) { |
+ bytes_marked_ += obj->Size(); |
marking_stack_.push(obj); |
} |
} |
@@ -73,7 +76,10 @@ class ConcurrentMarkingVisitor : public ObjectVisitor { |
} |
} |
+ size_t bytes_marked() { return bytes_marked_; } |
+ |
private: |
+ size_t bytes_marked_; |
std::stack<HeapObject*> marking_stack_; |
ConcurrentMarkingMarkbits markbits_; |
}; |
@@ -92,11 +98,19 @@ class ConcurrentMarking::Task : public CancelableTask { |
private: |
// v8::internal::CancelableTask overrides. |
void RunInternal() override { |
- USE(heap_); |
- for (HeapObject* obj : *root_set_) { |
- marking_visitor_.MarkObject(obj); |
+ double time_ms = heap_->MonotonicallyIncreasingTimeInMs(); |
+ { |
+ TimedScope scope(&time_ms); |
+ for (HeapObject* obj : *root_set_) { |
+ marking_visitor_.MarkObject(obj); |
+ } |
+ marking_visitor_.MarkTransitively(); |
+ } |
+ if (FLAG_trace_concurrent_marking) { |
+ heap_->isolate()->PrintWithTimestamp( |
+ "concurrently marked %dKB in %.2fms\n", |
+ static_cast<int>(marking_visitor_.bytes_marked() / KB), time_ms); |
} |
- marking_visitor_.MarkTransitively(); |
on_finish_->Signal(); |
} |
@@ -108,7 +122,12 @@ class ConcurrentMarking::Task : public CancelableTask { |
}; |
ConcurrentMarking::ConcurrentMarking(Heap* heap) |
- : heap_(heap), pending_task_(0) {} |
+ : heap_(heap), pending_task_semaphore_(0), is_task_pending_(false) { |
+ // Concurrent marking does not work with double unboxing. |
+ STATIC_ASSERT(!(V8_CONCURRENT_MARKING && V8_DOUBLE_FIELDS_UNBOXING)); |
+ // The runtime flag should be set only if the compile time flag was set. |
+ CHECK(!FLAG_concurrent_marking || V8_CONCURRENT_MARKING); |
+} |
ConcurrentMarking::~ConcurrentMarking() {} |
@@ -116,17 +135,26 @@ void ConcurrentMarking::AddRoot(HeapObject* object) { |
root_set_.push_back(object); |
} |
-void ConcurrentMarking::StartMarkingTask() { |
+void ConcurrentMarking::StartTask() { |
if (!FLAG_concurrent_marking) return; |
+ is_task_pending_ = true; |
V8::GetCurrentPlatform()->CallOnBackgroundThread( |
- new Task(heap_, &root_set_, &pending_task_), |
+ new Task(heap_, &root_set_, &pending_task_semaphore_), |
v8::Platform::kShortRunningTask); |
} |
void ConcurrentMarking::WaitForTaskToComplete() { |
if (!FLAG_concurrent_marking) return; |
- pending_task_.Wait(); |
+ pending_task_semaphore_.Wait(); |
+ is_task_pending_ = false; |
+ root_set_.clear(); |
+} |
+ |
+void ConcurrentMarking::EnsureTaskCompleted() { |
+ if (IsTaskPending()) { |
+ WaitForTaskToComplete(); |
+ } |
} |
} // namespace internal |