Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/heap/incremental-marking.cc

Issue 2304123003: [heap] Refactor incremental marking step. (Closed)
Patch Set: another fix of the test Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/incremental-marking.h ('k') | src/heap/incremental-marking-job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/incremental-marking.h" 5 #include "src/heap/incremental-marking.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/compilation-cache.h" 8 #include "src/compilation-cache.h"
9 #include "src/conversions.h" 9 #include "src/conversions.h"
10 #include "src/heap/gc-idle-time-handler.h" 10 #include "src/heap/gc-idle-time-handler.h"
11 #include "src/heap/gc-tracer.h" 11 #include "src/heap/gc-tracer.h"
12 #include "src/heap/mark-compact-inl.h" 12 #include "src/heap/mark-compact-inl.h"
13 #include "src/heap/object-stats.h" 13 #include "src/heap/object-stats.h"
14 #include "src/heap/objects-visiting-inl.h" 14 #include "src/heap/objects-visiting-inl.h"
15 #include "src/heap/objects-visiting.h" 15 #include "src/heap/objects-visiting.h"
16 #include "src/tracing/trace-event.h" 16 #include "src/tracing/trace-event.h"
17 #include "src/v8.h" 17 #include "src/v8.h"
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 IncrementalMarking::StepActions IncrementalMarking::IdleStepActions() {
23 return StepActions(IncrementalMarking::NO_GC_VIA_STACK_GUARD,
24 IncrementalMarking::FORCE_MARKING,
25 IncrementalMarking::DO_NOT_FORCE_COMPLETION);
26 }
27
28 IncrementalMarking::IncrementalMarking(Heap* heap) 22 IncrementalMarking::IncrementalMarking(Heap* heap)
29 : heap_(heap), 23 : heap_(heap),
30 observer_(*this, kAllocatedThreshold), 24 observer_(*this, kAllocatedThreshold),
31 state_(STOPPED), 25 state_(STOPPED),
32 is_compacting_(false), 26 is_compacting_(false),
33 steps_count_(0), 27 steps_count_(0),
34 old_generation_space_available_at_start_of_incremental_(0), 28 old_generation_space_available_at_start_of_incremental_(0),
35 old_generation_space_used_at_start_of_incremental_(0), 29 old_generation_space_used_at_start_of_incremental_(0),
36 bytes_rescanned_(0), 30 bytes_rescanned_(0),
37 should_hurry_(false), 31 should_hurry_(false),
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1044 }
1051 1045
1052 1046
1053 void IncrementalMarking::Epilogue() { 1047 void IncrementalMarking::Epilogue() {
1054 was_activated_ = false; 1048 was_activated_ = false;
1055 finalize_marking_completed_ = false; 1049 finalize_marking_completed_ = false;
1056 incremental_marking_finalization_rounds_ = 0; 1050 incremental_marking_finalization_rounds_ = 0;
1057 } 1051 }
1058 1052
1059 double IncrementalMarking::AdvanceIncrementalMarking( 1053 double IncrementalMarking::AdvanceIncrementalMarking(
1060 double deadline_in_ms, IncrementalMarking::StepActions step_actions) { 1054 double deadline_in_ms, CompletionAction completion_action,
1055 ForceCompletionAction force_completion) {
1061 DCHECK(!IsStopped()); 1056 DCHECK(!IsStopped());
1062 1057
1058 double remaining_time_in_ms = 0.0;
1063 intptr_t step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( 1059 intptr_t step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize(
1064 GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs, 1060 kStepSizeInMs,
1065 heap()->tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); 1061 heap()->tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
1066 double remaining_time_in_ms = 0.0;
1067 1062
1068 do { 1063 do {
1069 Step(step_size_in_bytes, step_actions.completion_action, 1064 Step(step_size_in_bytes, completion_action, force_completion);
1070 step_actions.force_marking, step_actions.force_completion);
1071 remaining_time_in_ms = 1065 remaining_time_in_ms =
1072 deadline_in_ms - heap()->MonotonicallyIncreasingTimeInMs(); 1066 deadline_in_ms - heap()->MonotonicallyIncreasingTimeInMs();
1073 } while (!heap_->mark_compact_collector()->marking_deque()->IsEmpty() && 1067 } while (remaining_time_in_ms >= kStepSizeInMs && !IsComplete() &&
1074 remaining_time_in_ms >=
1075 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
1076 !IsComplete() &&
1077 !heap()->mark_compact_collector()->marking_deque()->IsEmpty()); 1068 !heap()->mark_compact_collector()->marking_deque()->IsEmpty());
1078 return remaining_time_in_ms; 1069 return remaining_time_in_ms;
1079 } 1070 }
1080 1071
1081 1072
1082 void IncrementalMarking::OldSpaceStep(intptr_t allocated) {
1083 if (IsStopped() && ShouldActivateEvenWithoutIdleNotification()) {
1084 heap()->StartIncrementalMarking(Heap::kNoGCFlags, kNoGCCallbackFlags,
1085 "old space step");
1086 } else {
1087 Step(allocated * kFastMarking / kInitialMarkingSpeed, GC_VIA_STACK_GUARD);
1088 }
1089 }
1090
1091
1092 void IncrementalMarking::SpeedUp() { 1073 void IncrementalMarking::SpeedUp() {
1093 bool speed_up = false; 1074 bool speed_up = false;
1094 1075
1095 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) { 1076 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) {
1096 if (FLAG_trace_incremental_marking) { 1077 if (FLAG_trace_incremental_marking) {
1097 heap()->isolate()->PrintWithTimestamp( 1078 heap()->isolate()->PrintWithTimestamp(
1098 "[IncrementalMarking] Speed up marking after %d steps\n", 1079 "[IncrementalMarking] Speed up marking after %d steps\n",
1099 static_cast<int>(kMarkingSpeedAccellerationInterval)); 1080 static_cast<int>(kMarkingSpeedAccellerationInterval));
1100 } 1081 }
1101 speed_up = true; 1082 speed_up = true;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 (heap_->mark_compact_collector()->sweeper().IsSweepingCompleted() || 1152 (heap_->mark_compact_collector()->sweeper().IsSweepingCompleted() ||
1172 !FLAG_concurrent_sweeping)) { 1153 !FLAG_concurrent_sweeping)) {
1173 heap_->mark_compact_collector()->EnsureSweepingCompleted(); 1154 heap_->mark_compact_collector()->EnsureSweepingCompleted();
1174 } 1155 }
1175 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { 1156 if (!heap_->mark_compact_collector()->sweeping_in_progress()) {
1176 bytes_scanned_ = 0; 1157 bytes_scanned_ = 0;
1177 StartMarking(); 1158 StartMarking();
1178 } 1159 }
1179 } 1160 }
1180 1161
1181 intptr_t IncrementalMarking::Step(intptr_t allocated_bytes, 1162 void IncrementalMarking::NotifyAllocatedBytes(intptr_t allocated_bytes) {
1182 CompletionAction action,
1183 ForceMarkingAction marking,
1184 ForceCompletionAction completion) {
1185 DCHECK(allocated_bytes >= 0);
1186
1187 if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking || 1163 if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking ||
1188 (state_ != SWEEPING && state_ != MARKING)) { 1164 (state_ != SWEEPING && state_ != MARKING)) {
1189 return 0; 1165 return;
1190 } 1166 }
1191 1167
1192 allocated_ += allocated_bytes; 1168 allocated_ += allocated_bytes;
1193 1169
1194 if (marking == DO_NOT_FORCE_MARKING && allocated_ < kAllocatedThreshold && 1170 if (allocated_ >= kAllocatedThreshold ||
1195 write_barriers_invoked_since_last_step_ < 1171 write_barriers_invoked_since_last_step_ >=
1196 kWriteBarriersInvokedThreshold) { 1172 kWriteBarriersInvokedThreshold) {
1197 return 0;
1198 }
1199
1200 // If an idle notification happened recently, we delay marking steps.
1201 if (marking == DO_NOT_FORCE_MARKING &&
1202 heap_->RecentIdleNotificationHappened()) {
1203 return 0;
1204 }
1205
1206 intptr_t bytes_processed = 0;
1207 {
1208 HistogramTimerScope incremental_marking_scope(
1209 heap_->isolate()->counters()->gc_incremental_marking());
1210 TRACE_EVENT0("v8", "V8.GCIncrementalMarking");
1211 TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL);
1212 double start = heap_->MonotonicallyIncreasingTimeInMs();
1213
1214 // The marking speed is driven either by the allocation rate or by the rate 1173 // The marking speed is driven either by the allocation rate or by the rate
1215 // at which we are having to check the color of objects in the write 1174 // at which we are having to check the color of objects in the write
1216 // barrier. 1175 // barrier.
1217 // It is possible for a tight non-allocating loop to run a lot of write 1176 // It is possible for a tight non-allocating loop to run a lot of write
1218 // barriers before we get here and check them (marking can only take place 1177 // barriers before we get here and check them (marking can only take place
1219 // on 1178 // on
1220 // allocation), so to reduce the lumpiness we don't use the write barriers 1179 // allocation), so to reduce the lumpiness we don't use the write barriers
1221 // invoked since last step directly to determine the amount of work to do. 1180 // invoked since last step directly to determine the amount of work to do.
1222 intptr_t bytes_to_process = 1181 intptr_t bytes_to_process =
1223 marking_speed_ * 1182 marking_speed_ *
1224 Max(allocated_, write_barriers_invoked_since_last_step_); 1183 Max(allocated_, write_barriers_invoked_since_last_step_);
1225 allocated_ = 0; 1184 Step(bytes_to_process, GC_VIA_STACK_GUARD, FORCE_COMPLETION);
1226 write_barriers_invoked_since_last_step_ = 0; 1185 }
1186 }
1227 1187
1228 bytes_scanned_ += bytes_to_process; 1188 void IncrementalMarking::Step(intptr_t bytes_to_process,
1189 CompletionAction action,
1190 ForceCompletionAction completion) {
1191 HistogramTimerScope incremental_marking_scope(
1192 heap_->isolate()->counters()->gc_incremental_marking());
1193 TRACE_EVENT0("v8", "V8.GCIncrementalMarking");
1194 TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL);
1195 double start = heap_->MonotonicallyIncreasingTimeInMs();
1229 1196
1230 if (state_ == SWEEPING) { 1197 bytes_scanned_ += bytes_to_process;
1231 TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_SWEEPING); 1198
1232 FinalizeSweeping(); 1199 allocated_ = 0;
1200 write_barriers_invoked_since_last_step_ = 0;
1201
1202 if (state_ == SWEEPING) {
1203 TRACE_GC(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_SWEEPING);
1204 FinalizeSweeping();
1205 }
1206
1207 intptr_t bytes_processed = 0;
1208 if (state_ == MARKING) {
1209 const bool incremental_wrapper_tracing =
1210 FLAG_incremental_marking_wrappers && heap_->UsingEmbedderHeapTracer();
1211 const bool process_wrappers =
1212 incremental_wrapper_tracing &&
1213 (heap_->mark_compact_collector()
1214 ->RequiresImmediateWrapperProcessing() ||
1215 heap_->mark_compact_collector()->marking_deque()->IsEmpty());
1216 bool wrapper_work_left = incremental_wrapper_tracing;
1217 if (!process_wrappers) {
1218 bytes_processed = ProcessMarkingDeque(bytes_to_process);
1219 } else {
1220 const double wrapper_deadline =
1221 heap_->MonotonicallyIncreasingTimeInMs() + kStepSizeInMs;
1222 TRACE_GC(heap()->tracer(),
1223 GCTracer::Scope::MC_INCREMENTAL_WRAPPER_TRACING);
1224 heap_->mark_compact_collector()->RegisterWrappersWithEmbedderHeapTracer();
1225 wrapper_work_left =
1226 heap_->mark_compact_collector()
1227 ->embedder_heap_tracer()
1228 ->AdvanceTracing(wrapper_deadline,
1229 EmbedderHeapTracer::AdvanceTracingActions(
1230 EmbedderHeapTracer::ForceCompletionAction::
1231 DO_NOT_FORCE_COMPLETION));
1233 } 1232 }
1234 1233
1235 if (state_ == MARKING) { 1234 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty() &&
1236 const bool incremental_wrapper_tracing = 1235 !wrapper_work_left) {
1237 FLAG_incremental_marking_wrappers && heap_->UsingEmbedderHeapTracer(); 1236 if (completion == FORCE_COMPLETION ||
1238 const bool process_wrappers = 1237 IsIdleMarkingDelayCounterLimitReached()) {
1239 incremental_wrapper_tracing && 1238 if (!finalize_marking_completed_) {
1240 (heap_->mark_compact_collector() 1239 FinalizeMarking(action);
1241 ->RequiresImmediateWrapperProcessing() || 1240 } else {
1242 heap_->mark_compact_collector()->marking_deque()->IsEmpty()); 1241 MarkingComplete(action);
1243 bool wrapper_work_left = incremental_wrapper_tracing; 1242 }
1244 if (!process_wrappers) {
1245 bytes_processed = ProcessMarkingDeque(bytes_to_process);
1246 } else { 1243 } else {
1247 const double kWrapperTracngStepMs = 1.0; 1244 IncrementIdleMarkingDelayCounter();
1248 const double wrapper_deadline =
1249 heap_->MonotonicallyIncreasingTimeInMs() + kWrapperTracngStepMs;
1250 TRACE_GC(heap()->tracer(),
1251 GCTracer::Scope::MC_INCREMENTAL_WRAPPER_TRACING);
1252 heap_->mark_compact_collector()
1253 ->RegisterWrappersWithEmbedderHeapTracer();
1254 wrapper_work_left =
1255 heap_->mark_compact_collector()
1256 ->embedder_heap_tracer()
1257 ->AdvanceTracing(wrapper_deadline,
1258 EmbedderHeapTracer::AdvanceTracingActions(
1259 EmbedderHeapTracer::ForceCompletionAction::
1260 DO_NOT_FORCE_COMPLETION));
1261 }
1262
1263 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty() &&
1264 !wrapper_work_left) {
1265 if (completion == FORCE_COMPLETION ||
1266 IsIdleMarkingDelayCounterLimitReached()) {
1267 if (!finalize_marking_completed_) {
1268 FinalizeMarking(action);
1269 } else {
1270 MarkingComplete(action);
1271 }
1272 } else {
1273 IncrementIdleMarkingDelayCounter();
1274 }
1275 } 1245 }
1276 } 1246 }
1247 }
1277 1248
1278 steps_count_++; 1249 steps_count_++;
1279 1250
1280 // Speed up marking if we are marking too slow or if we are almost done 1251 // Speed up marking if we are marking too slow or if we are almost done
1281 // with marking. 1252 // with marking.
1282 SpeedUp(); 1253 SpeedUp();
1283 1254
1284 double end = heap_->MonotonicallyIncreasingTimeInMs(); 1255 double end = heap_->MonotonicallyIncreasingTimeInMs();
1285 double duration = (end - start); 1256 double duration = (end - start);
1286 // Note that we report zero bytes here when sweeping was in progress or 1257 // Note that we report zero bytes here when sweeping was in progress or
1287 // when we just started incremental marking. In these cases we did not 1258 // when we just started incremental marking. In these cases we did not
1288 // process the marking deque. 1259 // process the marking deque.
1289 heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed); 1260 heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed);
1290 }
1291 return bytes_processed;
1292 } 1261 }
1293 1262
1294 1263
1295 void IncrementalMarking::ResetStepCounters() { 1264 void IncrementalMarking::ResetStepCounters() {
1296 steps_count_ = 0; 1265 steps_count_ = 0;
1297 old_generation_space_available_at_start_of_incremental_ = 1266 old_generation_space_available_at_start_of_incremental_ =
1298 SpaceLeftInOldSpace(); 1267 SpaceLeftInOldSpace();
1299 old_generation_space_used_at_start_of_incremental_ = 1268 old_generation_space_used_at_start_of_incremental_ =
1300 heap_->PromotedTotalSize(); 1269 heap_->PromotedTotalSize();
1301 bytes_rescanned_ = 0; 1270 bytes_rescanned_ = 0;
(...skipping 17 matching lines...) Expand all
1319 idle_marking_delay_counter_++; 1288 idle_marking_delay_counter_++;
1320 } 1289 }
1321 1290
1322 1291
1323 void IncrementalMarking::ClearIdleMarkingDelayCounter() { 1292 void IncrementalMarking::ClearIdleMarkingDelayCounter() {
1324 idle_marking_delay_counter_ = 0; 1293 idle_marking_delay_counter_ = 0;
1325 } 1294 }
1326 1295
1327 } // namespace internal 1296 } // namespace internal
1328 } // namespace v8 1297 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/incremental-marking.h ('k') | src/heap/incremental-marking-job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698