summaryrefslogtreecommitdiff
path: root/util/cairo-script
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-12-19 12:54:53 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2009-01-02 09:53:24 +0000
commitfd96cea4fefeeee8bcccde663faa559151e2606e (patch)
tree92af865233f68773b3c28b47be19b5231f2b7343 /util/cairo-script
parentecb8dce27c769158fe4a92432a90b24a96f8afa9 (diff)
downloadcairo-fd96cea4fefeeee8bcccde663faa559151e2606e.tar.gz
[script] Improve array construction.
Limit the memory allocation to the initial array size and perform a direct copy from the operand stack to the array.
Diffstat (limited to 'util/cairo-script')
-rw-r--r--util/cairo-script/cairo-script-objects.c27
-rw-r--r--util/cairo-script/cairo-script-operators.c45
-rw-r--r--util/cairo-script/cairo-script-private.h1
-rw-r--r--util/cairo-script/cairo-script-scanner.c2
-rw-r--r--util/cairo-script/cairo-script-stack.c2
5 files changed, 41 insertions, 36 deletions
diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c
index df4fe8d45..552241f35 100644
--- a/util/cairo-script/cairo-script-objects.c
+++ b/util/cairo-script/cairo-script-objects.c
@@ -38,26 +38,30 @@
csi_status_t
csi_array_new (csi_t *ctx,
+ csi_integer_t initial_size,
csi_object_t *obj)
{
csi_array_t *array;
- if (ctx->free_array != NULL) {
- array = ctx->free_array;
- ctx->free_array = NULL;
- } else {
+ if (ctx->free_array == NULL ||
+ ctx->free_array->stack.size <= initial_size)
+ {
csi_status_t status;
array = _csi_slab_alloc (ctx, sizeof (csi_array_t));
if (_csi_unlikely (array == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
- status = _csi_stack_init (ctx, &array->stack, 32);
+ status = _csi_stack_init (ctx, &array->stack,
+ initial_size ? initial_size : 32);
if (_csi_unlikely (status)) {
_csi_slab_free (ctx, array, sizeof (csi_array_t));
return status;
}
+ } else {
+ array = ctx->free_array;
+ ctx->free_array = NULL;
}
array->base.type = CSI_OBJECT_TYPE_ARRAY;
@@ -153,16 +157,25 @@ void
csi_array_free (csi_t *ctx, csi_array_t *array)
{
if (ctx->free_array != NULL) {
+ if (array->stack.size > ctx->free_array->stack.size) {
+ csi_array_t *tmp = ctx->free_array;
+ ctx->free_array = array;
+ array = tmp;
+ }
+
_csi_stack_fini (ctx, &array->stack);
_csi_slab_free (ctx, array, sizeof (csi_array_t));
} else {
csi_integer_t n;
- ctx->free_array = array;
-
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);
}
}
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index 41c58d605..6b328a98d 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -567,44 +567,35 @@ static csi_status_t
end_array_construction (csi_t *ctx)
{
csi_object_t obj;
- csi_array_t *array;
csi_status_t status;
+ int len = 0;
- status = csi_array_new (ctx, &obj);
- if (_csi_unlikely (status))
- return status;
-
- array = obj.datum.array;
do {
- csi_object_t *value;
+ check (len + 1);
- check (1);
-
- value = _csi_peek_ostack (ctx, 0);
- if (csi_object_get_type (value) == CSI_OBJECT_TYPE_MARK) {
- pop (1);
+ if (csi_object_get_type (_csi_peek_ostack (ctx, len)) ==
+ CSI_OBJECT_TYPE_MARK)
+ {
break;
}
- status = csi_array_append (ctx, array, value);
- if (_csi_unlikely (status))
- return status;
-
- pop (1);
+ len++;
} while (TRUE);
- /* and reverse */
- if (array->stack.len) {
- unsigned int i, j;
+ status = csi_array_new (ctx, len, &obj);
+ if (_csi_unlikely (status))
+ return status;
- for (i = 0, j = array->stack.len; i < --j; i++) {
- csi_object_t tmp;
+ if (len != 0) {
+ csi_array_t *array;
- tmp = array->stack.objects[i];
- array->stack.objects[i] = array->stack.objects[j];
- array->stack.objects[j] = tmp;
- }
+ array = obj.datum.array;
+ memcpy (array->stack.objects,
+ _csi_peek_ostack (ctx, len - 1),
+ sizeof (csi_object_t) * len);
+ array->stack.len = len;
}
+ ctx->ostack.len -= len + 1;
return push (&obj);
}
@@ -824,7 +815,7 @@ _array (csi_t *ctx)
csi_object_t obj;
csi_status_t status;
- status = csi_array_new (ctx, &obj);
+ status = csi_array_new (ctx, 0, &obj);
if (_csi_unlikely (status))
return status;
diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h
index d21be1529..f74cb49fa 100644
--- a/util/cairo-script/cairo-script-private.h
+++ b/util/cairo-script/cairo-script-private.h
@@ -618,6 +618,7 @@ _csi_error (csi_status_t status);
csi_private csi_status_t
csi_array_new (csi_t *ctx,
+ csi_integer_t initial_size,
csi_object_t *obj);
csi_private csi_status_t
diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c
index 3f8a271e7..c08e447db 100644
--- a/util/cairo-script/cairo-script-scanner.c
+++ b/util/cairo-script/cairo-script-scanner.c
@@ -350,7 +350,7 @@ token_end (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src)
&scan->procedure_stack,
&scan->build_procedure);
- scan->status = csi_array_new (ctx, &scan->build_procedure);
+ scan->status = csi_array_new (ctx, 0, &scan->build_procedure);
scan->build_procedure.type |= CSI_OBJECT_ATTR_EXECUTABLE;
reset (scan);
return;
diff --git a/util/cairo-script/cairo-script-stack.c b/util/cairo-script/cairo-script-stack.c
index 4f5df46e7..d6c123b43 100644
--- a/util/cairo-script/cairo-script-stack.c
+++ b/util/cairo-script/cairo-script-stack.c
@@ -44,7 +44,7 @@ _csi_stack_init (csi_t *ctx, csi_stack_t *stack, csi_integer_t size)
stack->len = 0;
stack->size = size;
/* assert ((unsigned) size < INT32_MAX / sizeof (csi_object_t)); */
- stack->objects = _csi_alloc (ctx, stack->size * sizeof (csi_object_t));
+ stack->objects = _csi_alloc (ctx, size * sizeof (csi_object_t));
if (_csi_unlikely (stack->objects == NULL))
status = _csi_error (CSI_STATUS_NO_MEMORY);