| OLD | NEW |
| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 max_alive_after_gc_(0), | 107 max_alive_after_gc_(0), |
| 108 min_in_mutator_(kMaxInt), | 108 min_in_mutator_(kMaxInt), |
| 109 alive_after_last_gc_(0), | 109 alive_after_last_gc_(0), |
| 110 last_gc_end_timestamp_(0.0), | 110 last_gc_end_timestamp_(0.0), |
| 111 marking_time_(0.0), | 111 marking_time_(0.0), |
| 112 sweeping_time_(0.0), | 112 sweeping_time_(0.0), |
| 113 mark_compact_collector_(this), | 113 mark_compact_collector_(this), |
| 114 store_buffer_(this), | 114 store_buffer_(this), |
| 115 marking_(this), | 115 marking_(this), |
| 116 incremental_marking_(this), | 116 incremental_marking_(this), |
| 117 number_idle_notifications_(0), | |
| 118 last_idle_notification_gc_count_(0), | |
| 119 last_idle_notification_gc_count_init_(false), | |
| 120 mark_sweeps_since_idle_round_started_(0), | 117 mark_sweeps_since_idle_round_started_(0), |
| 121 gc_count_at_last_idle_gc_(0), | 118 gc_count_at_last_idle_gc_(0), |
| 122 scavenges_since_last_idle_round_(kIdleScavengeThreshold), | 119 scavenges_since_last_idle_round_(kIdleScavengeThreshold), |
| 123 full_codegen_bytes_generated_(0), | 120 full_codegen_bytes_generated_(0), |
| 124 crankshaft_codegen_bytes_generated_(0), | 121 crankshaft_codegen_bytes_generated_(0), |
| 125 gcs_since_last_deopt_(0), | 122 gcs_since_last_deopt_(0), |
| 126 #ifdef VERIFY_HEAP | 123 #ifdef VERIFY_HEAP |
| 127 no_weak_object_verification_scope_depth_(0), | 124 no_weak_object_verification_scope_depth_(0), |
| 128 #endif | 125 #endif |
| 129 allocation_sites_scratchpad_length_(0), | 126 allocation_sites_scratchpad_length_(0), |
| (...skipping 4200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4330 } | 4327 } |
| 4331 | 4328 |
| 4332 // After context disposal there is likely a lot of garbage remaining, reset | 4329 // After context disposal there is likely a lot of garbage remaining, reset |
| 4333 // the idle notification counters in order to trigger more incremental GCs | 4330 // the idle notification counters in order to trigger more incremental GCs |
| 4334 // on subsequent idle notifications. | 4331 // on subsequent idle notifications. |
| 4335 StartIdleRound(); | 4332 StartIdleRound(); |
| 4336 return false; | 4333 return false; |
| 4337 } | 4334 } |
| 4338 | 4335 |
| 4339 if (!FLAG_incremental_marking || isolate_->serializer_enabled()) { | 4336 if (!FLAG_incremental_marking || isolate_->serializer_enabled()) { |
| 4340 return IdleGlobalGC(); | 4337 return true; |
| 4341 } | 4338 } |
| 4342 | 4339 |
| 4343 // By doing small chunks of GC work in each IdleNotification, | 4340 // By doing small chunks of GC work in each IdleNotification, |
| 4344 // perform a round of incremental GCs and after that wait until | 4341 // perform a round of incremental GCs and after that wait until |
| 4345 // the mutator creates enough garbage to justify a new round. | 4342 // the mutator creates enough garbage to justify a new round. |
| 4346 // An incremental GC progresses as follows: | 4343 // An incremental GC progresses as follows: |
| 4347 // 1. many incremental marking steps, | 4344 // 1. many incremental marking steps, |
| 4348 // 2. one old space mark-sweep-compact, | 4345 // 2. one old space mark-sweep-compact, |
| 4349 // Use mark-sweep-compact events to count incremental GCs in a round. | 4346 // Use mark-sweep-compact events to count incremental GCs in a round. |
| 4350 | 4347 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4387 // the sweepter threads here. | 4384 // the sweepter threads here. |
| 4388 if (hint >= kMinHintForFullGC && | 4385 if (hint >= kMinHintForFullGC && |
| 4389 mark_compact_collector()->IsConcurrentSweepingInProgress()) { | 4386 mark_compact_collector()->IsConcurrentSweepingInProgress()) { |
| 4390 mark_compact_collector()->WaitUntilSweepingCompleted(); | 4387 mark_compact_collector()->WaitUntilSweepingCompleted(); |
| 4391 } | 4388 } |
| 4392 | 4389 |
| 4393 return false; | 4390 return false; |
| 4394 } | 4391 } |
| 4395 | 4392 |
| 4396 | 4393 |
| 4397 bool Heap::IdleGlobalGC() { | |
| 4398 static const int kIdlesBeforeScavenge = 4; | |
| 4399 static const int kIdlesBeforeMarkSweep = 7; | |
| 4400 static const int kIdlesBeforeMarkCompact = 8; | |
| 4401 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; | |
| 4402 static const unsigned int kGCsBetweenCleanup = 4; | |
| 4403 | |
| 4404 if (!last_idle_notification_gc_count_init_) { | |
| 4405 last_idle_notification_gc_count_ = gc_count_; | |
| 4406 last_idle_notification_gc_count_init_ = true; | |
| 4407 } | |
| 4408 | |
| 4409 bool uncommit = true; | |
| 4410 bool finished = false; | |
| 4411 | |
| 4412 // Reset the number of idle notifications received when a number of | |
| 4413 // GCs have taken place. This allows another round of cleanup based | |
| 4414 // on idle notifications if enough work has been carried out to | |
| 4415 // provoke a number of garbage collections. | |
| 4416 if (gc_count_ - last_idle_notification_gc_count_ < kGCsBetweenCleanup) { | |
| 4417 number_idle_notifications_ = | |
| 4418 Min(number_idle_notifications_ + 1, kMaxIdleCount); | |
| 4419 } else { | |
| 4420 number_idle_notifications_ = 0; | |
| 4421 last_idle_notification_gc_count_ = gc_count_; | |
| 4422 } | |
| 4423 | |
| 4424 if (number_idle_notifications_ == kIdlesBeforeScavenge) { | |
| 4425 CollectGarbage(NEW_SPACE, "idle notification"); | |
| 4426 new_space_.Shrink(); | |
| 4427 last_idle_notification_gc_count_ = gc_count_; | |
| 4428 } else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) { | |
| 4429 // Before doing the mark-sweep collections we clear the | |
| 4430 // compilation cache to avoid hanging on to source code and | |
| 4431 // generated code for cached functions. | |
| 4432 isolate_->compilation_cache()->Clear(); | |
| 4433 | |
| 4434 CollectAllGarbage(kReduceMemoryFootprintMask, "idle notification"); | |
| 4435 new_space_.Shrink(); | |
| 4436 last_idle_notification_gc_count_ = gc_count_; | |
| 4437 | |
| 4438 } else if (number_idle_notifications_ == kIdlesBeforeMarkCompact) { | |
| 4439 CollectAllGarbage(kReduceMemoryFootprintMask, "idle notification"); | |
| 4440 new_space_.Shrink(); | |
| 4441 last_idle_notification_gc_count_ = gc_count_; | |
| 4442 number_idle_notifications_ = 0; | |
| 4443 finished = true; | |
| 4444 } else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) { | |
| 4445 // If we have received more than kIdlesBeforeMarkCompact idle | |
| 4446 // notifications we do not perform any cleanup because we don't | |
| 4447 // expect to gain much by doing so. | |
| 4448 finished = true; | |
| 4449 } | |
| 4450 | |
| 4451 if (uncommit) UncommitFromSpace(); | |
| 4452 | |
| 4453 return finished; | |
| 4454 } | |
| 4455 | |
| 4456 | |
| 4457 #ifdef DEBUG | 4394 #ifdef DEBUG |
| 4458 | 4395 |
| 4459 void Heap::Print() { | 4396 void Heap::Print() { |
| 4460 if (!HasBeenSetUp()) return; | 4397 if (!HasBeenSetUp()) return; |
| 4461 isolate()->PrintStack(stdout); | 4398 isolate()->PrintStack(stdout); |
| 4462 AllSpaces spaces(this); | 4399 AllSpaces spaces(this); |
| 4463 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { | 4400 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { |
| 4464 space->Print(); | 4401 space->Print(); |
| 4465 } | 4402 } |
| 4466 } | 4403 } |
| (...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6424 static_cast<int>(object_sizes_last_time_[index])); | 6361 static_cast<int>(object_sizes_last_time_[index])); |
| 6425 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6362 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 6426 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6363 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 6427 | 6364 |
| 6428 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6365 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 6429 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6366 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 6430 ClearObjectStats(); | 6367 ClearObjectStats(); |
| 6431 } | 6368 } |
| 6432 | 6369 |
| 6433 } } // namespace v8::internal | 6370 } } // namespace v8::internal |
| OLD | NEW |