summaryrefslogtreecommitdiff
path: root/gjs
diff options
context:
space:
mode:
authorChristian Hergert <chergert@redhat.com>2019-06-03 14:09:44 -0700
committerChristian Hergert <chergert@redhat.com>2019-06-06 17:29:21 -0700
commitc5ae557f0c67cb69ad300ca74d9274e7ed924aa7 (patch)
treec0abc3bc9a52bc7551353dbdf5e448e657975fe2 /gjs
parent2abc180fefbeb877829aefe9a6e38bec04cab0e0 (diff)
downloadgjs-c5ae557f0c67cb69ad300ca74d9274e7ed924aa7.tar.gz
profiler: record duration of GC sweeps
Now that we are using sysprof-capture-3, we can record marks from the various subsystems in GJS. This adds marks to the capture when we perform a GC sweep operation. Related to GNOME/Initiatives#10
Diffstat (limited to 'gjs')
-rw-r--r--gjs/context-private.h5
-rw-r--r--gjs/context.cpp20
-rw-r--r--gjs/profiler-private.h4
-rw-r--r--gjs/profiler.cpp15
4 files changed, 43 insertions, 1 deletions
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 10dcf688..274352fa 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -117,6 +117,8 @@ class GjsContextPrivate {
bool m_should_profile : 1;
bool m_should_listen_sigusr2 : 1;
+ int64_t m_sweep_begin_time;
+
void schedule_gc_internal(bool force_gc);
static gboolean trigger_gc_if_needed(void* data);
static gboolean drain_job_queue_idle_handler(void* data);
@@ -148,7 +150,6 @@ class GjsContextPrivate {
GJS_USE const GjsAtoms& atoms(void) const { return m_atoms; }
GJS_USE bool destroying(void) const { return m_destroying; }
GJS_USE bool sweeping(void) const { return m_in_gc_sweep; }
- void set_sweeping(bool value) { m_in_gc_sweep = value; }
GJS_USE const char* program_name(void) const { return m_program_name; }
void set_program_name(char* value) { m_program_name = value; }
void set_search_path(char** value) { m_search_path = value; }
@@ -194,6 +195,8 @@ class GjsContextPrivate {
void register_unhandled_promise_rejection(uint64_t id, GjsAutoChar&& stack);
void unregister_unhandled_promise_rejection(uint64_t id);
+ void set_sweeping(bool value);
+
static void trace(JSTracer* trc, void* data);
void free_profiler(void);
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 0ac7fb68..6e2d54af 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -609,6 +609,26 @@ void GjsContextPrivate::schedule_gc_if_needed(void) {
schedule_gc_internal(false);
}
+void GjsContextPrivate::set_sweeping(bool value) {
+ // If we have a profiler enabled, record the duration of GC sweep
+ if (this->m_profiler != nullptr) {
+ int64_t now = g_get_monotonic_time() * 1000L;
+
+ if (value) {
+ m_sweep_begin_time = now;
+ } else {
+ if (m_sweep_begin_time != 0) {
+ _gjs_profiler_add_mark(this->m_profiler, m_sweep_begin_time,
+ now - m_sweep_begin_time, "GJS", "Sweep",
+ nullptr);
+ m_sweep_begin_time = 0;
+ }
+ }
+ }
+
+ m_in_gc_sweep = value;
+}
+
void GjsContextPrivate::exit(uint8_t exit_code) {
g_assert(!m_should_exit);
m_should_exit = true;
diff --git a/gjs/profiler-private.h b/gjs/profiler-private.h
index 20cb9f46..0697be25 100644
--- a/gjs/profiler-private.h
+++ b/gjs/profiler-private.h
@@ -33,6 +33,10 @@ G_BEGIN_DECLS
GjsProfiler *_gjs_profiler_new(GjsContext *context);
void _gjs_profiler_free(GjsProfiler *self);
+void _gjs_profiler_add_mark(GjsProfiler* self, gint64 time, gint64 duration,
+ const char* group, const char* name,
+ const char* message);
+
GJS_USE
bool _gjs_profiler_is_running(GjsProfiler *self);
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index b332b859..3f35aabb 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -639,3 +639,18 @@ gjs_profiler_set_filename(GjsProfiler *self,
g_free(self->filename);
self->filename = g_strdup(filename);
}
+
+void _gjs_profiler_add_mark(GjsProfiler* self, gint64 time_nsec,
+ gint64 duration_nsec, const char* group,
+ const char* name, const char* message) {
+ g_return_if_fail(self);
+ g_return_if_fail(group);
+ g_return_if_fail(name);
+
+#ifdef ENABLE_PROFILER
+ if (self->running && self->capture != nullptr) {
+ sysprof_capture_writer_add_mark(self->capture, time_nsec, -1, self->pid,
+ duration_nsec, group, name, message);
+ }
+#endif
+}