1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/heap/incremental-marking-job.h"
6
7#include "src/base/platform/time.h"
8#include "src/heap/heap-inl.h"
9#include "src/heap/heap.h"
10#include "src/heap/incremental-marking.h"
11#include "src/isolate.h"
12#include "src/v8.h"
13
14namespace v8 {
15namespace internal {
16
17void IncrementalMarkingJob::Start(Heap* heap) {
18  DCHECK(!heap->incremental_marking()->IsStopped());
19  ScheduleTask(heap);
20}
21
22void IncrementalMarkingJob::NotifyTask() { task_pending_ = false; }
23
24void IncrementalMarkingJob::ScheduleTask(Heap* heap) {
25  if (!task_pending_) {
26    v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
27    task_pending_ = true;
28    auto task = new Task(heap->isolate(), this);
29    V8::GetCurrentPlatform()->CallOnForegroundThread(isolate, task);
30  }
31}
32
33void IncrementalMarkingJob::Task::Step(Heap* heap) {
34  const int kIncrementalMarkingDelayMs = 1;
35  double deadline =
36      heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs;
37  heap->incremental_marking()->AdvanceIncrementalMarking(
38      deadline, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD,
39      i::IncrementalMarking::FORCE_COMPLETION, i::StepOrigin::kTask);
40  heap->FinalizeIncrementalMarkingIfComplete(
41      GarbageCollectionReason::kFinalizeMarkingViaTask);
42}
43
44void IncrementalMarkingJob::Task::RunInternal() {
45  Heap* heap = isolate()->heap();
46  job_->NotifyTask();
47  IncrementalMarking* incremental_marking = heap->incremental_marking();
48  if (incremental_marking->IsStopped()) {
49    if (heap->IncrementalMarkingLimitReached() !=
50        Heap::IncrementalMarkingLimit::kNoLimit) {
51      heap->StartIncrementalMarking(Heap::kNoGCFlags,
52                                    GarbageCollectionReason::kIdleTask,
53                                    kNoGCCallbackFlags);
54    }
55  }
56  if (!incremental_marking->IsStopped()) {
57    Step(heap);
58    if (!incremental_marking->IsStopped()) {
59      job_->ScheduleTask(heap);
60    }
61  }
62}
63
64}  // namespace internal
65}  // namespace v8
66