Add LowMemoryNotification to the API on Android platform.
authorfeng@chromium.org <feng@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Aug 2009 00:07:19 +0000 (00:07 +0000)
committerfeng@chromium.org <feng@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Aug 2009 00:07:19 +0000 (00:07 +0000)
Android system provides a unique feature that it sends a notification to the
browser in low memory condition, and the browser cleans up cache and frees
resources. Forcing a GC in low memory condition can free DOM objects and also
can shrink the old spaces.

This patch addresses the last comment in
http://codereview.chromium.org/173016/show

Mads Ager 2009/08/19 17:24:23
I would prefer to not use the flags to signal that a compacting collection is
requested.

TBR = ager
Review URL: http://codereview.chromium.org/173102

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2725 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
src/heap.cc
src/heap.h
src/mark-compact.cc
src/mark-compact.h

index 9608bf2..c7cc315 100644 (file)
@@ -2284,6 +2284,12 @@ class V8EXPORT V8 {
    */
   static void IdleNotification(bool is_high_priority);
 
+  /**
+   * Optional notification that the system is running low on memory.
+   * V8 uses these notifications to attempt to free memory.
+   */
+  static void LowMemoryNotification();
+
  private:
   V8();
 
index 10475f3..7d97fc6 100644 (file)
@@ -2604,10 +2604,18 @@ bool v8::V8::Dispose() {
 }
 
 
-void  v8::V8::IdleNotification(bool is_high_priority) {
+void v8::V8::IdleNotification(bool is_high_priority) {
   i::V8::IdleNotification(is_high_priority);
 }
 
+
+void v8::V8::LowMemoryNotification() {
+#if defined(ANDROID)
+  i::Heap::CollectAllGarbage(true);
+#endif
+}
+
+
 const char* v8::V8::GetVersion() {
   static v8::internal::EmbeddedVector<char, 128> buffer;
   v8::internal::Version::GetString(buffer);
index c7e7e67..c57137d 100644 (file)
@@ -315,11 +315,13 @@ void Heap::GarbageCollectionEpilogue() {
 }
 
 
-void Heap::CollectAllGarbage() {
+void Heap::CollectAllGarbage(bool force_compaction) {
   // Since we are ignoring the return value, the exact choice of space does
   // not matter, so long as we do not specify NEW_SPACE, which would not
   // cause a full GC.
+  MarkCompactCollector::SetForceCompaction(force_compaction);
   CollectGarbage(0, OLD_POINTER_SPACE);
+  MarkCompactCollector::SetForceCompaction(false);
 }
 
 
index ceec85c..a9d44c6 100644 (file)
@@ -627,8 +627,9 @@ class Heap : public AllStatic {
   // Returns whether required_space bytes are available after the collection.
   static bool CollectGarbage(int required_space, AllocationSpace space);
 
-  // Performs a full garbage collection.
-  static void CollectAllGarbage();
+  // Performs a full garbage collection. Force compaction if the
+  // parameter is true.
+  static void CollectAllGarbage(bool force_compaction = false);
 
   // Performs a full garbage collection if a context has been disposed
   // since the last time the check was performed.
index 6e823b3..10e81ac 100644 (file)
@@ -39,6 +39,7 @@ namespace internal {
 // -------------------------------------------------------------------------
 // MarkCompactCollector
 
+bool MarkCompactCollector::force_compaction_ = false;
 bool MarkCompactCollector::compacting_collection_ = false;
 
 int MarkCompactCollector::previous_marked_count_ = 0;
@@ -110,7 +111,7 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
 #endif
   ASSERT(!FLAG_always_compact || !FLAG_never_compact);
 
-  compacting_collection_ = FLAG_always_compact;
+  compacting_collection_ = FLAG_always_compact || force_compaction_;
 
   // We compact the old generation if it gets too fragmented (ie, we could
   // recover an expected amount of space by reclaiming the waste and free
index bd9e4a0..0bd212e 100644 (file)
@@ -75,6 +75,12 @@ class MarkCompactCollector: public AllStatic {
   // Type of functions to process non-live objects.
   typedef void (*ProcessNonLiveFunction)(HeapObject* object);
 
+  // Set the global force_compaction flag, it must be called before Prepare
+  // to take effect.
+  static void SetForceCompaction(bool value) {
+    force_compaction_ = value;
+  }
+
   // Prepares for GC by resetting relocation info in old and map spaces and
   // choosing spaces to compact.
   static void Prepare(GCTracer* tracer);
@@ -117,6 +123,10 @@ class MarkCompactCollector: public AllStatic {
   // The current stage of the collector.
   static CollectorState state_;
 #endif
+
+  // Global flag that forces a compaction.
+  static bool force_compaction_;
+
   // Global flag indicating whether spaces were compacted on the last GC.
   static bool compacting_collection_;