| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 4974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4985 if (uncommit) { | 4985 if (uncommit) { |
| 4986 new_space_.Shrink(); | 4986 new_space_.Shrink(); |
| 4987 UncommitFromSpace(); | 4987 UncommitFromSpace(); |
| 4988 } | 4988 } |
| 4989 } | 4989 } |
| 4990 } | 4990 } |
| 4991 | 4991 |
| 4992 | 4992 |
| 4993 bool Heap::IdleNotification(int hint) { | 4993 bool Heap::IdleNotification(int hint) { |
| 4994 const int kMaxHint = 1000; | 4994 const int kMaxHint = 1000; |
| 4995 intptr_t size_factor = Min(Max(hint, 30), kMaxHint) / 10; | 4995 intptr_t size_factor = Min(Max(hint, 20), kMaxHint) / 4; |
| 4996 // The size factor is in range [3..100]. | 4996 // The size factor is in range [5..250]. The numbers here are chosen from |
| 4997 // experiments. If you changes them, make sure to test with |
| 4998 // chrome/performance_ui_tests --gtest_filter="GeneralMixMemoryTest.* |
| 4997 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; | 4999 intptr_t step_size = size_factor * IncrementalMarking::kAllocatedThreshold; |
| 4998 | 5000 |
| 4999 if (contexts_disposed_ > 0) { | 5001 if (contexts_disposed_ > 0) { |
| 5000 if (hint >= kMaxHint) { | 5002 if (hint >= kMaxHint) { |
| 5001 // The embedder is requesting a lot of GC work after context disposal, | 5003 // The embedder is requesting a lot of GC work after context disposal, |
| 5002 // we age inline caches so that they don't keep objects from | 5004 // we age inline caches so that they don't keep objects from |
| 5003 // the old context alive. | 5005 // the old context alive. |
| 5004 AgeInlineCaches(); | 5006 AgeInlineCaches(); |
| 5005 } | 5007 } |
| 5006 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); | 5008 int mark_sweep_time = Min(TimeMarkSweepWouldTakeInMs(), 1000); |
| 5007 if (hint >= mark_sweep_time && !FLAG_expose_gc && | 5009 if (hint >= mark_sweep_time && !FLAG_expose_gc && |
| 5008 incremental_marking()->IsStopped()) { | 5010 incremental_marking()->IsStopped()) { |
| 5009 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 5011 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| 5010 CollectAllGarbage(kReduceMemoryFootprintMask, | 5012 CollectAllGarbage(kReduceMemoryFootprintMask, |
| 5011 "idle notification: contexts disposed"); | 5013 "idle notification: contexts disposed"); |
| 5012 } else { | 5014 } else { |
| 5013 AdvanceIdleIncrementalMarking(step_size); | 5015 AdvanceIdleIncrementalMarking(step_size); |
| 5014 contexts_disposed_ = 0; | 5016 contexts_disposed_ = 0; |
| 5015 } | 5017 } |
| 5016 // Make sure that we have no pending context disposals. | 5018 // Make sure that we have no pending context disposals. |
| 5017 // Take into account that we might have decided to delay full collection | 5019 // Take into account that we might have decided to delay full collection |
| 5018 // because incremental marking is in progress. | 5020 // because incremental marking is in progress. |
| 5019 ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); | 5021 ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); |
| 5022 // After context disposal there is likely a lot of garbage remaining, reset |
| 5023 // the idle notification counters in order to trigger more incremental GCs |
| 5024 // on subsequent idle notifications. |
| 5025 StartIdleRound(); |
| 5020 return false; | 5026 return false; |
| 5021 } | 5027 } |
| 5022 | 5028 |
| 5023 if (hint >= kMaxHint || !FLAG_incremental_marking || | 5029 if (!FLAG_incremental_marking || FLAG_expose_gc || Serializer::enabled()) { |
| 5024 FLAG_expose_gc || Serializer::enabled()) { | |
| 5025 return IdleGlobalGC(); | 5030 return IdleGlobalGC(); |
| 5026 } | 5031 } |
| 5027 | 5032 |
| 5028 // By doing small chunks of GC work in each IdleNotification, | 5033 // By doing small chunks of GC work in each IdleNotification, |
| 5029 // perform a round of incremental GCs and after that wait until | 5034 // perform a round of incremental GCs and after that wait until |
| 5030 // the mutator creates enough garbage to justify a new round. | 5035 // the mutator creates enough garbage to justify a new round. |
| 5031 // An incremental GC progresses as follows: | 5036 // An incremental GC progresses as follows: |
| 5032 // 1. many incremental marking steps, | 5037 // 1. many incremental marking steps, |
| 5033 // 2. one old space mark-sweep-compact, | 5038 // 2. one old space mark-sweep-compact, |
| 5034 // 3. many lazy sweep steps. | 5039 // 3. many lazy sweep steps. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5053 int new_mark_sweeps = ms_count_ - ms_count_at_last_idle_notification_; | 5058 int new_mark_sweeps = ms_count_ - ms_count_at_last_idle_notification_; |
| 5054 mark_sweeps_since_idle_round_started_ += new_mark_sweeps; | 5059 mark_sweeps_since_idle_round_started_ += new_mark_sweeps; |
| 5055 ms_count_at_last_idle_notification_ = ms_count_; | 5060 ms_count_at_last_idle_notification_ = ms_count_; |
| 5056 | 5061 |
| 5057 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { | 5062 if (mark_sweeps_since_idle_round_started_ >= kMaxMarkSweepsInIdleRound) { |
| 5058 FinishIdleRound(); | 5063 FinishIdleRound(); |
| 5059 return true; | 5064 return true; |
| 5060 } | 5065 } |
| 5061 | 5066 |
| 5062 if (incremental_marking()->IsStopped()) { | 5067 if (incremental_marking()->IsStopped()) { |
| 5063 if (!WorthStartingGCWhenIdle()) { | |
| 5064 FinishIdleRound(); | |
| 5065 return true; | |
| 5066 } | |
| 5067 incremental_marking()->Start(); | 5068 incremental_marking()->Start(); |
| 5068 } | 5069 } |
| 5069 | 5070 |
| 5070 AdvanceIdleIncrementalMarking(step_size); | 5071 AdvanceIdleIncrementalMarking(step_size); |
| 5071 return false; | 5072 return false; |
| 5072 } | 5073 } |
| 5073 | 5074 |
| 5074 | 5075 |
| 5075 bool Heap::IdleGlobalGC() { | 5076 bool Heap::IdleGlobalGC() { |
| 5076 static const int kIdlesBeforeScavenge = 4; | 5077 static const int kIdlesBeforeScavenge = 4; |
| (...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7139 } else { | 7140 } else { |
| 7140 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 7141 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
| 7141 } | 7142 } |
| 7142 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 7143 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
| 7143 reinterpret_cast<Address>(p); | 7144 reinterpret_cast<Address>(p); |
| 7144 remembered_unmapped_pages_index_++; | 7145 remembered_unmapped_pages_index_++; |
| 7145 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; | 7146 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; |
| 7146 } | 7147 } |
| 7147 | 7148 |
| 7148 } } // namespace v8::internal | 7149 } } // namespace v8::internal |
| OLD | NEW |