[gjs/wip/ptomato/mozjs38: 22/24] WIP - object.cpp weak pointer callback



commit 7ada1ba12c347f5e09a9e545bdbade690cf5475c
Author: Philip Chimento <philip chimento gmail com>
Date:   Wed Jan 11 23:37:28 2017 -0800

    WIP - object.cpp weak pointer callback
    
    Weak pointers need callbacks now!

 gi/object.cpp |   58 ++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 39 insertions(+), 19 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 7a7be6c..4eb60b1 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -23,6 +23,7 @@
 
 #include <config.h>
 
+#include <deque>
 #include <memory>
 #include <stack>
 #include <string.h>
@@ -93,6 +94,11 @@ enum {
 static std::stack<JS::PersistentRootedObject> object_init_list;
 static GHashTable *class_init_properties;
 
+static bool weak_pointer_callback = false;
+/* Use std::deque here instead of std::vector so that elements don't have to
+ * get moved around when the storage size changes */
+static std::deque<GObject *> weak_pointer_list;
+
 extern struct JSClass gjs_object_instance_class;
 static GThread *gjs_eval_thread;
 static volatile gint pending_idle_toggles;
@@ -1121,10 +1127,9 @@ wrapped_gobj_toggle_notify(gpointer      data,
                            GObject      *gobj,
                            gboolean      is_last_ref)
 {
-    bool is_main_thread, is_sweeping;
+    bool is_main_thread;
     bool toggle_up_queued, toggle_down_queued;
     GjsContext *context;
-    JSContext *js_context;
 
     context = gjs_context_get_current();
     if (_gjs_context_destroying(context)) {
@@ -1167,12 +1172,6 @@ wrapped_gobj_toggle_notify(gpointer      data,
      * not a big deal.
      */
     is_main_thread = (gjs_eval_thread == g_thread_self());
-    if (is_main_thread) {
-        js_context = (JSContext*) gjs_context_get_native_context(context);
-        is_sweeping = gjs_runtime_is_sweeping(JS_GetRuntime(js_context));
-    } else {
-        is_sweeping = false;
-    }
 
     toggle_up_queued = toggle_idle_source_is_queued(gobj, TOGGLE_UP);
     toggle_down_queued = toggle_idle_source_is_queued(gobj, TOGGLE_DOWN);
@@ -1205,16 +1204,7 @@ wrapped_gobj_toggle_notify(gpointer      data,
                 g_error("toggling up object %s that's already queued to toggle up\n",
                         G_OBJECT_TYPE_NAME(gobj));
             }
-            if (is_sweeping) {
-                if (JS_IsAboutToBeFinalized(ensure_heap_wrapper(gobj))) {
-                    /* Ouch, the JS object is dead already. Disassociate the GObject
-                     * and hope the GObject dies too.
-                     */
-                    disassociate_js_gobject(gobj);
-                }
-            } else {
-                handle_toggle_up(gobj);
-            }
+            handle_toggle_up(gobj);
         } else {
             queue_toggle_idle(gobj, TOGGLE_UP);
         }
@@ -1297,6 +1287,34 @@ init_object_private (JSContext       *context,
 }
 
 static void
+update_heap_wrapper_weak_pointers(JSRuntime *rt,
+                                  gpointer   data)
+{
+    for (auto iter = weak_pointer_list.begin(); iter != weak_pointer_list.end();
+         iter++) {
+        GObject *gobj = *iter;
+        auto heap_wrapper = ensure_heap_wrapper(gobj);
+        JS_UpdateWeakPointerAfterGC(heap_wrapper);
+
+        if (heap_wrapper == NULL) {
+            /* Ouch, the JS object is dead already. Disassociate the GObject
+             * and hope the GObject dies too.
+             */
+            disassociate_js_gobject(gobj);
+            iter = weak_pointer_list.erase(iter);
+        }
+    }
+}
+
+static void
+ensure_weak_pointer_callback(JSContext *cx)
+{
+    if (!weak_pointer_callback)
+        JS_AddWeakPointerCallback(JS_GetRuntime(cx),
+                                  update_heap_wrapper_weak_pointers, NULL);
+}
+
+static void
 associate_js_gobject (JSContext       *context,
                       JS::HandleObject object,
                       GObject         *gobj)
@@ -1306,6 +1324,8 @@ associate_js_gobject (JSContext       *context,
     priv = priv_from_js(context, object);
     priv->gobj = gobj;
 
+    ensure_weak_pointer_callback(context);
+
     g_assert(peek_js_obj(gobj) == NULL);
     set_js_obj(gobj, object);
 
@@ -2146,7 +2166,7 @@ static void
 set_js_obj(GObject  *gobj,
            JSObject *obj)
 {
-    ensure_heap_wrapper(gobj)->set(obj);
+    *ensure_heap_wrapper(gobj) = obj;
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]