diff --git a/perf/cairo-perf-trace.c b/perf/cairo-perf-trace.c index 6ee63a3c8..9e23f2896 100644 --- a/perf/cairo-perf-trace.c +++ b/perf/cairo-perf-trace.c @@ -232,6 +232,7 @@ execute (cairo_perf_t *perf, cairo_perf_timer_stop (); times[i] = cairo_perf_timer_elapsed (); + cairo_script_interpreter_finish (csi); cairo_script_interpreter_destroy (csi); if (perf->raw) { @@ -426,12 +427,10 @@ cairo_perf_fini (cairo_perf_t *perf) { cairo_boilerplate_free_targets (perf->targets); free (perf->times); -#if 0 /* XXX */ cairo_debug_reset_static_data (); #if HAVE_FCFINI FcFini (); #endif -#endif } static cairo_bool_t diff --git a/util/cairo-script/cairo-script-interpreter.c b/util/cairo-script/cairo-script-interpreter.c index bb504ad5b..ad4a1a7a4 100644 --- a/util/cairo-script/cairo-script-interpreter.c +++ b/util/cairo-script/cairo-script-interpreter.c @@ -116,6 +116,9 @@ _csi_perm_alloc (csi_t *ctx, int size) void * _csi_slab_alloc (csi_t *ctx, int size) { +#if CSI_DEBUG_MALLOC + return malloc (size); +#else int chunk_size; csi_chunk_t *chunk; void *ptr; @@ -150,6 +153,7 @@ _csi_slab_alloc (csi_t *ctx, int size) chunk->rem--; return ptr; +#endif } void @@ -161,12 +165,16 @@ _csi_slab_free (csi_t *ctx, void *ptr, int size) if (_csi_unlikely (ptr == NULL)) return; +#if CSI_DEBUG_MALLOC + free (ptr); +#else chunk_size = 2 * sizeof (void *); chunk_size = (size + chunk_size - 1) / chunk_size; free_list = ptr; *free_list = ctx->slabs[chunk_size].free_list; ctx->slabs[chunk_size].free_list = ptr; +#endif } static void @@ -396,16 +404,6 @@ _csi_fini (csi_t *ctx) _csi_scanner_fini (ctx, &ctx->scanner); _csi_hash_table_fini (&ctx->strings); - - if (ctx->free_array != NULL) - csi_array_free (ctx, ctx->free_array); - if (ctx->free_dictionary != NULL) - csi_dictionary_free (ctx, ctx->free_dictionary); - if (ctx->free_string != NULL) - csi_string_free (ctx, ctx->free_string); - - _csi_slab_fini (ctx); - _csi_perm_fini (ctx); } csi_status_t @@ -530,6 +528,8 @@ cairo_script_interpreter_run (csi_t *ctx, const char *filename) if (ctx->status) return ctx->status; + if (ctx->finished) + return ctx->status = CSI_STATUS_INTERPRETER_FINISHED; ctx->status = csi_file_new (ctx, &file, filename, "r"); if (ctx->status) @@ -550,6 +550,8 @@ cairo_script_interpreter_feed_string (csi_t *ctx, const char *line, int len) if (ctx->status) return ctx->status; + if (ctx->finished) + return ctx->status = CSI_STATUS_INTERPRETER_FINISHED; if (len < 0) len = strlen (line); @@ -573,6 +575,22 @@ cairo_script_interpreter_reference (csi_t *ctx) } slim_hidden_def (cairo_script_interpreter_reference); +cairo_status_t +cairo_script_interpreter_finish (csi_t *ctx) +{ + csi_status_t status; + + status = ctx->status; + if (! ctx->finished) { + _csi_fini (ctx); + ctx->finished = 1; + } else if (status == CAIRO_STATUS_SUCCESS) { + status = ctx->status = CSI_STATUS_INTERPRETER_FINISHED; + } + + return status; +} + cairo_status_t cairo_script_interpreter_destroy (csi_t *ctx) { @@ -582,7 +600,18 @@ cairo_script_interpreter_destroy (csi_t *ctx) if (--ctx->ref_count) return status; - _csi_fini (ctx); + if (! ctx->finished) + _csi_fini (ctx); + + if (ctx->free_array != NULL) + csi_array_free (ctx, ctx->free_array); + if (ctx->free_dictionary != NULL) + csi_dictionary_free (ctx, ctx->free_dictionary); + if (ctx->free_string != NULL) + csi_string_free (ctx, ctx->free_string); + + _csi_slab_fini (ctx); + _csi_perm_fini (ctx); free (ctx); return status; diff --git a/util/cairo-script/cairo-script-interpreter.h b/util/cairo-script/cairo-script-interpreter.h index e6d573003..a9318b038 100644 --- a/util/cairo-script/cairo-script-interpreter.h +++ b/util/cairo-script/cairo-script-interpreter.h @@ -91,6 +91,9 @@ cairo_script_interpreter_feed_string (cairo_script_interpreter_t *ctx, cairo_public cairo_script_interpreter_t * cairo_script_interpreter_reference (cairo_script_interpreter_t *ctx); +cairo_public cairo_status_t +cairo_script_interpreter_finish (cairo_script_interpreter_t *ctx); + cairo_public cairo_status_t cairo_script_interpreter_destroy (cairo_script_interpreter_t *ctx); diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c index 84398f18c..204e4b8d8 100644 --- a/util/cairo-script/cairo-script-objects.c +++ b/util/cairo-script/cairo-script-objects.c @@ -157,6 +157,16 @@ _csi_array_execute (csi_t *ctx, csi_array_t *array) void csi_array_free (csi_t *ctx, csi_array_t *array) { +#if CSI_DEBUG_MALLOC + _csi_stack_fini (ctx, &array->stack); + _csi_slab_free (ctx, array, sizeof (csi_array_t)); +#else + csi_integer_t n; + + for (n = 0; n < array->stack.len; n++) + csi_object_free (ctx, &array->stack.objects[n]); + array->stack.len = 0; + if (ctx->free_array != NULL) { if (array->stack.size > ctx->free_array->stack.size) { csi_array_t *tmp = ctx->free_array; @@ -166,18 +176,9 @@ csi_array_free (csi_t *ctx, csi_array_t *array) _csi_stack_fini (ctx, &array->stack); _csi_slab_free (ctx, array, sizeof (csi_array_t)); - } else { - csi_integer_t n; - - for (n = 0; n < array->stack.len; n++) - csi_object_free (ctx, &array->stack.objects[n]); - array->stack.len = 0; - - if (ctx->free_array == NULL) - ctx->free_array = array; - else - csi_array_free (ctx, array); - } + } else + ctx->free_array = array; +#endif } csi_status_t @@ -262,11 +263,16 @@ csi_dictionary_free (csi_t *ctx, _dictionary_entry_pluck, &data); +#if CSI_DEBUG_MALLOC + _csi_hash_table_fini (&dict->hash_table); + _csi_slab_free (ctx, dict, sizeof (csi_dictionary_t)); +#else if (ctx->free_dictionary != NULL) { _csi_hash_table_fini (&dict->hash_table); _csi_slab_free (ctx, dict, sizeof (csi_dictionary_t)); } else ctx->free_dictionary = dict; +#endif } csi_status_t @@ -575,6 +581,10 @@ _csi_string_execute (csi_t *ctx, csi_string_t *string) void csi_string_free (csi_t *ctx, csi_string_t *string) { +#if CSI_DEBUG_MALLOC + _csi_free (ctx, string->string); + _csi_slab_free (ctx, string, sizeof (csi_string_t)); +#else if (ctx->free_string != NULL) { if (string->len > ctx->free_string->len) { csi_string_t *tmp = ctx->free_string; @@ -586,6 +596,7 @@ csi_string_free (csi_t *ctx, csi_string_t *string) _csi_slab_free (ctx, string, sizeof (csi_string_t)); } else ctx->free_string = string; +#endif } csi_status_t diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h index d2ebc0c80..772be4c96 100644 --- a/util/cairo-script/cairo-script-private.h +++ b/util/cairo-script/cairo-script-private.h @@ -219,6 +219,7 @@ typedef enum _csi_status { CSI_STATUS_SCRIPT_INVALID_TYPE, CSI_STATUS_SCRIPT_INVALID_INDEX, CSI_STATUS_SCRIPT_UNDEFINED_NAME, + CSI_STATUS_INTERPRETER_FINISHED, _CSI_STATUS_SCRIPT_LAST_ERROR, CSI_INT_STATUS_UNSUPPORTED @@ -453,6 +454,8 @@ struct _cairo_script_interpreter { int ref_count; csi_status_t status; + unsigned int finished : 1; + csi_hooks_t hooks; csi_hash_table_t strings;