diff options
Diffstat (limited to 'gjs/signal_gc.patch')
-rw-r--r-- | gjs/signal_gc.patch | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/gjs/signal_gc.patch b/gjs/signal_gc.patch new file mode 100644 index 0000000..809d0e1 --- /dev/null +++ b/gjs/signal_gc.patch @@ -0,0 +1,162 @@ +From 20cfbeb9744a8d44b8e9dcce23d0c8e0f26842a1 Mon Sep 17 00:00:00 2001 +From: Colin Walters <walters@verbum.org> +Date: Thu, 15 Sep 2011 23:33:23 +0000 +Subject: context: Add optional signal emitted after a GC finishes + +Embedders may want to perform garbage collection profiling; support +this with an optional signal emitted after a collection finishes. + +I added a boolean to avoid calling JS_SetGCCallback() if not used, +because there's no way for that API to chain. + +https://bugzilla.gnome.org/show_bug.cgi?id=659253 +--- +diff --git a/gjs/context.c b/gjs/context.c +index d931a3b..5688477 100644 +--- a/gjs/context.c ++++ b/gjs/context.c +@@ -56,6 +56,8 @@ static void gjs_context_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); ++static JSBool gjs_on_context_gc (JSContext *cx, ++ JSGCStatus status); + + struct _GjsContext { + GObject parent; +@@ -70,7 +72,10 @@ struct _GjsContext { + + char **search_path; + +- unsigned int we_own_runtime : 1; ++ guint idle_emit_gc_id; ++ ++ guint we_own_runtime : 1; ++ guint gc_notifications_enabled : 1; + }; + + struct _GjsContextClass { +@@ -79,19 +84,19 @@ struct _GjsContextClass { + + G_DEFINE_TYPE(GjsContext, gjs_context, G_TYPE_OBJECT); + +-#if 0 + enum { ++ SIGNAL_GC, + LAST_SIGNAL + }; + + static int signals[LAST_SIGNAL]; +-#endif + + enum { + PROP_0, + PROP_JS_VERSION, + PROP_SEARCH_PATH, +- PROP_RUNTIME ++ PROP_RUNTIME, ++ PROP_GC_NOTIFICATIONS + }; + + +@@ -335,6 +340,22 @@ gjs_context_class_init(GjsContextClass *klass) + PROP_JS_VERSION, + pspec); + ++ pspec = g_param_spec_boolean("gc-notifications", ++ "", ++ "Whether or not to emit the \"gc\" signal", ++ FALSE, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); ++ ++ g_object_class_install_property(object_class, ++ PROP_GC_NOTIFICATIONS, ++ pspec); ++ ++ signals[SIGNAL_GC] = g_signal_new("gc", G_TYPE_FROM_CLASS(klass), ++ G_SIGNAL_RUN_LAST, 0, ++ NULL, NULL, ++ NULL, ++ G_TYPE_NONE, 0); ++ + gjs_register_native_module("byteArray", gjs_define_byte_array_stuff, 0); + } + +@@ -386,6 +407,11 @@ gjs_context_finalize(GObject *object) + + js_context = GJS_CONTEXT(object); + ++ if (js_context->idle_emit_gc_id > 0) { ++ g_source_remove (js_context->idle_emit_gc_id); ++ js_context->idle_emit_gc_id = 0; ++ } ++ + if (js_context->search_path != NULL) { + g_strfreev(js_context->search_path); + js_context->search_path = NULL; +@@ -674,6 +700,9 @@ gjs_context_constructor (GType type, + /* For GjsDBus */ + g_irepository_prepend_search_path(PKGLIBDIR); + ++ if (js_context->gc_notifications_enabled) ++ JS_SetGCCallback(js_context->context, gjs_on_context_gc); ++ + JS_EndRequest(js_context->context); + + g_static_mutex_lock (&contexts_lock); +@@ -697,6 +726,9 @@ gjs_context_get_property (GObject *object, + case PROP_JS_VERSION: + g_value_set_string(value, js_context->jsversion_string); + break; ++ case PROP_GC_NOTIFICATIONS: ++ g_value_set_boolean(value, js_context->gc_notifications_enabled); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -727,7 +759,9 @@ gjs_context_set_property (GObject *object, + else + js_context->jsversion_string = g_value_dup_string(value); + break; +- ++ case PROP_GC_NOTIFICATIONS: ++ js_context->gc_notifications_enabled = g_value_get_boolean(value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -865,6 +899,32 @@ gjs_context_maybe_gc (GjsContext *context) + gjs_maybe_gc(context->context); + } + ++static gboolean ++gjs_context_idle_emit_gc (gpointer data) ++{ ++ GjsContext *gjs_context = data; ++ ++ gjs_context->idle_emit_gc_id = 0; ++ ++ g_signal_emit (gjs_context, signals[SIGNAL_GC], 0); ++ ++ return FALSE; ++} ++ ++static JSBool ++gjs_on_context_gc (JSContext *cx, ++ JSGCStatus status) ++{ ++ GjsContext *gjs_context = JS_GetContextPrivate(cx); ++ ++ if (status == JSGC_END) { ++ if (gjs_context->idle_emit_gc_id == 0) ++ gjs_context->idle_emit_gc_id = g_idle_add (gjs_context_idle_emit_gc, gjs_context); ++ } ++ ++ return TRUE; ++} ++ + /** + * gjs_context_get_all: + * +-- +cgit v0.9.0.2 |