[gjs: 5/7] object: Add debug methods



commit ae59d9cec04ad6695728b315bd2d97de7ff15ce8
Author: Philip Chimento <philip chimento gmail com>
Date:   Thu Jun 7 00:53:22 2018 -0700

    object: Add debug methods
    
    Many methods of ObjectInstance log a debug message with all the same
    information, such as the address of the GObject, the JSObject, the
    ObjectInstance, and type info. Make this uniform (and shorter) by adding
    debug methods to ObjectInstance.

 gi/object.cpp    | 108 ++++++++++++++++++++++++-------------------------------
 gjs/jsapi-util.h |   2 +-
 2 files changed, 48 insertions(+), 62 deletions(-)
---
diff --git a/gi/object.cpp b/gi/object.cpp
index 5cd00e07..0ae7ed06 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -206,6 +206,29 @@ class ObjectInstance {
                   for_what, ns(), name());
         return false;
     }
+    void debug_lifecycle(const char *message) const {
+        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT,
+                            "[%p: GObject %p JS wrapper %p %s.%s (%s)] %s",
+                            this, m_gobj, m_wrapper.get(), ns(), name(),
+                            type_name(), message);
+    }
+    void debug_jsprop_base(const char *message, const char *id, JSObject *obj) const {
+        gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
+                         "[%p: GObject %p JS object %p %s.%s (%s)] %s '%s'",
+                         this, m_gobj, obj, ns(), name(), type_name(),
+                         message, id);
+    }
+    void debug_jsprop(const char *message, jsid id, JSObject *obj) const {
+        debug_jsprop_base(message, gjs_debug_id(id).c_str(), obj);
+    }
+    void debug_jsprop(const char *message, JSString *id, JSObject *obj) const {
+        debug_jsprop_base(message, gjs_debug_string(id).c_str(), obj);
+    }
+    static void debug_jsprop_static(const char *message, jsid id, JSObject *obj) {
+        gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
+                         "[JS object %p] %s '%s', no instance associated",
+                         obj, message, gjs_debug_id(id).c_str());
+    }
 
     /* Instance-only helper methods */
 
@@ -589,25 +612,21 @@ ObjectInstance::add_property(JSContext       *cx,
 
     /* priv is null during init: property is not being added from JS */
     if (!priv) {
-        gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Add prop '%s' hook, obj %s, "
-                         "no instance associated", gjs_debug_id(id).c_str(),
-                         gjs_debug_object(obj).c_str());
+        debug_jsprop_static("Add property hook", id, obj);
         return true;
     }
 
     return priv->add_property_impl(cx, obj, id, value);
 }
 
+
 bool
 ObjectInstance::add_property_impl(JSContext       *cx,
                                   JS::HandleObject obj,
                                   JS::HandleId     id,
                                   JS::HandleValue  value)
 {
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
-                     "Add prop '%s' hook, obj %s, priv %p, gobj %p %s",
-                     gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(),
-                     this, m_gobj, type_name());
+    debug_jsprop("Add property hook", id, obj);
 
     if (is_prototype() || is_custom_js_class() || m_gobj_disposed)
         return true;
@@ -626,9 +645,7 @@ ObjectInstance::prop_getter(JSContext *cx,
     JS::RootedString name(cx,
         gjs_dynamic_property_private_slot(&args.callee()).toString());
 
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Property getter '%s', obj %p priv %p",
-                     gjs_debug_string(name).c_str(),
-                     gjs_debug_object(obj).c_str(), priv);
+    priv->debug_jsprop("Property getter", name, obj);
 
     if (priv->is_prototype())
         return true;
@@ -741,9 +758,7 @@ ObjectInstance::field_getter(JSContext *cx,
     JS::RootedString name(cx,
         gjs_dynamic_property_private_slot(&args.callee()).toString());
 
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Field getter '%s', obj %p priv %p",
-                     gjs_debug_string(name).c_str(),
-                     gjs_debug_object(obj).c_str(), priv);
+    priv->debug_jsprop("Field getter", name, obj);
 
     if (priv->is_prototype())
         return true;
@@ -819,9 +834,7 @@ ObjectInstance::prop_setter(JSContext *cx,
     JS::RootedString name(cx,
         gjs_dynamic_property_private_slot(&args.callee()).toString());
 
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Property setter '%s', obj %p priv %p",
-                     gjs_debug_string(name).c_str(),
-                     gjs_debug_object(obj).c_str(), priv);
+    priv->debug_jsprop("Property setter", name, obj);
 
     if (priv->is_prototype())
         return true;
