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
This commit is contained in:
parent
47d8af7616
commit
a3f0f942a3
@ -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.
|
// Statically ensure that it is safe to allocate symbols in paged spaces.
|
||||||
STATIC_ASSERT(Symbol::kSize <= Page::kNonCodeObjectAreaSize);
|
STATIC_ASSERT(Symbol::kSize <= Page::kNonCodeObjectAreaSize);
|
||||||
AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE;
|
|
||||||
|
|
||||||
Object* result;
|
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;
|
if (!maybe->ToObject(&result)) return maybe;
|
||||||
|
|
||||||
HeapObject::cast(result)->set_map_no_write_barrier(symbol_map());
|
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;
|
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);
|
int index = (Hash(map, name) & kHashMask);
|
||||||
// After a GC there will be free slots, so we use them in order (this may
|
// After a GC there will be free slots, so we use them in order (this may
|
||||||
|
@ -882,12 +882,11 @@ class Heap {
|
|||||||
void* external_pointer,
|
void* external_pointer,
|
||||||
PretenureFlag pretenure);
|
PretenureFlag pretenure);
|
||||||
|
|
||||||
// Allocate a symbol.
|
// Allocate a symbol in old space.
|
||||||
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
||||||
// failed.
|
// failed.
|
||||||
// Please note this does not perform a garbage collection.
|
// Please note this does not perform a garbage collection.
|
||||||
MUST_USE_RESULT MaybeObject* AllocateSymbol(
|
MUST_USE_RESULT MaybeObject* AllocateSymbol();
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
|
|
||||||
// Allocate a tenured JS global property cell.
|
// Allocate a tenured JS global property cell.
|
||||||
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
||||||
|
@ -301,3 +301,19 @@ for (var i in objs) {
|
|||||||
TestKeyDescriptor(obj)
|
TestKeyDescriptor(obj)
|
||||||
TestKeyDelete(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();
|
||||||
|
Loading…
Reference in New Issue
Block a user