From aa03734d39bff436aafe09a9c869ae5ecb96f96a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 20 May 2011 15:50:54 -0400 Subject: [PATCH] Add "Memory" tab to lg shell_global_get_memory_info() is a new function which extracts a few global counters we have already, namely glibc's mallinfo, spidermonkey's JSGC_BYTES, and gjs' counters for boxed/object/etc wrappers. There is some slight overlap with perf; ultimately though I'd like this function to do some more extensive analysis, so it wouldn't be quite the same. perf is going to be mainly concerned with how big the whole process over time is; memory_info is for debugging memory leaks. https://bugzilla.gnome.org/show_bug.cgi?id=650692 --- js/ui/lookingGlass.js | 50 +++++++++++++++++++++++++++++++++++++++++++ src/shell-global.c | 37 ++++++++++++++++++++++++++++++++ src/shell-global.h | 15 +++++++++++++ 3 files changed, 102 insertions(+) diff --git a/js/ui/lookingGlass.js b/js/ui/lookingGlass.js index db3291f87..d7d50def9 100644 --- a/js/ui/lookingGlass.js +++ b/js/ui/lookingGlass.js @@ -582,6 +582,53 @@ ErrorLog.prototype = { } }; +function Memory() { + this._init(); +} + +Memory.prototype = { + _init: function() { + this.actor = new St.BoxLayout({ vertical: true }); + this._glibc_uordblks = new St.Label(); + this.actor.add(this._glibc_uordblks); + + this._js_bytes = new St.Label(); + this.actor.add(this._js_bytes); + + this._gjs_boxed = new St.Label(); + this.actor.add(this._gjs_boxed); + + this._gjs_gobject = new St.Label(); + this.actor.add(this._gjs_gobject); + + this._gjs_function = new St.Label(); + this.actor.add(this._gjs_function); + + this._gjs_closure = new St.Label(); + this.actor.add(this._gjs_closure); + + this._gcbutton = new St.Button({ label: 'Full GC', + style_class: 'lg-obj-inspector-button' }); + this._gcbutton.connect('clicked', Lang.bind(this, function () { global.gc(); this._renderText(); })); + this.actor.add(this._gcbutton, { x_align: St.Align.START, + x_fill: false }); + + this.actor.connect('notify::mapped', Lang.bind(this, this._renderText)); + }, + + _renderText: function() { + if (!this.actor.mapped) + return; + let memInfo = global.get_memory_info(); + this._glibc_uordblks.text = 'glibc_uordblks: ' + memInfo.glibc_uordblks; + this._js_bytes.text = 'js bytes: ' + memInfo.js_bytes; + this._gjs_boxed.text = 'gjs_boxed: ' + memInfo.gjs_boxed; + this._gjs_gobject.text = 'gjs_gobject: ' + memInfo.gjs_gobject; + this._gjs_function.text = 'gjs_function: ' + memInfo.gjs_function; + this._gjs_closure.text = 'gjs_closure: ' + memInfo.gjs_closure; + } +}; + function Extensions() { this._init(); } @@ -764,6 +811,9 @@ LookingGlass.prototype = { this._errorLog = new ErrorLog(); notebook.appendPage('Errors', this._errorLog.actor); + this._memory = new Memory(); + notebook.appendPage('Memory', this._memory.actor); + this._extensions = new Extensions(); notebook.appendPage('Extensions', this._extensions.actor); diff --git a/src/shell-global.c b/src/shell-global.c index e18dbc998..84b35db75 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -25,6 +25,11 @@ #include #include +/* Memory report bits */ +#ifdef HAVE_MALLINFO +#include +#endif + #include "shell-enum-types.h" #include "shell-global-private.h" #include "shell-jsapi-compat-private.h" @@ -1126,6 +1131,38 @@ shell_global_maybe_gc (ShellGlobal *global) gjs_context_maybe_gc (global->js_context); } +/** + * shell_global_get_memory_info: + * @global: + * @meminfo: (out caller-allocates): Output location for memory information + * + * Load process-global data about memory usage. + */ +void +shell_global_get_memory_info (ShellGlobal *global, + ShellMemoryInfo *meminfo) +{ + JSContext *context; + + memset (meminfo, 0, sizeof (meminfo)); +#ifdef HAVE_MALLINFO + { + struct mallinfo info = mallinfo (); + meminfo->glibc_uordblks = info.uordblks; + } +#endif + + context = gjs_context_get_native_context (global->js_context); + + meminfo->js_bytes = JS_GetGCParameter (JS_GetRuntime (context), JSGC_BYTES); + + meminfo->gjs_boxed = (unsigned int) gjs_counter_boxed.value; + meminfo->gjs_gobject = (unsigned int) gjs_counter_object.value; + meminfo->gjs_function = (unsigned int) gjs_counter_function.value; + meminfo->gjs_closure = (unsigned int) gjs_counter_closure.value; +} + + /** * shell_global_notify_error: * @global: a #ShellGlobal diff --git a/src/shell-global.h b/src/shell-global.h index c9d4f7c6f..d6f4c33a7 100644 --- a/src/shell-global.h +++ b/src/shell-global.h @@ -90,6 +90,21 @@ void shell_global_get_pointer (ShellGlobal *global, void shell_global_gc (ShellGlobal *global); void shell_global_maybe_gc (ShellGlobal *global); +typedef struct { + guint glibc_uordblks; + + guint js_bytes; + + guint gjs_boxed; + guint gjs_gobject; + guint gjs_function; + guint gjs_closure; +} ShellMemoryInfo; + +void shell_global_get_memory_info (ShellGlobal *global, + ShellMemoryInfo *meminfo); + + gboolean shell_global_set_property_mutable (ShellGlobal *global, const char *object, const char *property,