| 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..308d1b9a29f114ddfc7c613edf1a895b8696fccc
|
| --- /dev/null
|
| +++ b/src/heap/incremental-marking-job.cc
|
| @@ -0,0 +1,144 @@
|
| +// 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::Start(Heap* heap) {
|
| + DCHECK(!heap->incremental_marking()->IsStopped());
|
| + // We don't need to reset the flags because tasks from the previous job
|
| + // can still be pending. We just want to ensure that tasks are posted
|
| + // if they are not pending.
|
| + // If delayed task is pending and made_progress_since_last_delayed_task_ is
|
| + // true, then the delayed task will clear that flag when it is rescheduled.
|
| + ScheduleIdleTask(heap);
|
| + ScheduleDelayedTask(heap);
|
| +}
|
| +
|
| +
|
| +void IncrementalMarkingJob::NotifyIdleTask() { idle_task_pending_ = false; }
|
| +
|
| +
|
| +void IncrementalMarkingJob::NotifyDelayedTask() {
|
| + delayed_task_pending_ = false;
|
| +}
|
| +
|
| +
|
| +void IncrementalMarkingJob::NotifyIdleTaskProgress() {
|
| + made_progress_since_last_delayed_task_ = true;
|
| +}
|
| +
|
| +
|
| +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_) {
|
| + 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_->NotifyIdleTaskProgress();
|
| + 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
|
|
|