Commit 08f70db4 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Do not emit background GC trace events on the main thread

When the main thread contributes to an item parallel job and runs
an item parallel task, it currently emits a background GC trace event.

That is confusing and may lead to incorrect accounting of main thread
GC time. This patch fixes it by introducing a 'Runner' parameter
to ItemParalllelJob::Task::RunInParallel and emitting a foreground
GC event if the runner is the main thread.

Bug: v8:9508
Change-Id: I755751bfe9eef427666d5f16fb50aa6093059e80
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1706485Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62798}
parent 6e281ec3
...@@ -26,8 +26,12 @@ void ItemParallelJob::Task::SetupInternal(base::Semaphore* on_finish, ...@@ -26,8 +26,12 @@ void ItemParallelJob::Task::SetupInternal(base::Semaphore* on_finish,
} }
} }
void ItemParallelJob::Task::WillRunOnForeground() {
runner_ = Runner::kForeground;
}
void ItemParallelJob::Task::RunInternal() { void ItemParallelJob::Task::RunInternal() {
RunInParallel(); RunInParallel(runner_);
on_finish_->Signal(); on_finish_->Signal();
} }
...@@ -95,6 +99,7 @@ void ItemParallelJob::Run() { ...@@ -95,6 +99,7 @@ void ItemParallelJob::Run() {
// Contribute on main thread. // Contribute on main thread.
DCHECK(main_task); DCHECK(main_task);
main_task->WillRunOnForeground();
main_task->Run(); main_task->Run();
// Wait for background tasks. // Wait for background tasks.
......
...@@ -65,10 +65,11 @@ class V8_EXPORT_PRIVATE ItemParallelJob { ...@@ -65,10 +65,11 @@ class V8_EXPORT_PRIVATE ItemParallelJob {
class V8_EXPORT_PRIVATE Task : public CancelableTask { class V8_EXPORT_PRIVATE Task : public CancelableTask {
public: public:
enum class Runner { kForeground, kBackground };
explicit Task(Isolate* isolate); explicit Task(Isolate* isolate);
~Task() override = default; ~Task() override = default;
virtual void RunInParallel() = 0; virtual void RunInParallel(Runner runner) = 0;
protected: protected:
// Retrieves a new item that needs to be processed. Returns |nullptr| if // Retrieves a new item that needs to be processed. Returns |nullptr| if
...@@ -99,13 +100,14 @@ class V8_EXPORT_PRIVATE ItemParallelJob { ...@@ -99,13 +100,14 @@ class V8_EXPORT_PRIVATE ItemParallelJob {
// processing, e.g. scavenging). // processing, e.g. scavenging).
void SetupInternal(base::Semaphore* on_finish, std::vector<Item*>* items, void SetupInternal(base::Semaphore* on_finish, std::vector<Item*>* items,
size_t start_index); size_t start_index);
void WillRunOnForeground();
// We don't allow overriding this method any further. // We don't allow overriding this method any further.
void RunInternal() final; void RunInternal() final;
std::vector<Item*>* items_ = nullptr; std::vector<Item*>* items_ = nullptr;
size_t cur_index_ = 0; size_t cur_index_ = 0;
size_t items_considered_ = 0; size_t items_considered_ = 0;
Runner runner_ = Runner::kBackground;
base::Semaphore* on_finish_ = nullptr; base::Semaphore* on_finish_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(Task); DISALLOW_COPY_AND_ASSIGN(Task);
......
...@@ -2750,6 +2750,7 @@ class Evacuator : public Malloced { ...@@ -2750,6 +2750,7 @@ class Evacuator : public Malloced {
inline void Finalize(); inline void Finalize();
virtual GCTracer::BackgroundScope::ScopeId GetBackgroundTracingScope() = 0; virtual GCTracer::BackgroundScope::ScopeId GetBackgroundTracingScope() = 0;
virtual GCTracer::Scope::ScopeId GetTracingScope() = 0;
protected: protected:
static const int kInitialLocalPretenuringFeedbackCapacity = 256; static const int kInitialLocalPretenuringFeedbackCapacity = 256;
...@@ -2838,6 +2839,10 @@ class FullEvacuator : public Evacuator { ...@@ -2838,6 +2839,10 @@ class FullEvacuator : public Evacuator {
return GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_COPY; return GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_COPY;
} }
GCTracer::Scope::ScopeId GetTracingScope() override {
return GCTracer::Scope::MC_EVACUATE_COPY_PARALLEL;
}
inline void Finalize() { inline void Finalize() {
Evacuator::Finalize(); Evacuator::Finalize();
...@@ -2928,16 +2933,24 @@ class PageEvacuationTask : public ItemParallelJob::Task { ...@@ -2928,16 +2933,24 @@ class PageEvacuationTask : public ItemParallelJob::Task {
evacuator_(evacuator), evacuator_(evacuator),
tracer_(isolate->heap()->tracer()) {} tracer_(isolate->heap()->tracer()) {}
void RunInParallel() override { void RunInParallel(Runner runner) override {
TRACE_BACKGROUND_GC(tracer_, evacuator_->GetBackgroundTracingScope()); if (runner == Runner::kForeground) {
TRACE_GC(tracer_, evacuator_->GetTracingScope());
ProcessItems();
} else {
TRACE_BACKGROUND_GC(tracer_, evacuator_->GetBackgroundTracingScope());
ProcessItems();
}
}
private:
void ProcessItems() {
EvacuationItem* item = nullptr; EvacuationItem* item = nullptr;
while ((item = GetItem<EvacuationItem>()) != nullptr) { while ((item = GetItem<EvacuationItem>()) != nullptr) {
evacuator_->EvacuatePage(item->chunk()); evacuator_->EvacuatePage(item->chunk());
item->MarkFinished(); item->MarkFinished();
} }
} }
private:
Evacuator* evacuator_; Evacuator* evacuator_;
GCTracer* tracer_; GCTracer* tracer_;
}; };
...@@ -3237,24 +3250,35 @@ class UpdatingItem : public ItemParallelJob::Item { ...@@ -3237,24 +3250,35 @@ class UpdatingItem : public ItemParallelJob::Item {
class PointersUpdatingTask : public ItemParallelJob::Task { class PointersUpdatingTask : public ItemParallelJob::Task {
public: public:
explicit PointersUpdatingTask(Isolate* isolate, explicit PointersUpdatingTask(
GCTracer::BackgroundScope::ScopeId scope) Isolate* isolate, GCTracer::Scope::ScopeId scope,
GCTracer::BackgroundScope::ScopeId background_scope)
: ItemParallelJob::Task(isolate), : ItemParallelJob::Task(isolate),
tracer_(isolate->heap()->tracer()), tracer_(isolate->heap()->tracer()),
scope_(scope) {} scope_(scope),
background_scope_(background_scope) {}
void RunInParallel(Runner runner) override {
if (runner == Runner::kForeground) {
TRACE_GC(tracer_, scope_);
UpdatePointers();
} else {
TRACE_BACKGROUND_GC(tracer_, background_scope_);
UpdatePointers();
}
}
void RunInParallel() override { private:
TRACE_BACKGROUND_GC(tracer_, scope_); void UpdatePointers() {
UpdatingItem* item = nullptr; UpdatingItem* item = nullptr;
while ((item = GetItem<UpdatingItem>()) != nullptr) { while ((item = GetItem<UpdatingItem>()) != nullptr) {
item->Process(); item->Process();
item->MarkFinished(); item->MarkFinished();
} }
} }
private:
GCTracer* tracer_; GCTracer* tracer_;
GCTracer::BackgroundScope::ScopeId scope_; GCTracer::Scope::ScopeId scope_;
GCTracer::BackgroundScope::ScopeId background_scope_;
}; };
template <typename MarkingState> template <typename MarkingState>
...@@ -3670,7 +3694,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() { ...@@ -3670,7 +3694,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
remembered_set_tasks + num_ephemeron_table_updating_tasks); remembered_set_tasks + num_ephemeron_table_updating_tasks);
for (int i = 0; i < num_tasks; i++) { for (int i = 0; i < num_tasks; i++) {
updating_job.AddTask(new PointersUpdatingTask( updating_job.AddTask(new PointersUpdatingTask(
isolate(), isolate(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_PARALLEL,
GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_UPDATE_POINTERS)); GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_UPDATE_POINTERS));
} }
updating_job.AddItem(new EphemeronTableUpdatingItem(heap())); updating_job.AddItem(new EphemeronTableUpdatingItem(heap()));
...@@ -3703,7 +3727,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() { ...@@ -3703,7 +3727,7 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
if (num_tasks > 0) { if (num_tasks > 0) {
for (int i = 0; i < num_tasks; i++) { for (int i = 0; i < num_tasks; i++) {
updating_job.AddTask(new PointersUpdatingTask( updating_job.AddTask(new PointersUpdatingTask(
isolate(), isolate(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_PARALLEL,
GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_UPDATE_POINTERS)); GCTracer::BackgroundScope::MC_BACKGROUND_EVACUATE_UPDATE_POINTERS));
} }
updating_job.Run(); updating_job.Run();
...@@ -4213,8 +4237,9 @@ void MinorMarkCompactCollector::UpdatePointersAfterEvacuation() { ...@@ -4213,8 +4237,9 @@ void MinorMarkCompactCollector::UpdatePointersAfterEvacuation() {
const int num_tasks = Max(to_space_tasks, remembered_set_tasks); const int num_tasks = Max(to_space_tasks, remembered_set_tasks);
for (int i = 0; i < num_tasks; i++) { for (int i = 0; i < num_tasks; i++) {
updating_job.AddTask(new PointersUpdatingTask( updating_job.AddTask(new PointersUpdatingTask(
isolate(), GCTracer::BackgroundScope:: isolate(), GCTracer::Scope::MINOR_MC_EVACUATE_UPDATE_POINTERS_PARALLEL,
MINOR_MC_BACKGROUND_EVACUATE_UPDATE_POINTERS)); GCTracer::BackgroundScope::
MINOR_MC_BACKGROUND_EVACUATE_UPDATE_POINTERS));
} }
{ {
...@@ -4517,9 +4542,30 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task { ...@@ -4517,9 +4542,30 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task {
Page::kPageSize); Page::kPageSize);
} }
void RunInParallel() override { void RunInParallel(Runner runner) override {
TRACE_BACKGROUND_GC(collector_->heap()->tracer(), if (runner == Runner::kForeground) {
GCTracer::BackgroundScope::MINOR_MC_BACKGROUND_MARKING); TRACE_GC(collector_->heap()->tracer(),
GCTracer::Scope::MINOR_MC_MARK_PARALLEL);
ProcessItems();
} else {
TRACE_BACKGROUND_GC(
collector_->heap()->tracer(),
GCTracer::BackgroundScope::MINOR_MC_BACKGROUND_MARKING);
ProcessItems();
}
}
void MarkObject(Object object) {
if (!Heap::InYoungGeneration(object)) return;
HeapObject heap_object = HeapObject::cast(object);
if (marking_state_->WhiteToGrey(heap_object)) {
const int size = visitor_.Visit(heap_object);
IncrementLiveBytes(heap_object, size);
}
}
private:
void ProcessItems() {
double marking_time = 0.0; double marking_time = 0.0;
{ {
TimedScope scope(&marking_time); TimedScope scope(&marking_time);
...@@ -4538,17 +4584,6 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task { ...@@ -4538,17 +4584,6 @@ class YoungGenerationMarkingTask : public ItemParallelJob::Task {
static_cast<void*>(this), marking_time); static_cast<void*>(this), marking_time);
} }
} }
void MarkObject(Object object) {
if (!Heap::InYoungGeneration(object)) return;
HeapObject heap_object = HeapObject::cast(object);
if (marking_state_->WhiteToGrey(heap_object)) {
const int size = visitor_.Visit(heap_object);
IncrementLiveBytes(heap_object, size);
}
}
private:
void EmptyLocalMarkingWorklist() { void EmptyLocalMarkingWorklist() {
HeapObject object; HeapObject object;
while (marking_worklist_.Pop(&object)) { while (marking_worklist_.Pop(&object)) {
...@@ -4780,6 +4815,10 @@ class YoungGenerationEvacuator : public Evacuator { ...@@ -4780,6 +4815,10 @@ class YoungGenerationEvacuator : public Evacuator {
return GCTracer::BackgroundScope::MINOR_MC_BACKGROUND_EVACUATE_COPY; return GCTracer::BackgroundScope::MINOR_MC_BACKGROUND_EVACUATE_COPY;
} }
GCTracer::Scope::ScopeId GetTracingScope() override {
return GCTracer::Scope::MINOR_MC_EVACUATE_COPY_PARALLEL;
}
protected: protected:
void RawEvacuatePage(MemoryChunk* chunk, intptr_t* live_bytes) override; void RawEvacuatePage(MemoryChunk* chunk, intptr_t* live_bytes) override;
......
...@@ -41,10 +41,20 @@ class ScavengingTask final : public ItemParallelJob::Task { ...@@ -41,10 +41,20 @@ class ScavengingTask final : public ItemParallelJob::Task {
scavenger_(scavenger), scavenger_(scavenger),
barrier_(barrier) {} barrier_(barrier) {}
void RunInParallel() final { void RunInParallel(Runner runner) final {
TRACE_BACKGROUND_GC( if (runner == Runner::kForeground) {
heap_->tracer(), TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_SCAVENGE_PARALLEL);
GCTracer::BackgroundScope::SCAVENGER_BACKGROUND_SCAVENGE_PARALLEL); ProcessItems();
} else {
TRACE_BACKGROUND_GC(
heap_->tracer(),
GCTracer::BackgroundScope::SCAVENGER_BACKGROUND_SCAVENGE_PARALLEL);
ProcessItems();
}
}
private:
void ProcessItems() {
double scavenging_time = 0.0; double scavenging_time = 0.0;
{ {
barrier_->Start(); barrier_->Start();
...@@ -66,8 +76,6 @@ class ScavengingTask final : public ItemParallelJob::Task { ...@@ -66,8 +76,6 @@ class ScavengingTask final : public ItemParallelJob::Task {
scavenger_->bytes_copied(), scavenger_->bytes_promoted()); scavenger_->bytes_copied(), scavenger_->bytes_promoted());
} }
} }
private:
Heap* const heap_; Heap* const heap_;
Scavenger* const scavenger_; Scavenger* const scavenger_;
OneshotBarrier* const barrier_; OneshotBarrier* const barrier_;
......
...@@ -416,10 +416,12 @@ ...@@ -416,10 +416,12 @@
F(MC_EVACUATE_CANDIDATES) \ F(MC_EVACUATE_CANDIDATES) \
F(MC_EVACUATE_CLEAN_UP) \ F(MC_EVACUATE_CLEAN_UP) \
F(MC_EVACUATE_COPY) \ F(MC_EVACUATE_COPY) \
F(MC_EVACUATE_COPY_PARALLEL) \
F(MC_EVACUATE_EPILOGUE) \ F(MC_EVACUATE_EPILOGUE) \
F(MC_EVACUATE_PROLOGUE) \ F(MC_EVACUATE_PROLOGUE) \
F(MC_EVACUATE_REBALANCE) \ F(MC_EVACUATE_REBALANCE) \
F(MC_EVACUATE_UPDATE_POINTERS) \ F(MC_EVACUATE_UPDATE_POINTERS) \
F(MC_EVACUATE_UPDATE_POINTERS_PARALLEL) \
F(MC_EVACUATE_UPDATE_POINTERS_SLOTS_MAIN) \ F(MC_EVACUATE_UPDATE_POINTERS_SLOTS_MAIN) \
F(MC_EVACUATE_UPDATE_POINTERS_SLOTS_MAP_SPACE) \ F(MC_EVACUATE_UPDATE_POINTERS_SLOTS_MAP_SPACE) \
F(MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \ F(MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \
...@@ -447,15 +449,18 @@ ...@@ -447,15 +449,18 @@
F(MINOR_MC_EVACUATE) \ F(MINOR_MC_EVACUATE) \
F(MINOR_MC_EVACUATE_CLEAN_UP) \ F(MINOR_MC_EVACUATE_CLEAN_UP) \
F(MINOR_MC_EVACUATE_COPY) \ F(MINOR_MC_EVACUATE_COPY) \
F(MINOR_MC_EVACUATE_COPY_PARALLEL) \
F(MINOR_MC_EVACUATE_EPILOGUE) \ F(MINOR_MC_EVACUATE_EPILOGUE) \
F(MINOR_MC_EVACUATE_PROLOGUE) \ F(MINOR_MC_EVACUATE_PROLOGUE) \
F(MINOR_MC_EVACUATE_REBALANCE) \ F(MINOR_MC_EVACUATE_REBALANCE) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_PARALLEL) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_SLOTS) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_SLOTS) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_TO_NEW_ROOTS) \
F(MINOR_MC_EVACUATE_UPDATE_POINTERS_WEAK) \ F(MINOR_MC_EVACUATE_UPDATE_POINTERS_WEAK) \
F(MINOR_MC_MARK) \ F(MINOR_MC_MARK) \
F(MINOR_MC_MARK_GLOBAL_HANDLES) \ F(MINOR_MC_MARK_GLOBAL_HANDLES) \
F(MINOR_MC_MARK_PARALLEL) \
F(MINOR_MC_MARK_SEED) \ F(MINOR_MC_MARK_SEED) \
F(MINOR_MC_MARK_ROOTS) \ F(MINOR_MC_MARK_ROOTS) \
F(MINOR_MC_MARK_WEAK) \ F(MINOR_MC_MARK_WEAK) \
......
...@@ -28,7 +28,7 @@ class SimpleTask : public ItemParallelJob::Task { ...@@ -28,7 +28,7 @@ class SimpleTask : public ItemParallelJob::Task {
SimpleTask(Isolate* isolate, bool* did_run) SimpleTask(Isolate* isolate, bool* did_run)
: ItemParallelJob::Task(isolate), did_run_(did_run) {} : ItemParallelJob::Task(isolate), did_run_(did_run) {}
void RunInParallel() override { void RunInParallel(Runner runner) override {
ItemParallelJob::Item* item = nullptr; ItemParallelJob::Item* item = nullptr;
while ((item = GetItem<ItemParallelJob::Item>()) != nullptr) { while ((item = GetItem<ItemParallelJob::Item>()) != nullptr) {
item->MarkFinished(); item->MarkFinished();
...@@ -58,7 +58,7 @@ class EagerTask : public ItemParallelJob::Task { ...@@ -58,7 +58,7 @@ class EagerTask : public ItemParallelJob::Task {
public: public:
explicit EagerTask(Isolate* isolate) : ItemParallelJob::Task(isolate) {} explicit EagerTask(Isolate* isolate) : ItemParallelJob::Task(isolate) {}
void RunInParallel() override { void RunInParallel(Runner runner) override {
SimpleItem* item = nullptr; SimpleItem* item = nullptr;
while ((item = GetItem<SimpleItem>()) != nullptr) { while ((item = GetItem<SimpleItem>()) != nullptr) {
item->Process(); item->Process();
...@@ -120,7 +120,7 @@ class TaskProcessingOneItem : public ItemParallelJob::Task { ...@@ -120,7 +120,7 @@ class TaskProcessingOneItem : public ItemParallelJob::Task {
wait_when_done_(wait_when_done), wait_when_done_(wait_when_done),
did_process_an_item_(did_process_an_item) {} did_process_an_item_(did_process_an_item) {}
void RunInParallel() override { void RunInParallel(Runner runner) override {
SimpleItem* item = GetItem<SimpleItem>(); SimpleItem* item = GetItem<SimpleItem>();
if (did_process_an_item_) { if (did_process_an_item_) {
...@@ -164,7 +164,7 @@ class TaskForDifferentItems : public ItemParallelJob::Task { ...@@ -164,7 +164,7 @@ class TaskForDifferentItems : public ItemParallelJob::Task {
processed_b_(processed_b) {} processed_b_(processed_b) {}
~TaskForDifferentItems() override = default; ~TaskForDifferentItems() override = default;
void RunInParallel() override { void RunInParallel(Runner runner) override {
BaseItem* item = nullptr; BaseItem* item = nullptr;
while ((item = GetItem<BaseItem>()) != nullptr) { while ((item = GetItem<BaseItem>()) != nullptr) {
item->ProcessItem(this); item->ProcessItem(this);
......
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