[script] Freed object cache.

Cache the last freed object to reduce malloc pressure.
This commit is contained in:
Chris Wilson 2008-12-10 21:00:11 +00:00
parent 1042909796
commit adc9c90d79
4 changed files with 91 additions and 51 deletions

View file

@ -426,9 +426,6 @@ _csi_hash_table_foreach (csi_hash_table_t *hash_table,
unsigned long i;
csi_hash_entry_t *entry;
if (hash_table == NULL)
return;
/* Mark the table for iteration */
++hash_table->iterating;
for (i = 0; i < hash_table->arrangement->size; i++) {

View file

@ -55,9 +55,6 @@ _csi_error (csi_status_t status)
void *
_csi_alloc (csi_t *ctx, int size)
{
if (_csi_unlikely (ctx->status))
return NULL;
return malloc (size);
}
@ -76,9 +73,6 @@ _csi_alloc0 (csi_t *ctx, int size)
void *
_csi_realloc (csi_t *ctx, void *ptr, int size)
{
if (_csi_unlikely (ctx->status))
return NULL;
return realloc (ptr, size);
}
@ -98,9 +92,6 @@ _csi_slab_alloc (csi_t *ctx, int size)
csi_chunk_t *chunk;
void *ptr;
if (_csi_unlikely (ctx->status))
return NULL;
chunk_size = 2 * sizeof (void *);
chunk_size = (size + chunk_size - 1) / chunk_size;
@ -378,6 +369,13 @@ _csi_fini (csi_t *ctx)
_csi_hash_table_foreach (&ctx->strings, _intern_string_pluck, ctx);
_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);
}

View file

@ -42,19 +42,26 @@ csi_array_new (csi_t *ctx,
{
csi_array_t *array;
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);
if (ctx->free_array != NULL) {
array = ctx->free_array;
ctx->free_array = NULL;
} else {
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);
if (_csi_unlikely (status)) {
_csi_slab_free (ctx, array, sizeof (csi_array_t));
return status;
}
}
array->base.type = CSI_OBJECT_TYPE_ARRAY;
array->base.ref = 1;
status = _csi_stack_init (ctx, &array->stack, 32);
if (_csi_unlikely (status)) {
_csi_slab_free (ctx, array, sizeof (csi_array_t));
return status;
}
obj->type = CSI_OBJECT_TYPE_ARRAY;
obj->datum.array = array;
@ -145,8 +152,18 @@ _csi_array_execute (csi_t *ctx, csi_array_t *array)
void
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));
if (ctx->free_array != NULL) {
_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;
}
}
csi_status_t
@ -174,19 +191,27 @@ csi_dictionary_new (csi_t *ctx,
{
csi_dictionary_t *dict;
csi_status_t status;
dict = _csi_slab_alloc (ctx, sizeof (csi_dictionary_t));
if (_csi_unlikely (dict == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
if (ctx->free_dictionary != NULL) {
dict = ctx->free_dictionary;
ctx->free_dictionary = NULL;
} else {
csi_status_t status;
dict = _csi_slab_alloc (ctx, sizeof (csi_dictionary_t));
if (_csi_unlikely (dict == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
status = _csi_hash_table_init (&dict->hash_table,
_dictionary_name_equal);
if (_csi_unlikely (status)) {
_csi_slab_free (ctx, dict, sizeof (csi_dictionary_t));
return status;
}
}
dict->base.type = CSI_OBJECT_TYPE_DICTIONARY;
dict->base.ref = 1;
status = _csi_hash_table_init (&dict->hash_table, _dictionary_name_equal);
if (_csi_unlikely (status)) {
_csi_slab_free (ctx, dict, sizeof (csi_dictionary_t));
return status;
}
obj->type = CSI_OBJECT_TYPE_DICTIONARY;
obj->datum.dictionary = dict;
@ -224,9 +249,12 @@ csi_dictionary_free (csi_t *ctx,
_csi_hash_table_foreach (&dict->hash_table,
_dictionary_entry_pluck,
&data);
_csi_hash_table_fini (&dict->hash_table);
_csi_slab_free (ctx, dict, sizeof (csi_dictionary_t));
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;
}
csi_status_t
@ -480,28 +508,33 @@ csi_string_new (csi_t *ctx,
{
csi_string_t *string;
string = _csi_slab_alloc (ctx, sizeof (csi_string_t));
if (_csi_unlikely (string == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
string->base.type = CSI_OBJECT_TYPE_STRING;
string->base.ref = 1;
if (len < 0)
len = strlen (str);
if (_csi_unlikely (len >= INT32_MAX)) {
_csi_slab_free (ctx, string, sizeof (csi_string_t));
return _csi_error (CSI_STATUS_NO_MEMORY);
}
string->string = _csi_alloc (ctx, len + 1);
if (_csi_unlikely (string->string == NULL)) {
_csi_slab_free (ctx, string, sizeof (csi_string_t));
if (_csi_unlikely (len >= INT32_MAX))
return _csi_error (CSI_STATUS_NO_MEMORY);
if (ctx->free_string == NULL || ctx->free_string->len <= len) {
string = _csi_slab_alloc (ctx, sizeof (csi_string_t));
if (_csi_unlikely (string == NULL))
return _csi_error (CSI_STATUS_NO_MEMORY);
string->string = _csi_alloc (ctx, len + 1);
if (_csi_unlikely (string->string == NULL)) {
_csi_slab_free (ctx, string, sizeof (csi_string_t));
return _csi_error (CSI_STATUS_NO_MEMORY);
}
} else {
string = ctx->free_string;
ctx->free_string = NULL;
}
memcpy (string->string, str, len);
string->string[len] = '\0';
string->len = len;
string->base.type = CSI_OBJECT_TYPE_STRING;
string->base.ref = 1;
obj->type = CSI_OBJECT_TYPE_STRING;
obj->datum.string = string;
@ -530,8 +563,17 @@ _csi_string_execute (csi_t *ctx, csi_string_t *string)
void
csi_string_free (csi_t *ctx, csi_string_t *string)
{
_csi_free (ctx, string->string);
_csi_slab_free (ctx, string, sizeof (csi_string_t));
if (ctx->free_string != NULL) {
if (string->len > ctx->free_string->len) {
csi_string_t *tmp = ctx->free_string;
ctx->free_string = string;
string = tmp;
}
_csi_free (ctx, string->string);
_csi_slab_free (ctx, string, sizeof (csi_string_t));
} else
ctx->free_string = string;
}
csi_status_t

View file

@ -465,7 +465,10 @@ struct _cairo_script_interpreter {
struct {
csi_chunk_t *chunk;
void *free_list;
} slabs[(sizeof (union _csi_union_object) + (2*sizeof (void *)-1))/ (2*sizeof (void*))];
} slabs[16];
csi_array_t *free_array;
csi_dictionary_t *free_dictionary;
csi_string_t *free_string;
/* caches of live data */
csi_list_t *_images;