Line data Source code
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 :
19 77862 : class IncrementalMarkingJob::Task : public CancelableTask {
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 38931 : 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 31884 : void IncrementalMarkingJob::Start(Heap* heap) {
43 : DCHECK(!heap->incremental_marking()->IsStopped());
44 31884 : ScheduleTask(heap);
45 31884 : }
46 :
47 92462 : void IncrementalMarkingJob::ScheduleTask(Heap* heap) {
48 92462 : if (!task_pending_ && !heap->IsTearingDown()) {
49 : v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
50 38931 : task_pending_ = true;
51 : auto taskrunner =
52 38931 : V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate);
53 38931 : if (taskrunner->NonNestableTasksEnabled()) {
54 0 : taskrunner->PostNonNestableTask(base::make_unique<Task>(
55 : heap->isolate(), this,
56 0 : EmbedderHeapTracer::EmbedderStackState::kEmpty));
57 : } else {
58 38931 : taskrunner->PostTask(base::make_unique<Task>(
59 : heap->isolate(), this,
60 155724 : EmbedderHeapTracer::EmbedderStackState::kUnknown));
61 : }
62 : }
63 53531 : }
64 :
65 37638 : void IncrementalMarkingJob::Task::Step(
66 75276 : Heap* heap, EmbedderHeapTracer::EmbedderStackState stack_state) {
67 : const int kIncrementalMarkingDelayMs = 1;
68 : double deadline =
69 37638 : heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs;
70 : heap->incremental_marking()->AdvanceIncrementalMarking(
71 : deadline, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD,
72 37638 : i::StepOrigin::kTask);
73 : {
74 : EmbedderStackStateScope scope(heap->local_embedder_heap_tracer(),
75 : stack_state);
76 : heap->FinalizeIncrementalMarkingIfComplete(
77 37638 : GarbageCollectionReason::kFinalizeMarkingViaTask);
78 : }
79 37638 : }
80 :
81 76182 : void IncrementalMarkingJob::Task::RunInternal() {
82 : VMState<GC> state(isolate());
83 114273 : TRACE_EVENT_CALL_STATS_SCOPED(isolate(), "v8", "V8.Task");
84 :
85 38091 : Heap* heap = isolate()->heap();
86 : IncrementalMarking* incremental_marking = heap->incremental_marking();
87 38091 : if (incremental_marking->IsStopped()) {
88 1079 : if (heap->IncrementalMarkingLimitReached() !=
89 : Heap::IncrementalMarkingLimit::kNoLimit) {
90 : heap->StartIncrementalMarking(heap->GCFlagsForIncrementalMarking(),
91 : GarbageCollectionReason::kIdleTask,
92 626 : kGCCallbackScheduleIdleGarbageCollection);
93 : }
94 : }
95 :
96 : // Clear this flag after StartIncrementalMarking call to avoid
97 : // scheduling a new task when startining incremental marking.
98 38091 : job_->task_pending_ = false;
99 :
100 38091 : if (!incremental_marking->IsStopped()) {
101 37638 : Step(heap, stack_state_);
102 37638 : if (!incremental_marking->IsStopped()) {
103 19946 : job_->ScheduleTask(heap);
104 : }
105 : }
106 38091 : }
107 :
108 : } // namespace internal
109 183867 : } // namespace v8
|