Bug 1073577 - Fix new object cache interactions with moving GC r=terrence

This commit is contained in:
Jon Coppeard 2014-09-30 13:20:48 +01:00
parent 6bb9f1c44a
commit b91c15b771
2 changed files with 15 additions and 5 deletions

View File

@ -1525,8 +1525,10 @@ js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp,
allocKind = GetBackgroundAllocKind(allocKind);
NewObjectCache::EntryIndex entry = -1;
uint64_t gcNumber = 0;
if (JSContext *cx = cxArg->maybeJSContext()) {
NewObjectCache &cache = cx->runtime()->newObjectCache;
JSRuntime *rt = cx->runtime();
NewObjectCache &cache = rt->newObjectCache;
if (protoArg.isObject() &&
newKind == GenericObject &&
!cx->compartment()->hasObjectMetadataCallback() &&
@ -1547,6 +1549,7 @@ js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp,
}
}
}
gcNumber = rt->gc.gcNumber();
}
Rooted<TaggedProto> proto(cxArg, protoArg);
@ -1567,7 +1570,9 @@ js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp,
if (!obj)
return nullptr;
if (entry != -1 && !obj->hasDynamicSlots()) {
if (entry != -1 && !obj->hasDynamicSlots() &&
cxArg->asJSContext()->runtime()->gc.gcNumber() == gcNumber)
{
cxArg->asJSContext()->runtime()->newObjectCache.fillProto(entry, clasp,
proto, allocKind, obj);
}

View File

@ -315,18 +315,23 @@ class NewObjectCache
void invalidateEntriesForShape(JSContext *cx, HandleShape shape, HandleObject proto);
private:
bool lookup(const Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) {
EntryIndex makeIndex(const Class *clasp, gc::Cell *key, gc::AllocKind kind) {
uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
*pentry = hash % mozilla::ArrayLength(entries);
return hash % mozilla::ArrayLength(entries);
}
bool lookup(const Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) {
*pentry = makeIndex(clasp, key, kind);
Entry *entry = &entries[*pentry];
/* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
return entry->clasp == clasp && entry->key == key;
}
void fill(EntryIndex entry_, const Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj) {
void fill(EntryIndex entry_, const Class *clasp, gc::Cell *key, gc::AllocKind kind,
JSObject *obj) {
JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
JS_ASSERT(entry_ == makeIndex(clasp, key, kind));
Entry *entry = &entries[entry_];
JS_ASSERT(!obj->hasDynamicSlots() && !obj->hasDynamicElements());