[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.
This commit is contained in:
Chris Wilson 2008-12-19 12:54:53 +00:00
parent ecb8dce27c
commit fd96cea4fe
5 changed files with 41 additions and 36 deletions

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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);