Commit 047e906d authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Process weak cells in concurrent marking visitor.

BUG=chromium:694255

Change-Id: I6684850ae9759f719e3ed665157eaea2581a65cf
Reviewed-on: https://chromium-review.googlesource.com/590008
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46964}
parent 3eb4de34
...@@ -48,10 +48,13 @@ class ConcurrentMarkingVisitor final ...@@ -48,10 +48,13 @@ class ConcurrentMarkingVisitor final
public: public:
using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>; using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>;
explicit ConcurrentMarkingVisitor(ConcurrentMarking::MarkingWorklist* shared, explicit ConcurrentMarkingVisitor(
ConcurrentMarking::MarkingWorklist* bailout, ConcurrentMarking::MarkingWorklist* shared,
int task_id) ConcurrentMarking::MarkingWorklist* bailout,
: shared_(shared, task_id), bailout_(bailout, task_id) {} ConcurrentMarking::WeakCellWorklist* weak_cells, int task_id)
: shared_(shared, task_id),
bailout_(bailout, task_id),
weak_cells_(weak_cells, task_id) {}
bool ShouldVisit(HeapObject* object) { bool ShouldVisit(HeapObject* object) {
return ObjectMarking::GreyToBlack<AccessMode::ATOMIC>( return ObjectMarking::GreyToBlack<AccessMode::ATOMIC>(
...@@ -198,9 +201,21 @@ class ConcurrentMarkingVisitor final ...@@ -198,9 +201,21 @@ class ConcurrentMarkingVisitor final
} }
int VisitWeakCell(Map* map, WeakCell* object) { int VisitWeakCell(Map* map, WeakCell* object) {
// TODO(ulan): implement iteration of strong fields. if (!ShouldVisit(object)) return 0;
bailout_.Push(object); VisitMapPointer(object, object->map_slot());
return 0; if (!object->cleared()) {
HeapObject* value = HeapObject::cast(object->value());
if (ObjectMarking::IsBlackOrGrey<AccessMode::ATOMIC>(
value, marking_state(value))) {
// TODO(ulan): Record slot for value.
} else {
// If we do not know about liveness of values of weak cells, we have to
// process them when we know the liveness of the whole transitive
// closure.
weak_cells_.Push(object);
}
}
return WeakCell::BodyDescriptor::SizeOf(map, object);
} }
int VisitJSWeakCollection(Map* map, JSWeakCollection* object) { int VisitJSWeakCollection(Map* map, JSWeakCollection* object) {
...@@ -261,6 +276,7 @@ class ConcurrentMarkingVisitor final ...@@ -261,6 +276,7 @@ class ConcurrentMarkingVisitor final
ConcurrentMarking::MarkingWorklist::View shared_; ConcurrentMarking::MarkingWorklist::View shared_;
ConcurrentMarking::MarkingWorklist::View bailout_; ConcurrentMarking::MarkingWorklist::View bailout_;
ConcurrentMarking::WeakCellWorklist::View weak_cells_;
SlotSnapshot slot_snapshot_; SlotSnapshot slot_snapshot_;
}; };
...@@ -288,10 +304,12 @@ class ConcurrentMarking::Task : public CancelableTask { ...@@ -288,10 +304,12 @@ class ConcurrentMarking::Task : public CancelableTask {
}; };
ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared, ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
MarkingWorklist* bailout) MarkingWorklist* bailout,
WeakCellWorklist* weak_cells)
: heap_(heap), : heap_(heap),
shared_(shared), shared_(shared),
bailout_(bailout), bailout_(bailout),
weak_cells_(weak_cells),
pending_task_count_(0) { pending_task_count_(0) {
// The runtime flag should be set only if the compile time flag was set. // The runtime flag should be set only if the compile time flag was set.
#ifndef V8_CONCURRENT_MARKING #ifndef V8_CONCURRENT_MARKING
...@@ -303,7 +321,7 @@ ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared, ...@@ -303,7 +321,7 @@ ConcurrentMarking::ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
} }
void ConcurrentMarking::Run(int task_id, base::Mutex* lock) { void ConcurrentMarking::Run(int task_id, base::Mutex* lock) {
ConcurrentMarkingVisitor visitor(shared_, bailout_, task_id); ConcurrentMarkingVisitor visitor(shared_, bailout_, weak_cells_, task_id);
double time_ms; double time_ms;
size_t bytes_marked = 0; size_t bytes_marked = 0;
if (FLAG_trace_concurrent_marking) { if (FLAG_trace_concurrent_marking) {
...@@ -332,6 +350,7 @@ void ConcurrentMarking::Run(int task_id, base::Mutex* lock) { ...@@ -332,6 +350,7 @@ void ConcurrentMarking::Run(int task_id, base::Mutex* lock) {
base::LockGuard<base::Mutex> guard(lock); base::LockGuard<base::Mutex> guard(lock);
bailout_->FlushToGlobal(task_id); bailout_->FlushToGlobal(task_id);
} }
weak_cells_->FlushToGlobal(task_id);
{ {
base::LockGuard<base::Mutex> guard(&pending_lock_); base::LockGuard<base::Mutex> guard(&pending_lock_);
is_pending_[task_id] = false; is_pending_[task_id] = false;
......
...@@ -16,6 +16,7 @@ namespace internal { ...@@ -16,6 +16,7 @@ namespace internal {
class Heap; class Heap;
class Isolate; class Isolate;
class WeakCell;
class ConcurrentMarking { class ConcurrentMarking {
public: public:
...@@ -32,9 +33,10 @@ class ConcurrentMarking { ...@@ -32,9 +33,10 @@ class ConcurrentMarking {
static const int kTasks = 4; static const int kTasks = 4;
using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>; using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>;
using WeakCellWorklist = Worklist<WeakCell*, 64 /* segment size */>;
ConcurrentMarking(Heap* heap, MarkingWorklist* shared_, ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
MarkingWorklist* bailout_); MarkingWorklist* bailout, WeakCellWorklist* weak_cells);
void ScheduleTasks(); void ScheduleTasks();
void EnsureCompleted(); void EnsureCompleted();
...@@ -50,6 +52,7 @@ class ConcurrentMarking { ...@@ -50,6 +52,7 @@ class ConcurrentMarking {
Heap* heap_; Heap* heap_;
MarkingWorklist* shared_; MarkingWorklist* shared_;
MarkingWorklist* bailout_; MarkingWorklist* bailout_;
WeakCellWorklist* weak_cells_;
TaskLock task_lock_[kTasks + 1]; TaskLock task_lock_[kTasks + 1];
base::Mutex pending_lock_; base::Mutex pending_lock_;
base::ConditionVariable pending_condition_; base::ConditionVariable pending_condition_;
......
...@@ -5969,10 +5969,11 @@ bool Heap::SetUp() { ...@@ -5969,10 +5969,11 @@ bool Heap::SetUp() {
#ifdef V8_CONCURRENT_MARKING #ifdef V8_CONCURRENT_MARKING
MarkCompactCollector::MarkingWorklist* marking_worklist = MarkCompactCollector::MarkingWorklist* marking_worklist =
mark_compact_collector_->marking_worklist(); mark_compact_collector_->marking_worklist();
concurrent_marking_ = new ConcurrentMarking(this, marking_worklist->shared(), concurrent_marking_ = new ConcurrentMarking(
marking_worklist->bailout()); this, marking_worklist->shared(), marking_worklist->bailout(),
mark_compact_collector_->weak_cells());
#else #else
concurrent_marking_ = new ConcurrentMarking(this, nullptr, nullptr); concurrent_marking_ = new ConcurrentMarking(this, nullptr, nullptr, nullptr);
#endif #endif
minor_mark_compact_collector_ = new MinorMarkCompactCollector(this); minor_mark_compact_collector_ = new MinorMarkCompactCollector(this);
gc_idle_time_handler_ = new GCIdleTimeHandler(); gc_idle_time_handler_ = new GCIdleTimeHandler();
......
...@@ -642,6 +642,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -642,6 +642,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
MarkingWorklist* marking_worklist() { return &marking_worklist_; } MarkingWorklist* marking_worklist() { return &marking_worklist_; }
WeakCellWorklist* weak_cells() { return &weak_cells_; }
void AddWeakCell(WeakCell* weak_cell) { void AddWeakCell(WeakCell* weak_cell) {
weak_cells_.Push(kMainThread, weak_cell); weak_cells_.Push(kMainThread, weak_cell);
} }
......
...@@ -30,8 +30,9 @@ TEST(ConcurrentMarking) { ...@@ -30,8 +30,9 @@ TEST(ConcurrentMarking) {
CcTest::InitializeVM(); CcTest::InitializeVM();
Heap* heap = CcTest::heap(); Heap* heap = CcTest::heap();
ConcurrentMarking::MarkingWorklist shared, bailout; ConcurrentMarking::MarkingWorklist shared, bailout;
ConcurrentMarking::WeakCellWorklist weak_cells;
ConcurrentMarking* concurrent_marking = ConcurrentMarking* concurrent_marking =
new ConcurrentMarking(heap, &shared, &bailout); new ConcurrentMarking(heap, &shared, &bailout, &weak_cells);
PublishSegment(&shared, heap->undefined_value()); PublishSegment(&shared, heap->undefined_value());
concurrent_marking->ScheduleTasks(); concurrent_marking->ScheduleTasks();
concurrent_marking->EnsureCompleted(); concurrent_marking->EnsureCompleted();
...@@ -43,8 +44,9 @@ TEST(ConcurrentMarkingReschedule) { ...@@ -43,8 +44,9 @@ TEST(ConcurrentMarkingReschedule) {
CcTest::InitializeVM(); CcTest::InitializeVM();
Heap* heap = CcTest::heap(); Heap* heap = CcTest::heap();
ConcurrentMarking::MarkingWorklist shared, bailout; ConcurrentMarking::MarkingWorklist shared, bailout;
ConcurrentMarking::WeakCellWorklist weak_cells;
ConcurrentMarking* concurrent_marking = ConcurrentMarking* concurrent_marking =
new ConcurrentMarking(heap, &shared, &bailout); new ConcurrentMarking(heap, &shared, &bailout, &weak_cells);
PublishSegment(&shared, heap->undefined_value()); PublishSegment(&shared, heap->undefined_value());
concurrent_marking->ScheduleTasks(); concurrent_marking->ScheduleTasks();
concurrent_marking->EnsureCompleted(); concurrent_marking->EnsureCompleted();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment