Revision: 2748 Author: [email protected] Date: Mon Aug 24 19:54:39 2009 Log: Update the Idle collector to do a full GC after being idle for some time.
Remove the default argument from CollectAllGarbage. Review URL: http://codereview.chromium.org/174302 http://code.google.com/p/v8/source/detail?r=2748 Modified: /branches/bleeding_edge/include/v8.h /branches/bleeding_edge/src/api.cc /branches/bleeding_edge/src/debug.cc /branches/bleeding_edge/src/execution.cc /branches/bleeding_edge/src/heap-inl.h /branches/bleeding_edge/src/heap.cc /branches/bleeding_edge/src/heap.h /branches/bleeding_edge/src/mksnapshot.cc /branches/bleeding_edge/src/runtime.cc /branches/bleeding_edge/src/v8.cc /branches/bleeding_edge/src/v8.h ======================================= --- /branches/bleeding_edge/include/v8.h Wed Aug 19 17:07:19 2009 +++ /branches/bleeding_edge/include/v8.h Mon Aug 24 19:54:39 2009 @@ -2280,9 +2280,13 @@ /** * Optional notification that the embedder is idle. * V8 uses the notification to reduce memory footprint. + * This call can be used repeatedly if the embedder remains idle. * \param is_high_priority tells whether the embedder is high priority. + * Returns true if the embedder should stop calling IdleNotification + * until real work has been done. This indicates that V8 has done + * as much cleanup as it will be able to do. */ - static void IdleNotification(bool is_high_priority); + static bool IdleNotification(bool is_high_priority); /** * Optional notification that the system is running low on memory. ======================================= --- /branches/bleeding_edge/src/api.cc Wed Aug 19 17:07:19 2009 +++ /branches/bleeding_edge/src/api.cc Mon Aug 24 19:54:39 2009 @@ -2604,8 +2604,8 @@ } -void v8::V8::IdleNotification(bool is_high_priority) { - i::V8::IdleNotification(is_high_priority); +bool v8::V8::IdleNotification(bool is_high_priority) { + return i::V8::IdleNotification(is_high_priority); } @@ -3335,7 +3335,7 @@ flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU); const int current_flags = i::Logger::GetActiveProfilerModules(); i::Logger::ResumeProfiler(flags); - i::Heap::CollectAllGarbage(); + i::Heap::CollectAllGarbage(false); i::Logger::PauseProfiler(~current_flags & flags); } else { i::Logger::ResumeProfiler(flags); ======================================= --- /branches/bleeding_edge/src/debug.cc Mon Aug 24 09:08:44 2009 +++ /branches/bleeding_edge/src/debug.cc Mon Aug 24 19:54:39 2009 @@ -1548,8 +1548,8 @@ // Perform two GCs to get rid of all unreferenced scripts. The first GC gets // rid of all the cached script wrappers and the second gets rid of the // scripts which is no longer referenced. - Heap::CollectAllGarbage(); - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); + Heap::CollectAllGarbage(false); ASSERT(script_cache_ == NULL); script_cache_ = new ScriptCache(); @@ -1599,7 +1599,7 @@ // Perform GC to get unreferenced scripts evicted from the cache before // returning the content. - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); // Get the scripts from the cache. return script_cache_->GetScripts(); ======================================= --- /branches/bleeding_edge/src/execution.cc Wed Aug 19 08:14:11 2009 +++ /branches/bleeding_edge/src/execution.cc Mon Aug 24 19:54:39 2009 @@ -677,7 +677,7 @@ v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { // All allocation spaces other than NEW_SPACE have the same effect. - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); return v8::Undefined(); } ======================================= --- /branches/bleeding_edge/src/heap-inl.h Mon Aug 3 04:05:26 2009 +++ /branches/bleeding_edge/src/heap-inl.h Mon Aug 24 19:54:39 2009 @@ -238,7 +238,7 @@ amount_of_external_allocated_memory_ - amount_of_external_allocated_memory_at_last_global_gc_; if (amount_since_last_global_gc > external_allocation_limit_) { - CollectAllGarbage(); + CollectAllGarbage(false); } } else { // Avoid underflow. @@ -285,7 +285,7 @@ } \ if (!__object__->IsRetryAfterGC()) RETURN_EMPTY; \ Counters::gc_last_resort_from_handles.Increment(); \ - Heap::CollectAllGarbage(); \ + Heap::CollectAllGarbage(false); \ { \ AlwaysAllocateScope __scope__; \ __object__ = FUNCTION_CALL; \ ======================================= --- /branches/bleeding_edge/src/heap.cc Fri Aug 21 06:14:53 2009 +++ /branches/bleeding_edge/src/heap.cc Mon Aug 24 19:54:39 2009 @@ -332,7 +332,7 @@ // informed decisions about when to force a collection. if (!FLAG_expose_gc && context_disposed_pending_) { HistogramTimerScope scope(&Counters::gc_context); - CollectAllGarbage(); + CollectAllGarbage(false); } context_disposed_pending_ = false; } ======================================= --- /branches/bleeding_edge/src/heap.h Mon Aug 24 04:57:57 2009 +++ /branches/bleeding_edge/src/heap.h Mon Aug 24 19:54:39 2009 @@ -629,7 +629,7 @@ // Performs a full garbage collection. Force compaction if the // parameter is true. - static void CollectAllGarbage(bool force_compaction = false); + static void CollectAllGarbage(bool force_compaction); // Performs a full garbage collection if a context has been disposed // since the last time the check was performed. @@ -841,6 +841,39 @@ return (PromotedSpaceSize() + PromotedExternalMemorySize()) > old_gen_allocation_limit_; } + + // Can be called when the embedding application is idle. + static bool IdleNotification() { + static const int kIdlesBeforeCollection = 7; + static int number_idle_notifications = 0; + static int last_gc_count = gc_count_; + + bool finished = false; + + if (last_gc_count == gc_count_) { + number_idle_notifications++; + } else { + number_idle_notifications = 0; + last_gc_count = gc_count_; + } + + if (number_idle_notifications >= kIdlesBeforeCollection) { + // The first time through we collect without forcing compaction. + // The second time through we force compaction and quit. + bool force_compaction = + number_idle_notifications > kIdlesBeforeCollection; + CollectAllGarbage(force_compaction); + last_gc_count = gc_count_; + if (force_compaction) { + number_idle_notifications = 0; + finished = true; + } + } + + // Uncommit unused memory in new space. + Heap::UncommitFromSpace(); + return finished; + } // Declare all the root indices. enum RootListIndex { ======================================= --- /branches/bleeding_edge/src/mksnapshot.cc Tue Apr 14 07:58:23 2009 +++ /branches/bleeding_edge/src/mksnapshot.cc Mon Aug 24 19:54:39 2009 @@ -171,7 +171,7 @@ } } // Get rid of unreferenced scripts with a global GC. - i::Heap::CollectAllGarbage(); + i::Heap::CollectAllGarbage(false); i::Serializer ser; ser.Serialize(); v8::internal::byte* bytes; ======================================= --- /branches/bleeding_edge/src/runtime.cc Wed Aug 19 00:30:20 2009 +++ /branches/bleeding_edge/src/runtime.cc Mon Aug 24 19:54:39 2009 @@ -7263,7 +7263,7 @@ ASSERT(args.length() == 3); // First perform a full GC in order to avoid references from dead objects. - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); // Check parameters. CONVERT_CHECKED(JSObject, target, args[0]); @@ -7339,7 +7339,7 @@ ASSERT(args.length() == 2); // First perform a full GC in order to avoid dead objects. - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); // Check parameters. CONVERT_CHECKED(JSFunction, constructor, args[0]); @@ -7633,7 +7633,7 @@ // Handle last resort GC and make sure to allow future allocations // to grow the heap without causing GCs (if possible). Counters::gc_last_resort_from_js.Increment(); - Heap::CollectAllGarbage(); + Heap::CollectAllGarbage(false); } } ======================================= --- /branches/bleeding_edge/src/v8.cc Thu Aug 20 01:12:30 2009 +++ /branches/bleeding_edge/src/v8.cc Mon Aug 24 19:54:39 2009 @@ -157,13 +157,13 @@ } -void V8::IdleNotification(bool is_high_priority) { - if (!FLAG_use_idle_notification) return; +bool V8::IdleNotification(bool is_high_priority) { + if (!FLAG_use_idle_notification) return false; // Ignore high priority instances of V8. - if (is_high_priority) return; - - // Uncommit unused memory in new space. - Heap::UncommitFromSpace(); + if (is_high_priority) return false; + + // Tell the heap that it may want to adjust. + return Heap::IdleNotification(); } ======================================= --- /branches/bleeding_edge/src/v8.h Thu Aug 13 02:35:51 2009 +++ /branches/bleeding_edge/src/v8.h Mon Aug 24 19:54:39 2009 @@ -100,7 +100,7 @@ static Smi* RandomPositiveSmi(); // Idle notification directly from the API. - static void IdleNotification(bool is_high_priority); + static bool IdleNotification(bool is_high_priority); private: // True if engine is currently running --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
