summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi-tests/testGCWeakRef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jsapi-tests/testGCWeakRef.cpp')
-rw-r--r--js/src/jsapi-tests/testGCWeakRef.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testGCWeakRef.cpp b/js/src/jsapi-tests/testGCWeakRef.cpp
new file mode 100644
index 000000000..d658106b2
--- /dev/null
+++ b/js/src/jsapi-tests/testGCWeakRef.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+* vim: set ts=8 sts=4 et sw=4 tw=99:
+*/
+/* 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 "gc/Barrier.h"
+#include "js/RootingAPI.h"
+
+#include "jsapi-tests/tests.h"
+
+struct MyHeap
+{
+ explicit MyHeap(JSObject* obj) : weak(obj) {}
+ js::WeakRef<JSObject*> weak;
+
+ void trace(JSTracer* trc) {
+ js::TraceWeakEdge(trc, &weak, "weak");
+ }
+};
+
+BEGIN_TEST(testGCWeakRef)
+{
+ // Create an object and add a property to it so that we can read the
+ // property back later to verify that object internals are not garbage.
+ JS::RootedObject obj(cx, JS_NewPlainObject(cx));
+ CHECK(obj);
+ CHECK(JS_DefineProperty(cx, obj, "x", 42, 0));
+
+ // Store the object behind a weak pointer and remove other references.
+ JS::Rooted<MyHeap> heap(cx, MyHeap(obj));
+ obj = nullptr;
+
+ cx->gc.minorGC(JS::gcreason::API);
+
+ // The minor collection should have treated the weak ref as a strong ref,
+ // so the object should still be live, despite not having any other live
+ // references.
+ CHECK(heap.get().weak.unbarrieredGet() != nullptr);
+ obj = heap.get().weak;
+ JS::RootedValue v(cx);
+ CHECK(JS_GetProperty(cx, obj, "x", &v));
+ CHECK(v.isInt32());
+ CHECK(v.toInt32() == 42);
+
+ // A full collection with a second ref should keep the object as well.
+ CHECK(obj == heap.get().weak);
+ JS_GC(cx);
+ CHECK(obj == heap.get().weak);
+ v = JS::UndefinedValue();
+ CHECK(JS_GetProperty(cx, obj, "x", &v));
+ CHECK(v.isInt32());
+ CHECK(v.toInt32() == 42);
+
+ // A full collection after nulling the root should collect the object, or
+ // at least null out the weak reference before returning to the mutator.
+ obj = nullptr;
+ JS_GC(cx);
+ CHECK(heap.get().weak == nullptr);
+
+ return true;
+}
+END_TEST(testGCWeakRef)
+