/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80:
*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Exercise WeakCache<GCHashSet>.
BEGIN_TEST(testWeakCacheSet) { // Create two objects tenured and two in the nursery. If zeal is on, // this may fail and we'll get more tenured objects. That's fine: // the test will continue to work, it will just not test as much.
JS::RootedObject tenured1(cx, JS_NewPlainObject(cx));
JS::RootedObject tenured2(cx, JS_NewPlainObject(cx));
JS_GC(cx);
JS::RootedObject nursery1(cx, JS_NewPlainObject(cx));
JS::RootedObject nursery2(cx, JS_NewPlainObject(cx));
using ObjectSet =
GCHashSet<HeapPtr<JSObject*>, StableCellHasher<HeapPtr<JSObject*>>,
SystemAllocPolicy>; using Cache = JS::WeakCache<ObjectSet>;
Cache cache(JS::GetObjectZone(tenured1));
// Verify relocation and that we don't sweep too aggressively.
JS_GC(cx);
CHECK(cache.has(tenured1));
CHECK(cache.has(tenured2));
CHECK(cache.has(nursery1));
CHECK(cache.has(nursery2));
// Unroot two entries and verify that they get removed.
tenured2 = nursery2 = nullptr;
JS_GC(cx);
CHECK(cache.has(tenured1));
CHECK(cache.has(nursery1));
CHECK(cache.count() == 2);
returntrue;
}
END_TEST(testWeakCacheSet)
// Exercise WeakCache<GCHashMap>.
BEGIN_TEST(testWeakCacheMap) { // Create two objects tenured and two in the nursery. If zeal is on, // this may fail and we'll get more tenured objects. That's fine: // the test will continue to work, it will just not test as much.
JS::RootedObject tenured1(cx, JS_NewPlainObject(cx));
JS::RootedObject tenured2(cx, JS_NewPlainObject(cx));
JS_GC(cx);
JS::RootedObject nursery1(cx, JS_NewPlainObject(cx));
JS::RootedObject nursery2(cx, JS_NewPlainObject(cx));
using ObjectMap = js::GCHashMap<HeapPtr<JSObject*>, uint32_t,
js::StableCellHasher<HeapPtr<JSObject*>>>; using Cache = JS::WeakCache<ObjectMap>;
Cache cache(JS::GetObjectZone(tenured1), cx);
// Exercise WeakCache<GCVector>.
BEGIN_TEST(testWeakCacheGCVector) { // Create two objects tenured and two in the nursery. If zeal is on, // this may fail and we'll get more tenured objects. That's fine: // the test will continue to work, it will just not test as much.
JS::RootedObject tenured1(cx, JS_NewPlainObject(cx));
JS::RootedObject tenured2(cx, JS_NewPlainObject(cx));
JS_GC(cx);
JS::RootedObject nursery1(cx, JS_NewPlainObject(cx));
JS::RootedObject nursery2(cx, JS_NewPlainObject(cx));
using ObjectVector = JS::WeakCache<GCVector<HeapPtr<JSObject*>>>;
ObjectVector cache(JS::GetObjectZone(tenured1), cx);
// A simple structure that embeds an object pointer. We cripple the hash // implementation so that we can test hash table collisions. struct ObjectEntry {
HeapPtr<JSObject*> obj; explicit ObjectEntry(JSObject* o) : obj(o) {} booloperator==(const ObjectEntry& other) const { return obj == other.obj; } bool traceWeak(JSTracer* trc) { return TraceWeakEdge(trc, &obj, "ObjectEntry::obj");
}
};
namespace js { template <> struct StableCellHasher<ObjectEntry> { using Key = ObjectEntry; using Lookup = JSObject*;
staticbool maybeGetHash(const Lookup& l, HashNumber* hashOut) { if (!StableCellHasher<JSObject*>::maybeGetHash(l, hashOut)) { returnfalse;
} // Reduce hash code to single bit to generate hash collisions.
*hashOut &= 0x1; returntrue;
} staticbool ensureHash(const Lookup& l, HashNumber* hashOut) { if (!StableCellHasher<JSObject*>::ensureHash(l, hashOut)) { returnfalse;
} // Reduce hash code to single bit to generate hash collisions.
*hashOut &= 0x1; returntrue;
} static HashNumber hash(const Lookup& l) { // Reduce hash code to single bit to generate hash collisions. return StableCellHasher<HeapPtr<JSObject*>>::hash(l) & 0x1;
} staticbool match(const Key& k, const Lookup& l) { return StableCellHasher<HeapPtr<JSObject*>>::match(k.obj, l);
}
};
} // namespace js
// A structure that contains a pointer to a JSObject but is keyed based on an // integer. This lets us test replacing dying entries in a set. struct NumberAndObjectEntry {
uint32_t number;
HeapPtr<JSObject*> obj;
bool TestUniqueIDLookups() { // Test hash table lookups during incremental sweeping where the hash is // generated based on a unique ID. The problem is that the unique ID table // will have already been swept by this point so looking up a dead pointer // in the table will fail. This lookup happens if we try to match a live key // against a dead table entry with the same hash code.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.