@@ -883,9 +896,7 @@ ObjectInstance::field_setter(JSContext *cx,
     JS::RootedString name(cx,
         gjs_dynamic_property_private_slot(&args.callee()).toString());
 
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Field setter '%s', obj %p priv %p",
-                     gjs_debug_string(name).c_str(),
-                     gjs_debug_object(obj).c_str(), priv);
+    priv->debug_jsprop("Field setter", name, obj);
 
     if (priv->is_prototype())
         return true;
@@ -1121,9 +1132,7 @@ ObjectInstance::resolve(JSContext       *cx,
          * will run afterwards will fail because of the "priv == NULL"
          * check there.
          */
-        gjs_debug_jsprop(GJS_DEBUG_GOBJECT, "Resolve prop '%s' hook, obj %s, "
-                         "no instance associated", gjs_debug_id(id).c_str(),
-                         gjs_debug_object(obj).c_str());
+        debug_jsprop_static("Resolve hook", id, obj);
         *resolved = false;
         return true;
     }
@@ -1137,11 +1146,7 @@ ObjectInstance::resolve_impl(JSContext       *context,
                              JS::HandleId     id,
                              bool            *resolved)
 {
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
-                 "Resolve prop '%s' hook, obj %s, priv %p (%s.%s), gobj %p %s",
-                 gjs_debug_id(id).c_str(),
-                 gjs_debug_object(obj).c_str(),
-                 this, ns(), name(), m_gobj, type_name());
+    debug_jsprop("Resolve hook", id, obj);
 
     if (!is_prototype()) {
         *resolved = false;
@@ -1214,9 +1219,7 @@ ObjectInstance::resolve_impl(JSContext       *context,
             return true;
         }
 
-        gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
-                         "Defining lazy GObject property '%s' in prototype of %s",
-                         gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str());
+        debug_jsprop("Defining lazy GObject property", id, obj);
 
         JS::RootedValue private_id(context, JS::StringValue(JSID_TO_STRING(id)));
         if (!gjs_define_property_dynamic(context, proto, name, "gobject_prop",
@@ -1242,9 +1245,7 @@ ObjectInstance::resolve_impl(JSContext       *context,
             return true;
         }
 
-        gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
-                         "Defining lazy GObject field '%s' in prototype of %s",
-                         gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str());
+        debug_jsprop("Defining lazy GObject field", id, obj);
 
         unsigned flags = GJS_MODULE_PROP_FLAGS;
         if (!(g_field_info_get_flags(field_info) & GI_FIELD_IS_WRITABLE))
@@ -1290,8 +1291,7 @@ ObjectInstance::resolve_impl(JSContext       *context,
     if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) {
         gjs_debug(GJS_DEBUG_GOBJECT,
                   "Defining method %s in prototype for %s (%s.%s)",
-                  g_base_info_get_name( (GIBaseInfo*) method_info),
-                  type_name(), ns(), this->name());
+                  method_info.name(), type_name(), ns(), this->name());
 
         if (!gjs_define_function(context, obj, m_gtype, method_info))
             return false;
@@ -1428,10 +1428,7 @@ void
 ObjectInstance::context_dispose_notify(void)
 {
     if (wrapper_is_rooted()) {
-        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "GObject wrapper %p for GObject "
-                            "%p (%s) was rooted but is now unrooted due to "
-                            "GjsContext dispose", m_wrapper.get(),
-                            m_gobj, type_name());
+        debug_lifecycle("Was rooted, but unrooting due to GjsContext dispose");
         discard_wrapper();
         unlink();
     }
@@ -1440,9 +1437,7 @@ ObjectInstance::context_dispose_notify(void)
 void
 ObjectInstance::toggle_down(void)
 {
-    gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Toggle notify DOWN for GObject "
-                        "%p (%s), JS obj %p", m_gobj, type_name(),
-                        m_wrapper.get());
+    debug_lifecycle("Toggle notify DOWN");
 
     /* Change to weak ref so the wrapper-wrappee pair can be
      * collected by the GC
@@ -1450,7 +1445,7 @@ ObjectInstance::toggle_down(void)
     if (wrapper_is_rooted()) {
         GjsContext *context;
 
-        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Unrooting object");
+        debug_lifecycle("Unrooting wrapper");
         switch_to_unrooted();
 
         /* During a GC, the collector asks each object which other
@@ -1485,9 +1480,7 @@ ObjectInstance::toggle_up(void)
     if (!has_wrapper()) /* Object already GC'd */
         return;
 
-    gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Toggle notify UP for GObject "
-                        "%p (%s), JS obj %p", m_gobj, type_name(),
-                        m_wrapper.get());
+    debug_lifecycle("Toggle notify UP");
 
     /* Change to strong ref so the wrappee keeps the wrapper alive
      * in case the wrapper has data in it that the app cares about
@@ -1496,7 +1489,7 @@ ObjectInstance::toggle_up(void)
         /* FIXME: thread the context through somehow. Maybe by looking up
          * the compartment that obj belongs to. */
         GjsContext *context = gjs_context_get_current();
