From a3f0f942a391068eb586f867427aa14d489b50e5 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Thu, 28 Mar 2013 13:52:31 +0000 Subject: [PATCH] Always allocate symbols in old space. Keys are expected to be tenured. This now not only includes internalized strings, but also symbols. R=rossberg@chromium.org BUG= Review URL: https://chromiumcodereview.appspot.com/13158002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14095 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/heap.cc | 9 ++++++--- src/heap.h | 5 ++--- test/mjsunit/harmony/symbols.js | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/heap.cc b/src/heap.cc index 7c9a7fd632..98a530b5d7 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -5428,13 +5428,13 @@ MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { } -MaybeObject* Heap::AllocateSymbol(PretenureFlag pretenure) { +MaybeObject* Heap::AllocateSymbol() { // Statically ensure that it is safe to allocate symbols in paged spaces. STATIC_ASSERT(Symbol::kSize <= Page::kNonCodeObjectAreaSize); - AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; Object* result; - MaybeObject* maybe = AllocateRaw(Symbol::kSize, space, OLD_POINTER_SPACE); + MaybeObject* maybe = + AllocateRaw(Symbol::kSize, OLD_POINTER_SPACE, OLD_POINTER_SPACE); if (!maybe->ToObject(&result)) return maybe; HeapObject::cast(result)->set_map_no_write_barrier(symbol_map()); @@ -7470,6 +7470,9 @@ void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) { } name = internalized_string; } + // This cache is cleared only between mark compact passes, so we expect the + // cache to only contain old space names. + ASSERT(!HEAP->InNewSpace(name)); int index = (Hash(map, name) & kHashMask); // After a GC there will be free slots, so we use them in order (this may diff --git a/src/heap.h b/src/heap.h index 7a1d3c577e..8992e318e2 100644 --- a/src/heap.h +++ b/src/heap.h @@ -882,12 +882,11 @@ class Heap { void* external_pointer, PretenureFlag pretenure); - // Allocate a symbol. + // Allocate a symbol in old space. // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation // failed. // Please note this does not perform a garbage collection. - MUST_USE_RESULT MaybeObject* AllocateSymbol( - PretenureFlag pretenure = NOT_TENURED); + MUST_USE_RESULT MaybeObject* AllocateSymbol(); // Allocate a tenured JS global property cell. // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation diff --git a/test/mjsunit/harmony/symbols.js b/test/mjsunit/harmony/symbols.js index c2002e6ac7..93b6fbda4e 100644 --- a/test/mjsunit/harmony/symbols.js +++ b/test/mjsunit/harmony/symbols.js @@ -301,3 +301,19 @@ for (var i in objs) { TestKeyDescriptor(obj) TestKeyDelete(obj) } + + +function TestCachedKeyAfterScavenge() { + gc(); + // Keyed property lookup are cached. Hereby we assume that the keys are + // tenured, so that we only have to clear the cache between mark compacts, + // but not between scavenges. This must also apply for symbol keys. + var key = Symbol("key"); + var a = {}; + a[key] = "abc"; + + for (var i = 0; i < 1000000; i++) { + a[key] += "a"; // Allocations cause a scavenge. + } +} +TestCachedKeyAfterScavenge();