Permalink
Browse files

profiler: add SPSProfiler implementation

Currently this is Linux only as it requires the Linux implementation of
POSIX signals.

There is a simple API, and the profile output is written to
/tmp/gjs-profile-<pid>. Description of the capture format is provided
in profile.cpp.

For apps started with gjs-console, you can toggle on/off profiling by
sending SIGUSR2 to the process.
  • Loading branch information...
1 parent 92f8406 commit 46eff4e2db7e83a61932d161f652aca0a377d9c9 @chergert committed Apr 13, 2016
Showing with 2,639 additions and 11 deletions.
  1. +19 −11 Makefile.am
  2. +2 −0 gjs/compat.h
  3. +15 −0 gjs/console.cpp
  4. +1 −0 gjs/gjs-module.h
  5. +2 −0 gjs/jsapi-private.cpp
  6. +556 −0 gjs/profiler.cpp
  7. +44 −0 gjs/profiler.h
  8. +32 −0 test/gjs-tests.cpp
  9. +686 −0 util/sp-capture-reader.c
  10. +65 −0 util/sp-capture-reader.h
  11. +155 −0 util/sp-capture-types.h
  12. +954 −0 util/sp-capture-writer.c
  13. +108 −0 util/sp-capture-writer.h
View
@@ -37,6 +37,7 @@ nobase_gjs_module_include_HEADERS = \
gjs/byteArray.h \
gjs/importer.h \
gjs/jsapi-util.h \
+ gjs/profiler.h \
gjs/runtime.h \
gjs/type-module.h \
gjs/mem.h \
@@ -59,16 +60,19 @@ nobase_gjs_module_include_HEADERS = \
gi/gtype.h \
gi/gerror.h
-noinst_HEADERS += \
- gjs/jsapi-private.h \
- gjs/context-private.h \
- gi/proxyutils.h \
- util/crash.h \
- util/hash-x32.h \
- util/error.h \
- util/glib.h \
- util/log.h \
- util/misc.h
+noinst_HEADERS += \
+ gjs/jsapi-private.h \
+ gjs/context-private.h \
+ gi/proxyutils.h \
+ util/crash.h \
+ util/hash-x32.h \
+ util/error.h \
+ util/glib.h \
+ util/log.h \
+ util/misc.h \
+ util/sp-capture-reader.h \
+ util/sp-capture-types.h \
+ util/sp-capture-writer.h
########################################################################
pkgconfigdir = $(libdir)/pkgconfig
@@ -93,6 +97,7 @@ libgjs_la_CPPFLAGS = \
$(GJS_CFLAGS) \
$(gjs_directory_defines)\
-I$(top_srcdir)/gi \
+ -I$(top_srcdir)/util \
-DGJS_COMPILATION
libgjs_la_LDFLAGS = \
$(EXTRA_LINK_FLAGS) \
@@ -123,6 +128,7 @@ libgjs_la_SOURCES = \
gjs/jsapi-util-string.cpp \
gjs/mem.cpp \
gjs/native.cpp \
+ gjs/profiler.cpp \
gjs/runtime.cpp \
gjs/stack.cpp \
gjs/type-module.cpp \
@@ -133,7 +139,9 @@ libgjs_la_SOURCES = \
util/glib.cpp \
util/crash.cpp \
util/log.cpp \
- util/misc.cpp
+ util/misc.cpp \
+ util/sp-capture-reader.c \
+ util/sp-capture-writer.c
# For historical reasons, some files live in gi/
libgjs_la_SOURCES += \
View
@@ -31,7 +31,9 @@
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
_Pragma("GCC diagnostic push")
+#ifndef __cplusplus
_Pragma("GCC diagnostic ignored \"-Wstrict-prototypes\"")
+#endif
_Pragma("GCC diagnostic ignored \"-Winvalid-offsetof\"")
#endif
#include <jsapi.h>
View
@@ -28,10 +28,12 @@
#include <gjs/gjs.h>
#include <gjs/coverage.h>
+#include <gjs/profiler.h>
static char **include_path = NULL;
static char **coverage_prefixes = NULL;
static char *coverage_output_path = NULL;
+static char *profile_output_path = NULL;
static char *command = NULL;
static const char *GJS_COVERAGE_CACHE_FILE_NAME = ".internal-gjs-coverage-cache";
@@ -41,6 +43,7 @@ static GOptionEntry entries[] = {
{ "coverage-prefix", 'C', 0, G_OPTION_ARG_STRING_ARRAY, &coverage_prefixes, "Add the prefix PREFIX to the list of files to generate coverage info for", "PREFIX" },
{ "coverage-output", 0, 0, G_OPTION_ARG_STRING, &coverage_output_path, "Write coverage output to a directory DIR. This option is mandatory when using --coverage-path", "DIR", },
{ "include-path", 'I', 0, G_OPTION_ARG_STRING_ARRAY, &include_path, "Add the directory DIR to the list of directories to search for js files.", "DIR" },
+ { "profile-output", 0, 0, G_OPTION_ARG_FILENAME, &profile_output_path, "Enable the profiler and Write output to FILE", "FILE" },
{ NULL }
};
@@ -65,6 +68,7 @@ main(int argc, char **argv)
GError *error = NULL;
GjsContext *js_context;
GjsCoverage *coverage = NULL;
+ GjsProfiler *profiler;
char *script;
const char *filename;
const char *program_name;
@@ -132,6 +136,16 @@ main(int argc, char **argv)
g_free(path_to_cache_file);
}
+ profiler = gjs_profiler_new(js_context);
+
+ /* Allow SIGUSR2 (with sigaction param) to enable/disable */
+ gjs_profiler_setup_signals();
+
+ if (profile_output_path) {
+ gjs_profiler_set_filename(profiler, profile_output_path);
+ gjs_profiler_start(profiler);
+ }
+
/* prepare command line arguments */
if (!gjs_context_define_string_array(js_context, "ARGV",
argc - 1, (const char**)argv + 1,
@@ -158,6 +172,7 @@ main(int argc, char **argv)
gjs_coverage_write_statistics(coverage,
coverage_output_path);
+ gjs_profiler_free(profiler);
g_object_unref(js_context);
g_free(script);
exit(code);
View
@@ -28,6 +28,7 @@
#include <gjs/native.h>
#include <gjs/mem.h>
#include <gjs/importer.h>
+#include <gjs/profiler.h>
#include <gjs/runtime.h>
#include <gjs/jsapi-util.h>
View
@@ -33,7 +33,9 @@
#include <string.h>
#pragma GCC diagnostic push
+#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#endif
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#include <jsfriendapi.h>
#pragma GCC diagnostic pop
Oops, something went wrong.

0 comments on commit 46eff4e

Please sign in to comment.