eo: add a small object cache to make memory recycling faster.

This commit is contained in:
Cedric Bail 2013-09-11 11:23:50 +09:00
parent 164299e689
commit 5290befb53
2 changed files with 42 additions and 2 deletions

View File

@ -687,6 +687,8 @@ eo_class_funcs_set(Eo_Class *klass_id, const Eo_Op_Func_Description *func_descs)
static void
eo_class_free(_Eo_Class *klass)
{
void *object;
if (klass->constructed)
{
if (klass->desc->class_destructor)
@ -695,6 +697,11 @@ eo_class_free(_Eo_Class *klass)
_dich_func_clean_all(klass);
}
EINA_TRASH_CLEAN(&klass->trash, object)
free(object);
eina_lock_free(&klass->trash_lock);
free(klass);
}
@ -886,6 +893,7 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
klass = calloc(1, _eo_class_sz + extn_sz + mro_sz + mixins_sz);
EINA_MAGIC_SET(klass, EO_CLASS_EINA_MAGIC);
eina_lock_new(&klass->trash_lock);
klass->parent = parent;
klass->desc = desc;
klass->extensions = (const _Eo_Class **) ((char *) klass + _eo_class_sz);
@ -1073,6 +1081,7 @@ EAPI Eo *
eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id, ...)
{
Eina_Bool do_err;
_Eo *obj;
_Eo_Class *klass = _eo_class_pointer_get(klass_id);
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, NULL);
@ -1087,7 +1096,19 @@ eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent
return NULL;
}
_Eo *obj = calloc(1, klass->obj_size);
eina_lock_take(&klass->trash_lock);
obj = eina_trash_pop(&klass->trash);
if (obj)
{
memset(obj, 0, klass->obj_size);
klass->trash_count--;
}
else
{
obj = calloc(1, klass->obj_size);
}
eina_lock_release(&klass->trash_lock);
obj->refcount++;
obj->klass = klass;

View File

@ -139,6 +139,11 @@ struct _Eo_Class
const _Eo_Class **mro;
/* cached object for faster allocation */
Eina_Trash *trash;
Eina_Lock trash_lock;
unsigned int trash_count;
unsigned int obj_size; /**< size of an object of this class */
unsigned int chain_size;
unsigned int base_id;
@ -204,6 +209,8 @@ _eo_del_internal(const char *file, int line, _Eo *obj)
static inline void
_eo_free(_Eo *obj)
{
_Eo_Class *klass = (_Eo_Class*) obj->klass;
#ifdef EO_DEBUG
if (obj->datarefcount)
{
@ -211,7 +218,19 @@ _eo_free(_Eo *obj)
}
#endif
_eo_id_release(obj->obj_id);
free(obj);
eina_lock_take(&klass->trash_lock);
if (klass->trash_count <= 8)
{
eina_trash_push(&klass->trash, obj);
klass->trash_count++;
eina_lock_release(&klass->trash_lock);
}
else
{
eina_lock_release(&klass->trash_lock);
free(obj);
}
}
static inline _Eo *