Revision: 10513
Author:   [email protected]
Date:     Thu Jan 26 03:32:01 2012
Log: Flush number string cache on GC (bug 1605). Also start with a small
number string cache and only grow it if needed, which will be useful
for saving boot time memory use.
This is a second try for  https://chromiumcodereview.appspot.com/923502
after fixing an unrelated stack overflow issue.
Review URL: https://chromiumcodereview.appspot.com/9169080
http://code.google.com/p/v8/source/detail?r=10513

Modified:
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/test/cctest/test-mark-compact.cc

=======================================
--- /branches/bleeding_edge/src/heap.cc Wed Jan 25 07:17:26 2012
+++ /branches/bleeding_edge/src/heap.cc Thu Jan 26 03:32:01 2012
@@ -902,8 +902,7 @@

   CompletelyClearInstanceofCache();

-  // TODO(1605) select heuristic for flushing NumberString cache with
-  // FlushNumberStringCache
+  FlushNumberStringCache();
   if (FLAG_cleanup_code_caches_at_gc) {
     polymorphic_code_cache()->set_cache(undefined_value());
   }
@@ -2512,7 +2511,10 @@
   }
   set_intrinsic_function_names(StringDictionary::cast(obj));

-  if (InitializeNumberStringCache()->IsFailure()) return false;
+  { MaybeObject* maybe_obj = AllocateInitialNumberStringCache();
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_number_string_cache(FixedArray::cast(obj));

   // Allocate cache for single character ASCII strings.
   { MaybeObject* maybe_obj =
@@ -2622,18 +2624,42 @@
 }


-MaybeObject* Heap::InitializeNumberStringCache() {
- // Compute the size of the number string cache based on the max heap size.
-  // max_semispace_size_ == 512 KB => number_string_cache_size = 32.
-  // max_semispace_size_ ==   8 MB => number_string_cache_size = 16KB.
-  int number_string_cache_size = max_semispace_size_ / 512;
-  number_string_cache_size = Max(32, Min(16*KB, number_string_cache_size));
-  Object* obj;
+MaybeObject* Heap::AllocateInitialNumberStringCache() {
   MaybeObject* maybe_obj =
-      AllocateFixedArray(number_string_cache_size * 2, TENURED);
- if (maybe_obj->ToObject(&obj)) set_number_string_cache(FixedArray::cast(obj));
+      AllocateFixedArray(kInitialNumberStringCacheSize * 2, TENURED);
   return maybe_obj;
 }
+
+
+int Heap::FullSizeNumberStringCacheLength() {
+ // Compute the size of the number string cache based on the max newspace size. + // The number string cache has a minimum size based on twice the initial cache
+  // size to ensure that it is bigger after being made 'full size'.
+  int number_string_cache_size = max_semispace_size_ / 512;
+  number_string_cache_size = Max(kInitialNumberStringCacheSize * 2,
+                                 Min(0x4000, number_string_cache_size));
+ // There is a string and a number per entry so the length is twice the number
+  // of entries.
+  return number_string_cache_size * 2;
+}
+
+
+void Heap::AllocateFullSizeNumberStringCache() {
+ // The idea is to have a small number string cache in the snapshot to keep + // boot-time memory usage down. If we expand the number string cache already
+  // while creating the snapshot then that didn't work out.
+  ASSERT(!Serializer::enabled());
+  MaybeObject* maybe_obj =
+      AllocateFixedArray(FullSizeNumberStringCacheLength(), TENURED);
+  Object* new_cache;
+  if (maybe_obj->ToObject(&new_cache)) {
+ // We don't bother to repopulate the cache with entries from the old cache.
+    // It will be repopulated soon enough with new strings.
+    set_number_string_cache(FixedArray::cast(new_cache));
+  }
+ // If allocation fails then we just return without doing anything. It is only
+  // a cache, so best effort is OK here.
+}


 void Heap::FlushNumberStringCache() {
@@ -2681,11 +2707,17 @@
   int mask = (number_string_cache()->length() >> 1) - 1;
   if (number->IsSmi()) {
     hash = smi_get_hash(Smi::cast(number)) & mask;
-    number_string_cache()->set(hash * 2, Smi::cast(number));
   } else {
     hash = double_get_hash(number->Number()) & mask;
-    number_string_cache()->set(hash * 2, number);
-  }
+  }
+  if (number_string_cache()->get(hash * 2) != undefined_value() &&
+ number_string_cache()->length() != FullSizeNumberStringCacheLength()) {
+    // The first time we have a hash collision, we move to the full sized
+    // number string cache.
+    AllocateFullSizeNumberStringCache();
+    return;
+  }
+  number_string_cache()->set(hash * 2, number);
   number_string_cache()->set(hash * 2 + 1, string);
 }

=======================================
--- /branches/bleeding_edge/src/heap.h  Wed Jan 25 07:17:26 2012
+++ /branches/bleeding_edge/src/heap.h  Thu Jan 26 03:32:01 2012
@@ -1798,8 +1798,13 @@
   GCTracer* tracer_;


- // Initializes the number to string cache based on the max semispace size.
-  MUST_USE_RESULT MaybeObject* InitializeNumberStringCache();
+  // Allocates a small number to string cache.
+  MUST_USE_RESULT MaybeObject* AllocateInitialNumberStringCache();
+  // Creates and installs the full-sized number string cache.
+  void AllocateFullSizeNumberStringCache();
+ // Get the length of the number to string cache based on the max semispace
+  // size.
+  int FullSizeNumberStringCacheLength();
   // Flush the number to string cache.
   void FlushNumberStringCache();

@@ -1896,6 +1901,7 @@

   static const int kInitialSymbolTableSize = 2048;
   static const int kInitialEvalCacheSize = 64;
+  static const int kInitialNumberStringCacheSize = 256;

   // Maximum GC pause.
   int max_gc_pause_;
=======================================
--- /branches/bleeding_edge/test/cctest/test-mark-compact.cc Wed Jan 25 07:17:26 2012 +++ /branches/bleeding_edge/test/cctest/test-mark-compact.cc Thu Jan 26 03:32:01 2012
@@ -540,7 +540,7 @@
       }
     } else {
       if (v8::internal::Snapshot::IsEnabled()) {
-        CHECK_LE(booted_memory - initial_memory, 6500 * 1024);  // 6365.
+        CHECK_LE(booted_memory - initial_memory, 6500 * 1024);  // 6356.
       } else {
         CHECK_LE(booted_memory - initial_memory, 6654 * 1024);  // 6424
       }

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to