[gjs] Optimize pushing the current context
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Optimize pushing the current context
- Date: Thu, 30 Sep 2010 14:49:33 +0000 (UTC)
commit 8dbbff01912d8e23e89aed369fda956e9aadd253
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Sep 29 18:15:29 2010 -0400
Optimize pushing the current context
For gjs_runtime_push_context() keep track of the number of times
an identical context has been pushed. This allows avoiding allocating
a GSList node for the most common case of repeatedly pushing the
default context.
https://bugzilla.gnome.org/show_bug.cgi?id=630964
gjs/jsapi-util.c | 36 ++++++++++++++++++++++++++++++------
1 files changed, 30 insertions(+), 6 deletions(-)
---
diff --git a/gjs/jsapi-util.c b/gjs/jsapi-util.c
index ebcd65a..6a3a138 100644
--- a/gjs/jsapi-util.c
+++ b/gjs/jsapi-util.c
@@ -41,6 +41,11 @@ gjs_util_error_quark (void)
}
typedef struct {
+ JSContext *context;
+ int depth;
+} ContextFrame;
+
+typedef struct {
GHashTable *dynamic_classes;
JSObject *import_global;
@@ -48,6 +53,7 @@ typedef struct {
JSContext *default_context;
/* In a thread-safe future we'd keep this in per-thread data */
+ ContextFrame current_frame;
GSList *context_stack;
} RuntimeData;
@@ -131,7 +137,14 @@ gjs_runtime_push_context(JSRuntime *runtime,
rd = get_data_from_runtime(runtime);
- rd->context_stack = g_slist_prepend(rd->context_stack, context);
+ if (context == rd->current_frame.context) {
+ rd->current_frame.depth++;
+ } else {
+ rd->context_stack = g_slist_prepend(rd->context_stack,
+ g_slice_dup(ContextFrame, &rd->current_frame));
+ rd->current_frame.context = context;
+ rd->current_frame.depth = 0;
+ }
}
/**
@@ -148,7 +161,16 @@ gjs_runtime_pop_context(JSRuntime *runtime)
rd = get_data_from_runtime(runtime);
- rd->context_stack = g_slist_delete_link(rd->context_stack, rd->context_stack);
+ if (rd->current_frame.depth == 0) {
+ if (rd->context_stack == NULL)
+ gjs_fatal("gjs_runtime_pop_context() called more times than gjs_runtime_push_context()");
+
+ rd->current_frame = *(ContextFrame *)rd->context_stack->data;
+ g_slice_free(ContextFrame, rd->context_stack->data);
+ rd->context_stack = g_slist_delete_link(rd->context_stack, rd->context_stack);
+ } else {
+ rd->current_frame.depth--;
+ }
}
/**
@@ -170,13 +192,18 @@ gjs_runtime_set_default_context(JSRuntime *runtime,
rd = get_data_from_runtime(runtime);
+ if (rd->context_stack != NULL || rd->current_frame.depth != 0)
+ gjs_fatal("gjs_runtime_set_default_context() called during gjs_push_context()");
+
if (context != NULL) {
if (rd->default_context != NULL)
gjs_fatal("gjs_runtime_set_default_context() called twice on the same JSRuntime");
rd->default_context = context;
+ rd->current_frame.context = context;
rd->import_global = JS_GetGlobalObject(rd->default_context);
} else {
rd->default_context = NULL;
+ rd->current_frame.context = NULL;
rd->import_global = NULL;
}
}
@@ -220,10 +247,7 @@ gjs_runtime_get_current_context(JSRuntime *runtime)
rd = get_data_from_runtime(runtime);
- if (rd->context_stack)
- return rd->context_stack->data;
- else
- return rd->default_context;
+ return rd->current_frame.context;
}
static JSClass global_class = {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]