V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
incremental-marking-job.cc
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/embedder-tracing.h"
9 #include "src/heap/heap-inl.h"
10 #include "src/heap/heap.h"
11 #include "src/heap/incremental-marking.h"
12 #include "src/isolate.h"
13 #include "src/v8.h"
14 #include "src/vm-state-inl.h"
15 
16 namespace v8 {
17 namespace internal {
18 
20  public:
21  static void Step(Heap* heap,
22  EmbedderHeapTracer::EmbedderStackState stack_state);
23 
24  Task(Isolate* isolate, IncrementalMarkingJob* job,
25  EmbedderHeapTracer::EmbedderStackState stack_state)
26  : CancelableTask(isolate),
27  isolate_(isolate),
28  job_(job),
29  stack_state_(stack_state) {}
30 
31  // CancelableTask overrides.
32  void RunInternal() override;
33 
34  Isolate* isolate() const { return isolate_; }
35 
36  private:
37  Isolate* const isolate_;
38  IncrementalMarkingJob* const job_;
39  const EmbedderHeapTracer::EmbedderStackState stack_state_;
40 };
41 
42 void IncrementalMarkingJob::Start(Heap* heap) {
43  DCHECK(!heap->incremental_marking()->IsStopped());
44  ScheduleTask(heap);
45 }
46 
47 void IncrementalMarkingJob::ScheduleTask(Heap* heap) {
48  if (!task_pending_ && !heap->IsTearingDown()) {
49  v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
50  task_pending_ = true;
51  auto taskrunner =
52  V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate);
53  if (taskrunner->NonNestableTasksEnabled()) {
54  taskrunner->PostNonNestableTask(base::make_unique<Task>(
55  heap->isolate(), this,
56  EmbedderHeapTracer::EmbedderStackState::kEmpty));
57  } else {
58  taskrunner->PostTask(base::make_unique<Task>(
59  heap->isolate(), this,
60  EmbedderHeapTracer::EmbedderStackState::kUnknown));
61  }
62  }
63 }
64 
65 void IncrementalMarkingJob::Task::Step(
66  Heap* heap, EmbedderHeapTracer::EmbedderStackState stack_state) {
67  const int kIncrementalMarkingDelayMs = 1;
68  double deadline =
69  heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs;
70  heap->incremental_marking()->AdvanceIncrementalMarking(
71  deadline, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD,
72  i::StepOrigin::kTask);
73  {
74  EmbedderStackStateScope scope(heap->local_embedder_heap_tracer(),
75  stack_state);
76  heap->FinalizeIncrementalMarkingIfComplete(
77  GarbageCollectionReason::kFinalizeMarkingViaTask);
78  }
79 }
80 
81 void IncrementalMarkingJob::Task::RunInternal() {
82  VMState<GC> state(isolate());
83  TRACE_EVENT_CALL_STATS_SCOPED(isolate(), "v8", "V8.Task");
84 
85  Heap* heap = isolate()->heap();
86  IncrementalMarking* incremental_marking = heap->incremental_marking();
87  if (incremental_marking->IsStopped()) {
88  if (heap->IncrementalMarkingLimitReached() !=
89  Heap::IncrementalMarkingLimit::kNoLimit) {
90  heap->StartIncrementalMarking(heap->GCFlagsForIncrementalMarking(),
91  GarbageCollectionReason::kIdleTask,
92  kGCCallbackScheduleIdleGarbageCollection);
93  }
94  }
95 
96  // Clear this flag after StartIncrementalMarking call to avoid
97  // scheduling a new task when startining incremental marking.
98  job_->task_pending_ = false;
99 
100  if (!incremental_marking->IsStopped()) {
101  Step(heap, stack_state_);
102  if (!incremental_marking->IsStopped()) {
103  job_->ScheduleTask(heap);
104  }
105  }
106 }
107 
108 } // namespace internal
109 } // namespace v8
Definition: libplatform.h:13