[gjs] context: Drain toggle queue at start of GC
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] context: Drain toggle queue at start of GC
- Date: Sat, 1 Apr 2017 20:29:05 +0000 (UTC)
commit 404e7053ac9805ed2cb0259138e9ac0e4464f03f
Author: Philip Chimento <philip endlessm com>
Date: Thu Mar 9 18:45:48 2017 -0800
context: Drain toggle queue at start of GC
In order to minimize the chances of a JS object being garbage collected
while it is queued to toggle up, we handle all pending object toggles
when garbage collection starts.
https://bugzilla.gnome.org/show_bug.cgi?id=778862
gi/object.cpp | 5 ++---
gjs/context.cpp | 20 +++++++++++++++-----
2 files changed, 17 insertions(+), 8 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 91a10bc..0bd4b12 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1021,9 +1021,8 @@ wrapped_gobj_toggle_notify(gpointer data,
* is dead, and attempting to keep it alive would soon crash
* the process. Plus, if we touch the JSAPI, libmozjs aborts in
* the first BeginRequest.
- * Thus, in the toggleup+sweeping case we deassociate the object
- * and the wrapper and let the wrapper die. Then, if the object
- * appears again, we log a critical.
+ * Thus, we drain the toggle queue when GC starts, in order to
+ * prevent this from happening.
* In practice, a toggle up during JS finalize can only happen
* for temporary refs/unrefs of objects that are garbage anyway,
* because JS code is never invoked while the finalizers run
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 30c9ca6..e55e667 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -279,6 +279,19 @@ gjs_printerr(JSContext *context,
return true;
}
+static void
+on_garbage_collect(JSRuntime *rt,
+ JSGCStatus status,
+ void *data)
+{
+ /* We finalize any pending toggle refs before doing any garbage collection,
+ * so that we can collect the JS wrapper objects, and in order to minimize
+ * the chances of objects having a pending toggle up queued when they are
+ * garbage collected. */
+ if (status == JSGC_BEGIN)
+ gjs_object_clear_toggles();
+}
+
/* Requires request, does not throw error */
static bool
gjs_define_promise_object(JSContext *cx,
@@ -403,11 +416,6 @@ gjs_context_dispose(GObject *object)
gjs_debug(GJS_DEBUG_CONTEXT,
"Destroying JS context");
- /* Finalize any pending toggle refs left over on the main context,
- * before doing any garbage collection, so that we can collect the JS
- * wrapper objects */
- gjs_object_clear_toggles();
-
JS_BeginRequest(js_context->context);
/* Do a full GC here before tearing down, since once we do
@@ -505,6 +513,8 @@ gjs_context_constructed(GObject *object)
JS_BeginRequest(js_context->context);
+ JS_SetGCCallback(js_context->runtime, on_garbage_collect, js_context);
+
/* set ourselves as the private data */
JS_SetContextPrivate(js_context->context, js_context);
JS::RootedObject global(js_context->context);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]