OLD | NEW |
---|---|
(Empty) | |
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 | |
14 namespace v8 { | |
15 namespace internal { | |
16 | |
17 | |
18 void IncrementalMarkingJob::NotifyIdleTask() { idle_task_pending_ = false; } | |
19 | |
20 | |
21 void IncrementalMarkingJob::NotifyDelayedTask() { | |
22 delayed_task_pending_ = false; | |
23 } | |
24 | |
25 | |
26 void IncrementalMarkingJob::NotifyProgress() { | |
27 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
| |
28 } | |
29 | |
30 | |
31 void IncrementalMarkingJob::ScheduleIdleTask(Heap* heap) { | |
32 if (!idle_task_pending_) { | |
33 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate()); | |
34 if (V8::GetCurrentPlatform()->IdleTasksEnabled(isolate)) { | |
35 idle_task_pending_ = true; | |
36 auto task = new IdleTask(heap->isolate(), this); | |
37 V8::GetCurrentPlatform()->CallIdleOnForegroundThread(isolate, task); | |
38 } | |
39 } | |
40 } | |
41 | |
42 | |
43 void IncrementalMarkingJob::ScheduleDelayedTask(Heap* heap) { | |
44 if (!delayed_task_pending_) { | |
45 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.
| |
46 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate()); | |
47 delayed_task_pending_ = true; | |
48 made_progress_since_last_delayed_task_ = false; | |
49 auto task = new DelayedTask(heap->isolate(), this); | |
50 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread(isolate, task, | |
51 kDelayInSeconds); | |
52 } | |
53 } | |
54 | |
55 | |
56 IncrementalMarkingJob::IdleTask::Progress IncrementalMarkingJob::IdleTask::Step( | |
57 Heap* heap, double deadline_in_ms) { | |
58 IncrementalMarking* incremental_marking = heap->incremental_marking(); | |
59 MarkCompactCollector* mark_compact_collector = heap->mark_compact_collector(); | |
60 if (incremental_marking->IsStopped()) { | |
61 return kDone; | |
62 } | |
63 if (mark_compact_collector->sweeping_in_progress()) { | |
64 if (mark_compact_collector->IsSweepingCompleted()) { | |
65 mark_compact_collector->EnsureSweepingCompleted(); | |
66 } | |
67 return kMoreWork; | |
68 } | |
69 const double remaining_idle_time_in_ms = heap->AdvanceIncrementalMarking( | |
70 0, deadline_in_ms, IncrementalMarking::IdleStepActions()); | |
71 if (remaining_idle_time_in_ms > 0.0) { | |
72 heap->TryFinalizeIdleIncrementalMarking(remaining_idle_time_in_ms); | |
73 } | |
74 return incremental_marking->IsStopped() ? kDone : kMoreWork; | |
75 } | |
76 | |
77 | |
78 void IncrementalMarkingJob::IdleTask::RunInternal(double deadline_in_seconds) { | |
79 double deadline_in_ms = | |
80 deadline_in_seconds * | |
81 static_cast<double>(base::Time::kMillisecondsPerSecond); | |
82 Heap* heap = isolate_->heap(); | |
83 double start_ms = heap->MonotonicallyIncreasingTimeInMs(); | |
84 job_->NotifyIdleTask(); | |
85 job_->NotifyProgress(); | |
86 if (Step(heap, deadline_in_ms) == kMoreWork) { | |
87 job_->ScheduleIdleTask(heap); | |
88 } | |
89 if (FLAG_trace_idle_notification) { | |
90 double current_time_ms = heap->MonotonicallyIncreasingTimeInMs(); | |
91 double idle_time_in_ms = deadline_in_ms - start_ms; | |
92 double deadline_difference = deadline_in_ms - current_time_ms; | |
93 PrintIsolate(isolate_, "%8.0f ms: ", isolate_->time_millis_since_init()); | |
94 PrintF( | |
95 "Idle task: requested idle time %.2f ms, used idle time %.2f " | |
96 "ms, deadline usage %.2f ms\n", | |
97 idle_time_in_ms, idle_time_in_ms - deadline_difference, | |
98 deadline_difference); | |
99 } | |
100 } | |
101 | |
102 | |
103 void IncrementalMarkingJob::DelayedTask::Step(Heap* heap) { | |
104 const int kIncrementalMarkingDelayMs = 50; | |
105 double deadline = | |
106 heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs; | |
107 heap->AdvanceIncrementalMarking( | |
108 0, deadline, i::IncrementalMarking::StepActions( | |
109 i::IncrementalMarking::NO_GC_VIA_STACK_GUARD, | |
110 i::IncrementalMarking::FORCE_MARKING, | |
111 i::IncrementalMarking::FORCE_COMPLETION)); | |
112 heap->FinalizeIncrementalMarkingIfComplete( | |
113 "Incremental marking task: finalize incremental marking"); | |
114 } | |
115 | |
116 | |
117 void IncrementalMarkingJob::DelayedTask::RunInternal() { | |
118 Heap* heap = isolate_->heap(); | |
119 job_->NotifyDelayedTask(); | |
120 IncrementalMarking* incremental_marking = heap->incremental_marking(); | |
121 if (!incremental_marking->IsStopped()) { | |
122 if (job_->ShouldForceMarkingStep()) { | |
123 Step(heap); | |
124 } | |
125 // The Step() above could have finished incremental marking. | |
126 if (!incremental_marking->IsStopped()) { | |
127 job_->ScheduleDelayedTask(heap); | |
128 } | |
129 } | |
130 } | |
131 | |
132 } // namespace internal | |
133 } // namespace v8 | |
OLD | NEW |