Reviewers: Vyacheslav Egorov,
Description:
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.
Please review this at https://chromiumcodereview.appspot.com/9169080/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/heap.h
M src/heap.cc
M test/cctest/test-mark-compact.cc
Index: src/heap.cc
===================================================================
--- src/heap.cc (revision 10510)
+++ src/heap.cc (working copy)
@@ -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,20 +2624,44 @@
}
-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() {
// Flush the number to string cache.
int len = number_string_cache()->length();
@@ -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);
}
Index: src/heap.h
===================================================================
--- src/heap.h (revision 10510)
+++ src/heap.h (working copy)
@@ -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_;
Index: test/cctest/test-mark-compact.cc
===================================================================
--- test/cctest/test-mark-compact.cc (revision 10510)
+++ test/cctest/test-mark-compact.cc (working copy)
@@ -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