Chromium Code Reviews| Index: src/heap/incremental-marking-job.cc |
| diff --git a/src/heap/incremental-marking-job.cc b/src/heap/incremental-marking-job.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1e1f1bdaac569857b61c0c6a00ccf68956e308f5 |
| --- /dev/null |
| +++ b/src/heap/incremental-marking-job.cc |
| @@ -0,0 +1,133 @@ |
| +// Copyright 2012 the V8 project authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "src/heap/incremental-marking-job.h" |
| + |
| +#include "src/base/platform/time.h" |
| +#include "src/heap/heap-inl.h" |
| +#include "src/heap/heap.h" |
| +#include "src/heap/incremental-marking.h" |
| +#include "src/isolate.h" |
| +#include "src/v8.h" |
| + |
| +namespace v8 { |
| +namespace internal { |
| + |
| + |
| +void IncrementalMarkingJob::NotifyIdleTask() { idle_task_pending_ = false; } |
| + |
| + |
| +void IncrementalMarkingJob::NotifyDelayedTask() { |
| + delayed_task_pending_ = false; |
| +} |
| + |
| + |
| +void IncrementalMarkingJob::NotifyProgress() { |
| + made_progress_since_last_delayed_task_ = false; |
|
Michael Lippautz
2015/09/08 10:16:26
This should be true, I guess. Otherwise the Delaye
ulan
2015/09/08 11:34:53
Good catch! This slipped through during last minut
|
| +} |
| + |
| + |
| +void IncrementalMarkingJob::ScheduleIdleTask(Heap* heap) { |
| + if (!idle_task_pending_) { |
| + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate()); |
| + if (V8::GetCurrentPlatform()->IdleTasksEnabled(isolate)) { |
| + idle_task_pending_ = true; |
| + auto task = new IdleTask(heap->isolate(), this); |
| + V8::GetCurrentPlatform()->CallIdleOnForegroundThread(isolate, task); |
| + } |
| + } |
| +} |
| + |
| + |
| +void IncrementalMarkingJob::ScheduleDelayedTask(Heap* heap) { |
| + if (!delayed_task_pending_) { |
| + const int kDelayInSeconds = 5; |
|
Michael Lippautz
2015/09/08 10:16:26
nit: Can we make this a constant in IncrementalMar
ulan
2015/09/08 11:34:53
Done.
|
| + v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate()); |
| + delayed_task_pending_ = true; |
| + made_progress_since_last_delayed_task_ = false; |
| + auto task = new DelayedTask(heap->isolate(), this); |
| + V8::GetCurrentPlatform()->CallDelayedOnForegroundThread(isolate, task, |
| + kDelayInSeconds); |
| + } |
| +} |
| + |
| + |
| +IncrementalMarkingJob::IdleTask::Progress IncrementalMarkingJob::IdleTask::Step( |
| + Heap* heap, double deadline_in_ms) { |
| + IncrementalMarking* incremental_marking = heap->incremental_marking(); |
| + MarkCompactCollector* mark_compact_collector = heap->mark_compact_collector(); |
| + if (incremental_marking->IsStopped()) { |
| + return kDone; |
| + } |
| + if (mark_compact_collector->sweeping_in_progress()) { |
| + if (mark_compact_collector->IsSweepingCompleted()) { |
| + mark_compact_collector->EnsureSweepingCompleted(); |
| + } |
| + return kMoreWork; |
| + } |
| + const double remaining_idle_time_in_ms = heap->AdvanceIncrementalMarking( |
| + 0, deadline_in_ms, IncrementalMarking::IdleStepActions()); |
| + if (remaining_idle_time_in_ms > 0.0) { |
| + heap->TryFinalizeIdleIncrementalMarking(remaining_idle_time_in_ms); |
| + } |
| + return incremental_marking->IsStopped() ? kDone : kMoreWork; |
| +} |
| + |
| + |
| +void IncrementalMarkingJob::IdleTask::RunInternal(double deadline_in_seconds) { |
| + double deadline_in_ms = |
| + deadline_in_seconds * |
| + static_cast<double>(base::Time::kMillisecondsPerSecond); |
| + Heap* heap = isolate_->heap(); |
| + double start_ms = heap->MonotonicallyIncreasingTimeInMs(); |
| + job_->NotifyIdleTask(); |
| + job_->NotifyProgress(); |
| + if (Step(heap, deadline_in_ms) == kMoreWork) { |
| + job_->ScheduleIdleTask(heap); |
| + } |
| + if (FLAG_trace_idle_notification) { |
| + double current_time_ms = heap->MonotonicallyIncreasingTimeInMs(); |
| + double idle_time_in_ms = deadline_in_ms - start_ms; |
| + double deadline_difference = deadline_in_ms - current_time_ms; |
| + PrintIsolate(isolate_, "%8.0f ms: ", isolate_->time_millis_since_init()); |
| + PrintF( |
| + "Idle task: requested idle time %.2f ms, used idle time %.2f " |
| + "ms, deadline usage %.2f ms\n", |
| + idle_time_in_ms, idle_time_in_ms - deadline_difference, |
| + deadline_difference); |
| + } |
| +} |
| + |
| + |
| +void IncrementalMarkingJob::DelayedTask::Step(Heap* heap) { |
| + const int kIncrementalMarkingDelayMs = 50; |
| + double deadline = |
| + heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs; |
| + heap->AdvanceIncrementalMarking( |
| + 0, deadline, i::IncrementalMarking::StepActions( |
| + i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, |
| + i::IncrementalMarking::FORCE_MARKING, |
| + i::IncrementalMarking::FORCE_COMPLETION)); |
| + heap->FinalizeIncrementalMarkingIfComplete( |
| + "Incremental marking task: finalize incremental marking"); |
| +} |
| + |
| + |
| +void IncrementalMarkingJob::DelayedTask::RunInternal() { |
| + Heap* heap = isolate_->heap(); |
| + job_->NotifyDelayedTask(); |
| + IncrementalMarking* incremental_marking = heap->incremental_marking(); |
| + if (!incremental_marking->IsStopped()) { |
| + if (job_->ShouldForceMarkingStep()) { |
| + Step(heap); |
| + } |
| + // The Step() above could have finished incremental marking. |
| + if (!incremental_marking->IsStopped()) { |
| + job_->ScheduleDelayedTask(heap); |
| + } |
| + } |
| +} |
| + |
| +} // namespace internal |
| +} // namespace v8 |