[gjs/wip/ptomato/mozjs31prep: 9/10] object: Use JS::Heap for GObject-JSObject weak ref
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs31prep: 9/10] object: Use JS::Heap for GObject-JSObject weak ref
- Date: Thu, 3 Nov 2016 01:23:15 +0000 (UTC)
commit 887b651fafbb2afd5087ba9539d48af5023bff4a
Author: Philip Chimento <philip endlessm com>
Date: Wed Nov 2 17:48:22 2016 -0700
object: Use JS::Heap for GObject-JSObject weak ref
This will be necessary in mozjs31 because the garbage collector could
move the object around, which should be tracked by JS::Heap.
Unlike other uses of JS::Heap, we do not want to either trace or root the
object, because it is supposed to be a weak reference.
gi/object.cpp | 36 +++++++++++++++++++++++++++++++-----
1 files changed, 31 insertions(+), 5 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index b4a0d0d..28cb9c0 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -101,6 +101,7 @@ GJS_DEFINE_PRIV_FROM_JS(ObjectInstance, gjs_object_instance_class)
static JSObject* peek_js_obj (GObject *gobj);
static void set_js_obj (GObject *gobj,
JSObject *obj);
+static void poison_js_obj(GObject *gobj);
static void disassociate_js_gobject (GObject *gobj);
static void invalidate_all_signals (ObjectInstance *priv);
@@ -1213,8 +1214,8 @@ disassociate_js_gobject (GObject *gobj)
invalidate_all_signals(priv);
release_native_object(priv);
- /* Use -1 to mark that a JS object once existed, but it doesn't any more */
- set_js_obj(gobj, (JSObject*)(-1));
+ /* Mark that a JS object once existed, but it doesn't any more */
+ poison_js_obj(gobj);
#if DEBUG_DISPOSE
g_object_weak_unref(gobj, wrapped_gobj_dispose_notify, object);
@@ -1973,15 +1974,34 @@ gjs_define_object_class(JSContext *context,
NULL, NULL, JSPROP_PERMANENT);
}
+static void
+release_heap_wrapper(gpointer data)
+{
+ delete static_cast<JS::Heap<JSObject *> *>(data);
+}
+
+static JS::Heap<JSObject *> *
+ensure_heap_wrapper(GObject *gobj)
+{
+ gpointer data = g_object_get_qdata(gobj, gjs_object_priv_quark());
+ if (G_UNLIKELY(data == NULL)) {
+ auto heap_object = new JS::Heap<JSObject *>();
+ g_object_set_qdata_full(gobj, gjs_object_priv_quark(), heap_object,
+ release_heap_wrapper);
+ return heap_object;
+ }
+ return static_cast<JS::Heap<JSObject *> *>(data);
+}
+
static JSObject*
peek_js_obj(GObject *gobj)
{
- JSObject *object = (JSObject*) g_object_get_qdata(gobj, gjs_object_priv_quark());
+ JSObject *object = ensure_heap_wrapper(gobj)->get();
if (G_UNLIKELY (object == (JSObject*)(-1))) {
g_critical ("Object %p (a %s) resurfaced after the JS wrapper was finalized. "
"This is some library doing dubious memory management inside dispose()",
- gobj, g_type_name(G_TYPE_FROM_INSTANCE(object)));
+ gobj, g_type_name(G_TYPE_FROM_INSTANCE(gobj)));
return NULL; /* return null to associate again with a new wrapper */
}
@@ -1992,7 +2012,13 @@ static void
set_js_obj(GObject *gobj,
JSObject *obj)
{
- g_object_set_qdata(gobj, gjs_object_priv_quark(), obj);
+ ensure_heap_wrapper(gobj)->set(obj);
+}
+
+static void
+poison_js_obj(GObject *gobj)
+{
+ ensure_heap_wrapper(gobj)->set((JSObject *) -1);
}
JSObject*
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]