OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3750 } | 3750 } |
3751 Struct::cast(result)->InitializeBody(size); | 3751 Struct::cast(result)->InitializeBody(size); |
3752 return result; | 3752 return result; |
3753 } | 3753 } |
3754 | 3754 |
3755 | 3755 |
3756 bool Heap::IdleNotification() { | 3756 bool Heap::IdleNotification() { |
3757 static const int kIdlesBeforeScavenge = 4; | 3757 static const int kIdlesBeforeScavenge = 4; |
3758 static const int kIdlesBeforeMarkSweep = 7; | 3758 static const int kIdlesBeforeMarkSweep = 7; |
3759 static const int kIdlesBeforeMarkCompact = 8; | 3759 static const int kIdlesBeforeMarkCompact = 8; |
| 3760 static const int kMaxIdleCount = 9; |
| 3761 static const int kGCsBetweenCleanup = 4; |
3760 static int number_idle_notifications = 0; | 3762 static int number_idle_notifications = 0; |
3761 static int last_gc_count = gc_count_; | 3763 static int last_gc_count = gc_count_; |
3762 | 3764 |
3763 bool uncommit = true; | 3765 bool uncommit = true; |
3764 bool finished = false; | 3766 bool finished = false; |
3765 | 3767 |
3766 if (last_gc_count == gc_count_) { | 3768 // Reset the number of idle notifications received when a number of |
3767 number_idle_notifications++; | 3769 // GCs have taken place. This allows another round of cleanup based |
| 3770 // on idle notifications if enough work has been carried out to |
| 3771 // provoke a number of garbage collections. |
| 3772 if (gc_count_ < last_gc_count + kGCsBetweenCleanup) { |
| 3773 number_idle_notifications = |
| 3774 Min(number_idle_notifications + 1, kMaxIdleCount); |
3768 } else { | 3775 } else { |
3769 number_idle_notifications = 0; | 3776 number_idle_notifications = 0; |
3770 last_gc_count = gc_count_; | 3777 last_gc_count = gc_count_; |
3771 } | 3778 } |
3772 | 3779 |
3773 if (number_idle_notifications == kIdlesBeforeScavenge) { | 3780 if (number_idle_notifications == kIdlesBeforeScavenge) { |
3774 if (contexts_disposed_ > 0) { | 3781 if (contexts_disposed_ > 0) { |
3775 HistogramTimerScope scope(&Counters::gc_context); | 3782 HistogramTimerScope scope(&Counters::gc_context); |
3776 CollectAllGarbage(false); | 3783 CollectAllGarbage(false); |
3777 } else { | 3784 } else { |
3778 CollectGarbage(NEW_SPACE); | 3785 CollectGarbage(NEW_SPACE); |
3779 } | 3786 } |
3780 new_space_.Shrink(); | 3787 new_space_.Shrink(); |
3781 last_gc_count = gc_count_; | 3788 last_gc_count = gc_count_; |
3782 | |
3783 } else if (number_idle_notifications == kIdlesBeforeMarkSweep) { | 3789 } else if (number_idle_notifications == kIdlesBeforeMarkSweep) { |
3784 // Before doing the mark-sweep collections we clear the | 3790 // Before doing the mark-sweep collections we clear the |
3785 // compilation cache to avoid hanging on to source code and | 3791 // compilation cache to avoid hanging on to source code and |
3786 // generated code for cached functions. | 3792 // generated code for cached functions. |
3787 CompilationCache::Clear(); | 3793 CompilationCache::Clear(); |
3788 | 3794 |
3789 CollectAllGarbage(false); | 3795 CollectAllGarbage(false); |
3790 new_space_.Shrink(); | 3796 new_space_.Shrink(); |
3791 last_gc_count = gc_count_; | 3797 last_gc_count = gc_count_; |
3792 | 3798 |
3793 } else if (number_idle_notifications == kIdlesBeforeMarkCompact) { | 3799 } else if (number_idle_notifications == kIdlesBeforeMarkCompact) { |
3794 CollectAllGarbage(true); | 3800 CollectAllGarbage(true); |
3795 new_space_.Shrink(); | 3801 new_space_.Shrink(); |
3796 last_gc_count = gc_count_; | 3802 last_gc_count = gc_count_; |
3797 number_idle_notifications = 0; | |
3798 finished = true; | 3803 finished = true; |
3799 | 3804 |
3800 } else if (contexts_disposed_ > 0) { | 3805 } else if (contexts_disposed_ > 0) { |
3801 if (FLAG_expose_gc) { | 3806 if (FLAG_expose_gc) { |
3802 contexts_disposed_ = 0; | 3807 contexts_disposed_ = 0; |
3803 } else { | 3808 } else { |
3804 HistogramTimerScope scope(&Counters::gc_context); | 3809 HistogramTimerScope scope(&Counters::gc_context); |
3805 CollectAllGarbage(false); | 3810 CollectAllGarbage(false); |
3806 last_gc_count = gc_count_; | 3811 last_gc_count = gc_count_; |
3807 } | 3812 } |
3808 // If this is the first idle notification, we reset the | 3813 // If this is the first idle notification, we reset the |
3809 // notification count to avoid letting idle notifications for | 3814 // notification count to avoid letting idle notifications for |
3810 // context disposal garbage collections start a potentially too | 3815 // context disposal garbage collections start a potentially too |
3811 // aggressive idle GC cycle. | 3816 // aggressive idle GC cycle. |
3812 if (number_idle_notifications <= 1) { | 3817 if (number_idle_notifications <= 1) { |
3813 number_idle_notifications = 0; | 3818 number_idle_notifications = 0; |
3814 uncommit = false; | 3819 uncommit = false; |
3815 } | 3820 } |
| 3821 } else if (number_idle_notifications > kIdlesBeforeMarkCompact) { |
| 3822 // If we have received more than kIdlesBeforeMarkCompact idle |
| 3823 // notifications we do not perform any cleanup because we don't |
| 3824 // expect to gain much by doing so. |
| 3825 finished = true; |
3816 } | 3826 } |
3817 | 3827 |
3818 // Make sure that we have no pending context disposals and | 3828 // Make sure that we have no pending context disposals and |
3819 // conditionally uncommit from space. | 3829 // conditionally uncommit from space. |
3820 ASSERT(contexts_disposed_ == 0); | 3830 ASSERT(contexts_disposed_ == 0); |
3821 if (uncommit) Heap::UncommitFromSpace(); | 3831 if (uncommit) Heap::UncommitFromSpace(); |
3822 return finished; | 3832 return finished; |
3823 } | 3833 } |
3824 | 3834 |
3825 | 3835 |
(...skipping 1612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5438 void ExternalStringTable::TearDown() { | 5448 void ExternalStringTable::TearDown() { |
5439 new_space_strings_.Free(); | 5449 new_space_strings_.Free(); |
5440 old_space_strings_.Free(); | 5450 old_space_strings_.Free(); |
5441 } | 5451 } |
5442 | 5452 |
5443 | 5453 |
5444 List<Object*> ExternalStringTable::new_space_strings_; | 5454 List<Object*> ExternalStringTable::new_space_strings_; |
5445 List<Object*> ExternalStringTable::old_space_strings_; | 5455 List<Object*> ExternalStringTable::old_space_strings_; |
5446 | 5456 |
5447 } } // namespace v8::internal | 5457 } } // namespace v8::internal |
OLD | NEW |