[gjs/wip/ptomato/mozjs38: 8/27] object: Trace vfunc trampolines



commit 66ae7e87f03c6f6bf8db1f2dfdfcae1ba557949d
Author: Philip Chimento <philip endlessm com>
Date:   Mon Feb 6 17:35:35 2017 -0800

    object: Trace vfunc trampolines
    
    Previously these trampolines were leaked, and the JS functions they
    pointed to were treated as weak pointers. We still have to leak the
    trampoline structs themselves, because the GType's vtable still refers to
    them.
    
    However, we can tie the JS functions to the lifetime of the prototype
    and trace them during garbage collection, which will become required in
    SpiderMonkey 38 when they can be moved around during GC.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=776966

 gi/object.cpp         |   14 ++++++++++++++
 gjs/jsapi-util-root.h |   11 +++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 33f9891..b9826c8 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -23,6 +23,7 @@
 
 #include <config.h>
 
+#include <deque>
 #include <memory>
 #include <set>
 #include <stack>
@@ -65,6 +66,9 @@ struct ObjectInstance {
        prototypes) */
     GTypeClass *klass;
 
+    /* A list of all vfunc trampolines, used when tracing */
+    std::deque<GjsCallbackTrampoline *> vfuncs;
+
     unsigned js_object_finalized : 1;
 };
 
@@ -1524,6 +1528,9 @@ object_instance_trace(JSTracer *tracer,
 
         gjs_closure_trace(cd->closure, tracer);
     }
+
+    for (auto vfunc : priv->vfuncs)
+        vfunc->js_function.trace(tracer, "ObjectInstance::vfunc");
 }
 
 static void
@@ -1569,6 +1576,12 @@ object_instance_finalize(JSFreeOp  *fop,
         release_native_object(priv);
     }
 
+    /* We have to leak the trampolines, since the GType's vtable still refers
+     * to them */
+    for (auto iter : priv->vfuncs)
+        iter->js_function.reset();
+    priv->vfuncs.clear();
+
     if (priv->keep_alive.rooted()) {
         /* This happens when the refcount on the object is still >1,
          * for example with global objects GDK never frees like GdkDisplay,
@@ -2439,6 +2452,7 @@ gjs_hook_up_vfunc(JSContext *cx,
                                                  GI_SCOPE_TYPE_NOTIFIED, true);
 
         *((ffi_closure **)method_ptr) = trampoline->closure;
+        priv->vfuncs.push_back(trampoline);
 
         g_base_info_unref(interface_info);
         g_base_info_unref(type_info);
diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h
index 65551dd..01cc478 100644
--- a/gjs/jsapi-util-root.h
+++ b/gjs/jsapi-util-root.h
@@ -90,6 +90,17 @@ struct GjsHeapOperation<JSObject *> {
     }
 };
 
+template<>
+struct GjsHeapOperation<JS::Value> {
+    static void
+    trace(JSTracer            *tracer,
+          JS::Heap<JS::Value> *thing,
+          const char          *name)
+    {
+        JS_CallHeapValueTracer(tracer, thing, name);
+    }
+};
+
 /* GjsMaybeOwned is intended only for use in heap allocation. Do not allocate it
  * on the stack, and do not allocate any instances of structures that have it as
  * a member on the stack either. Unfortunately we cannot enforce this at compile


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