/* -*- 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/. */
#include"js/GCVector.h"
#include"jsapi-tests/tests.h"
#include"gc/StableCellHasher-inl.h"
usingnamespace js;
staticvoid MinimizeHeap(JSContext* cx) { // The second collection is to force us to wait for the background // sweeping that the first GC started to finish.
JS_GC(cx);
JS_GC(cx);
js::gc::FinishGC(cx);
}
// Do not start with an ID.
CHECK(!gc::HasUniqueId(obj));
// Ensure we can get a new UID.
CHECK(gc::GetOrCreateUniqueId(obj, &uid));
CHECK(uid > gc::LargestTaggedNullCellPointer);
// We should now have an id.
CHECK(gc::HasUniqueId(obj));
// Calling again should get us the same thing.
CHECK(gc::GetOrCreateUniqueId(obj, &tmp));
CHECK(uid == tmp);
// Tenure the thing and check that the UID moved with it.
MinimizeHeap(cx);
uintptr_t tenuredAddr = uintptr_t(obj.get());
CHECK(tenuredAddr != nurseryAddr);
CHECK(!gc::IsInsideNursery(obj));
CHECK(gc::HasUniqueId(obj));
CHECK(gc::GetOrCreateUniqueId(obj, &tmp));
CHECK(uid == tmp);
// Allocate a new nursery thing in the same location and check that we // removed the prior uid that was attached to the location.
obj = JS_NewPlainObject(cx);
CHECK(obj);
CHECK(uintptr_t(obj.get()) == nurseryAddr);
CHECK(!gc::HasUniqueId(obj));
// Try to get another tenured object in the same location and check that // the uid was removed correctly.
obj = nullptr;
MinimizeHeap(cx);
obj = JS_NewPlainObject(cx);
MinimizeHeap(cx);
CHECK(uintptr_t(obj.get()) == tenuredAddr);
CHECK(!gc::HasUniqueId(obj));
CHECK(gc::GetOrCreateUniqueId(obj, &tmp));
CHECK(uid != tmp);
uid = tmp;
// Allocate a few arenas worth of objects to ensure we get some compaction. conststatic size_t N = 2049; using ObjectVector = JS::GCVector<JSObject*>;
JS::Rooted<ObjectVector> vec(cx, ObjectVector(cx)); for (size_t i = 0; i < N; ++i) {
obj = JS_NewPlainObject(cx);
CHECK(obj);
CHECK(vec.append(obj));
}
// Transfer our vector to tenured if it isn't there already.
MinimizeHeap(cx);
// Tear holes in the heap by unrooting the even objects and collecting.
JS::Rooted<ObjectVector> vec2(cx, ObjectVector(cx)); for (size_t i = 0; i < N; ++i) { if (i % 2 == 1) {
CHECK(vec2.append(vec[i]));
}
}
vec.clear();
// Grab the last object in the vector as our object of interest.
obj = vec2.back();
CHECK(obj);
CHECK(!gc::IsInsideNursery(obj));
tenuredAddr = uintptr_t(obj.get());
CHECK(gc::GetOrCreateUniqueId(obj, &uid));
// Force a compaction to move the object and check that the uid moved to // the new tenured heap location.
JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, JS::GCOptions::Shrink, JS::GCReason::API);
// There's a very low probability that this check could fail, but it is // possible. If it becomes an annoying intermittent then we should make // this test more robust by recording IDs of many objects and then checking // that some have moved.
CHECK(uintptr_t(obj.get()) != tenuredAddr);
CHECK(gc::HasUniqueId(obj));
CHECK(gc::GetOrCreateUniqueId(obj, &tmp));
CHECK(uid == tmp);
returntrue;
}
END_TEST(testGCUID)
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
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.