From c8328a837deb148c1b413f26a8ba8d75ce7833b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 28 Apr 2021 18:25:32 +0200 Subject: log: Optimize topics check avoiding repeated strings checks Avoid repeating the same string checks while debug logging. We can just save the enabled topics in a vector (if logging is enabled at all) and quickly check whether a topic is enabled. --- util/log.cpp | 171 +++++++++++++++++++++++++---------------------------------- util/log.h | 1 + 2 files changed, 74 insertions(+), 98 deletions(-) (limited to 'util') diff --git a/util/log.cpp b/util/log.cpp index 64730da6..93068a3b 100644 --- a/util/log.cpp +++ b/util/log.cpp @@ -22,6 +22,8 @@ # include // for getpid #endif +#include + #include #include "util/log.h" @@ -30,20 +32,70 @@ static std::atomic_bool s_initialized = ATOMIC_VAR_INIT(false); static bool s_debug_log_enabled = false; static bool s_print_thread = false; -static const char* s_topics = nullptr; static FILE* s_logfp = nullptr; -static GjsAutoStrv s_prefixes; static GjsAutoPointer s_timer; +static std::vector s_enabled_topics; + +static const char* topic_to_prefix(GjsDebugTopic topic) { + switch (topic) { + case GJS_DEBUG_GI_USAGE: + return "JS GI USE"; + case GJS_DEBUG_MEMORY: + return "JS MEMORY"; + case GJS_DEBUG_CONTEXT: + return "JS CTX"; + case GJS_DEBUG_IMPORTER: + return "JS IMPORT"; + case GJS_DEBUG_NATIVE: + return "JS NATIVE"; + case GJS_DEBUG_CAIRO: + return "JS CAIRO"; + case GJS_DEBUG_KEEP_ALIVE: + return "JS KP ALV"; + case GJS_DEBUG_GREPO: + return "JS G REPO"; + case GJS_DEBUG_GNAMESPACE: + return "JS G NS"; + case GJS_DEBUG_GOBJECT: + return "JS G OBJ"; + case GJS_DEBUG_GFUNCTION: + return "JS G FUNC"; + case GJS_DEBUG_GFUNDAMENTAL: + return "JS G FNDMTL"; + case GJS_DEBUG_GCLOSURE: + return "JS G CLSR"; + case GJS_DEBUG_GBOXED: + return "JS G BXD"; + case GJS_DEBUG_GENUM: + return "JS G ENUM"; + case GJS_DEBUG_GPARAM: + return "JS G PRM"; + case GJS_DEBUG_GERROR: + return "JS G ERR"; + case GJS_DEBUG_GINTERFACE: + return "JS G IFACE"; + case GJS_DEBUG_GTYPE: + return "JS GTYPE"; + default: + return "???"; + } +} + +static GjsDebugTopic prefix_to_topic(const char* prefix) { + for (unsigned i = 0; i < GJS_DEBUG_LAST; i++) { + auto topic = static_cast(i); + if (g_str_equal(topic_to_prefix(topic), prefix)) + return topic; + } + + return GJS_DEBUG_LAST; +} void gjs_log_init() { bool expected = false; if (!s_initialized.compare_exchange_strong(expected, true)) return; - s_topics = g_getenv("GJS_DEBUG_TOPICS"); - if (s_topics) - s_prefixes = g_strsplit(s_topics, ";", -1); - if (gjs_environment_variable_is_set("GJS_DEBUG_TIMESTAMP")) s_timer = g_timer_new(); @@ -89,6 +141,18 @@ void gjs_log_init() { if (!s_logfp) s_logfp = stderr; + + if (s_debug_log_enabled) { + auto* topics = g_getenv("GJS_DEBUG_TOPICS"); + s_enabled_topics = std::vector(GJS_DEBUG_LAST, topics == nullptr); + if (topics) { + GjsAutoStrv prefixes(g_strsplit(topics, ";", -1)); + for (unsigned i = 0; prefixes[i] != NULL; i++) { + GjsDebugTopic topic = prefix_to_topic(prefixes[i]); + s_enabled_topics[topic] = topic != GJS_DEBUG_LAST; + } + } + } } void gjs_log_cleanup() { @@ -102,29 +166,7 @@ void gjs_log_cleanup() { } s_timer = nullptr; - s_prefixes = nullptr; -} - -/* prefix is allowed if it's in the ;-delimited environment variable - * GJS_DEBUG_TOPICS or if that variable is not set. - */ -static bool -is_allowed_prefix (const char *prefix) -{ - bool found = false; - int i; - - if (!s_prefixes) - return true; - - for (i = 0; s_prefixes[i] != NULL; i++) { - if (!strcmp(s_prefixes[i], prefix)) { - found = true; - break; - } - } - - return found; + s_enabled_topics.clear(); } #define PREFIX_LENGTH 12 @@ -148,77 +190,10 @@ gjs_debug(GjsDebugTopic topic, const char *format, ...) { - const char *prefix; va_list args; char *s; - if (!s_debug_log_enabled) - return; - - switch (topic) { - case GJS_DEBUG_GI_USAGE: - prefix = "JS GI USE"; - break; - case GJS_DEBUG_MEMORY: - prefix = "JS MEMORY"; - break; - case GJS_DEBUG_CONTEXT: - prefix = "JS CTX"; - break; - case GJS_DEBUG_IMPORTER: - prefix = "JS IMPORT"; - break; - case GJS_DEBUG_NATIVE: - prefix = "JS NATIVE"; - break; - case GJS_DEBUG_CAIRO: - prefix = "JS CAIRO"; - break; - case GJS_DEBUG_KEEP_ALIVE: - prefix = "JS KP ALV"; - break; - case GJS_DEBUG_GREPO: - prefix = "JS G REPO"; - break; - case GJS_DEBUG_GNAMESPACE: - prefix = "JS G NS"; - break; - case GJS_DEBUG_GOBJECT: - prefix = "JS G OBJ"; - break; - case GJS_DEBUG_GFUNCTION: - prefix = "JS G FUNC"; - break; - case GJS_DEBUG_GFUNDAMENTAL: - prefix = "JS G FNDMTL"; - break; - case GJS_DEBUG_GCLOSURE: - prefix = "JS G CLSR"; - break; - case GJS_DEBUG_GBOXED: - prefix = "JS G BXD"; - break; - case GJS_DEBUG_GENUM: - prefix = "JS G ENUM"; - break; - case GJS_DEBUG_GPARAM: - prefix = "JS G PRM"; - break; - case GJS_DEBUG_GERROR: - prefix = "JS G ERR"; - break; - case GJS_DEBUG_GINTERFACE: - prefix = "JS G IFACE"; - break; - case GJS_DEBUG_GTYPE: - prefix = "JS GTYPE"; - break; - default: - prefix = "???"; - break; - } - - if (!is_allowed_prefix(prefix)) + if (!s_debug_log_enabled || !s_enabled_topics[topic]) return; va_start (args, format); @@ -256,7 +231,7 @@ gjs_debug(GjsDebugTopic topic, s = s2; } - write_to_stream(s_logfp, prefix, s); + write_to_stream(s_logfp, topic_to_prefix(topic), s); g_free(s); } diff --git a/util/log.h b/util/log.h index d56dda3d..92880e73 100644 --- a/util/log.h +++ b/util/log.h @@ -30,6 +30,7 @@ typedef enum { GJS_DEBUG_GFUNDAMENTAL, GJS_DEBUG_GINTERFACE, GJS_DEBUG_GTYPE, + GJS_DEBUG_LAST, } GjsDebugTopic; /* These defines are because we have some pretty expensive and -- cgit v1.2.1