-        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Rooting object");
+        debug_lifecycle("Rooting wrapper");
         auto cx = static_cast<JSContext *>(gjs_context_get_native_context(context));
         switch_to_rooted(cx);
     }
@@ -1672,8 +1665,7 @@ ObjectInstance::ObjectInstance(JSContext       *cx,
     if (m_info)
         g_base_info_ref(m_info);
 
-    gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Instance constructor of %s, "
-                        "JS obj %p, priv %p", type_name(), object.get(), this);
+    debug_lifecycle("Instance constructor");
 }
 
 ObjectInstance::ObjectInstance(JSObject     *prototype,
@@ -1722,9 +1714,8 @@ ObjectInstance::weak_pointer_was_finalized(void)
          * the weak pointer list first, since the disassociation
          * may also cause it to be erased.)
          */
-        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Found GObject weak pointer "
-                            "whose JS object %p is about to be finalized: "
-                            "%p (%s)", m_wrapper.get(), m_gobj, type_name());
+        debug_lifecycle("Found GObject weak pointer whose JS wrapper is about "
+                        "to be finalized");
         return true;
     }
     return false;
@@ -1765,9 +1756,7 @@ ObjectInstance::ensure_uses_toggle_ref(JSContext *cx)
     if (m_uses_toggle_ref)
         return;
 
-    gjs_debug_jsprop(GJS_DEBUG_GOBJECT,
-                     "Switching object instance %p, gobj %p %s to toggle ref",
-                     this, m_gobj, type_name());
+    debug_lifecycle("Switching object instance to toggle ref");
 
     g_assert(!wrapper_is_rooted());
 
@@ -1900,8 +1889,7 @@ ObjectInstance::init_impl(JSContext              *context,
     if (!m_gobj)
         associate_js_gobject(context, object, gobj);
 
-    gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "JSObject created with GObject %p (%s)",
-                        m_gobj, type_name());
+    debug_lifecycle("JSObject created");
 
     TRACE(GJS_OBJECT_PROXY_NEW(this, m_gobj, ns(), name()));
 
@@ -1977,9 +1965,7 @@ void
 ObjectInstance::finalize_impl(JSFreeOp  *fop,
                               JSObject  *obj)
 {
-    gjs_debug_lifecycle(GJS_DEBUG_GOBJECT,
-                        "Finalizing %s, JS obj %p, priv %p, GObject %p",
-                        type_name(), obj, this, m_gobj);
+    debug_lifecycle("Finalize");
 
     TRACE(GJS_OBJECT_PROXY_FINALIZE(priv, m_gobj, ns(), name()));
 
@@ -2032,7 +2018,7 @@ ObjectInstance::finalize_impl(JSFreeOp  *fop,
         gjs_debug(GJS_DEBUG_GOBJECT,
                   "Wrapper was finalized despite being kept alive, has refcount >1");
 
-        gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Unrooting object");
+        debug_lifecycle("Unrooting object");
 
         discard_wrapper();
     }
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 7bb3e5a6..e009f127 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -73,7 +73,7 @@ public:
 
     operator T *() { return GjsAutoInfo::unique_ptr::get(); }
 
-    const char *name(void) { return g_base_info_get_name(this); }
+    const char *name(void) { return g_base_info_get_name(*this); }
 };
 
 /* For use of GjsAutoInfo<T> in GC hash maps */


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