Eo: Added cur_klass as a parameter to eo_*_do_super.

We now need to pass the current class to eo_do_super. This is faster and
more memory efficient and generally lets us do things better.

Using the eo_benchmarks we get ~20% speed-up.
This commit is contained in:
Tom Hacohen 2013-03-13 16:04:04 +00:00
parent 61ca9d550d
commit 83180acf26
3 changed files with 38 additions and 82 deletions

View File

@ -630,6 +630,7 @@ EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
/**
* @brief Calls the super function for the specific op.
* @param obj The object to work on
* @param cur_klass The *current* class (use the class *after* this in the MRO).
* @param ... list of parameters.
* @return @c EINA_TRUE on success.
*
@ -637,11 +638,12 @@ EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
*
* @see #eo_do
*/
#define eo_do_super(obj, ...) eo_do_super_internal(obj, EO_OP_TYPE_REGULAR, __VA_ARGS__)
#define eo_do_super(obj, cur_klass, ...) eo_do_super_internal(obj, cur_klass, EO_OP_TYPE_REGULAR, __VA_ARGS__)
/**
* @brief Calls the super function for the specific op.
* @param klass The klass to work on
* @param cur_klass The *current* class (use the class *after* this in the MRO).
* @param ... list of parameters.
* @return @c EINA_TRUE on success.
*
@ -649,11 +651,12 @@ EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
*
* @see #eo_class_do
*/
#define eo_class_do_super(klass, ...) eo_class_do_super_internal(klass, __VA_ARGS__)
#define eo_class_do_super(klass, cur_klass, ...) eo_class_do_super_internal(klass, cur_klass, __VA_ARGS__)
/**
* @brief Calls the super function for the specific op.
* @param obj The object to work on
* @param cur_klass The *current* class (use the class *after* this in the MRO).
* @param op_type The type of the ops that are passed.
* @param op The wanted op.
* @param ... list of parameters.
@ -664,11 +667,12 @@ EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
* @see #eo_do
* @see #eo_do_super
*/
EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...);
EAPI Eina_Bool eo_do_super_internal(Eo *obj, const Eo_Class *cur_klass, Eo_Op_Type op_type, Eo_Op op, ...);
/**
* @brief Calls the super function for the specific op.
* @param klass The klass to work on
* @param cur_klass The *current* class (use the class *after* this in the MRO).
* @param op The wanted op.
* @param ... list of parameters.
* @return @c EINA_TRUE on success.
@ -678,7 +682,7 @@ EAPI Eina_Bool eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...);
* @see #eo_class_do
* @see #eo_class_do_super
*/
EAPI Eina_Bool eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...);
EAPI Eina_Bool eo_class_do_super_internal(const Eo_Class *klass, const Eo_Class *cur_klass, Eo_Op op, ...);
/**
* @brief Gets the class of the object.

View File

@ -27,11 +27,6 @@ static inline void _eo_unref(Eo *obj);
static const Eo_Class *_eo_op_class_get(Eo_Op op);
static const Eo_Op_Description *_eo_op_id_desc_get(Eo_Op op);
typedef struct
{
const Eo_Class *kls;
} Eo_Kls_Itr;
struct _Eo {
EINA_MAGIC
EINA_INLIST;
@ -44,8 +39,6 @@ struct _Eo {
Eina_List *composite_objects;
Eo_Kls_Itr mro_itr;
int refcount;
Eina_Bool do_error:1;
@ -106,7 +99,6 @@ struct _Eo_Class
Eo_Extension_Data_Offset *extn_data_off;
const Eo_Class **mro;
Eo_Kls_Itr mro_itr;
unsigned int extn_data_size;
unsigned int chain_size;
@ -253,40 +245,14 @@ _eo_op_id_name_get(Eo_Op op)
return (desc) ? desc->name : NULL;
}
static inline void
_eo_kls_itr_init(const Eo_Class *obj_klass, Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state)
{
memcpy(prev_state, cur, sizeof(*cur));
cur->kls = *obj_klass->mro;
}
static inline void
_eo_kls_itr_end(Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state)
{
memcpy(cur, prev_state, sizeof(*cur));
}
static inline const Eo_Class *
_eo_kls_itr_get(Eo_Kls_Itr *cur)
{
return cur->kls;
}
static inline void
_eo_kls_itr_set(Eo_Kls_Itr *cur, const Eo_Class *kls)
{
cur->kls = kls;
}
static inline const Eo_Class *
_eo_kls_itr_next(const Eo_Class *orig_kls, Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_state, Eo_Op op)
_eo_kls_itr_next(const Eo_Class *orig_kls, const Eo_Class *cur_klass, Eo_Op op)
{
const Eo_Class **kls_itr = NULL;
memcpy(prev_state, cur, sizeof(*cur));
/* Find the kls itr. */
kls_itr = orig_kls->mro;
while (*kls_itr && (*kls_itr != cur->kls))
while (*kls_itr && (*kls_itr != cur_klass))
kls_itr++;
if (*kls_itr)
@ -300,31 +266,27 @@ _eo_kls_itr_next(const Eo_Class *orig_kls, Eo_Kls_Itr *cur, Eo_Kls_Itr *prev_sta
kls_itr++;
continue;
}
cur->kls = fsrc->src;
return cur->kls;
return fsrc->src;
}
}
cur->kls = NULL;
return NULL;
}
static inline const op_type_funcs *
_eo_kls_itr_func_get(Eo_Kls_Itr *mro_itr, Eo_Op op)
_eo_kls_itr_func_get(const Eo_Class *cur_klass, Eo_Op op)
{
const Eo_Class *klass = _eo_kls_itr_get(mro_itr);
const Eo_Class *klass = cur_klass;
if (klass)
{
const op_type_funcs *func = _dich_func_get(klass, op);
if (func && func->func)
{
_eo_kls_itr_set(mro_itr, func->src);
return func;
}
}
_eo_kls_itr_set(mro_itr, NULL);
return NULL;
}
@ -340,7 +302,7 @@ _eo_kls_itr_func_get(Eo_Kls_Itr *mro_itr, Eo_Op op)
while (0)
static Eina_Bool
_eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
_eo_op_internal(Eo *obj, const Eo_Class *cur_klass, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
{
#ifdef EO_DEBUG
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
@ -356,8 +318,7 @@ _eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
#endif
{
const op_type_funcs *func =
_eo_kls_itr_func_get(&obj->mro_itr, op);
const op_type_funcs *func = _eo_kls_itr_func_get(cur_klass, op);
if (EINA_LIKELY(func != NULL))
{
void *func_data =_eo_data_get(obj, func->src);
@ -373,14 +334,10 @@ _eo_op_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, va_list *p_list)
EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
{
/* FIXME: Clean this up a bit. */
Eo_Kls_Itr prev_state;
_eo_kls_itr_init(emb_obj->klass, &emb_obj->mro_itr, &prev_state);
if (_eo_op_internal(emb_obj, op_type, op, p_list))
if (_eo_op_internal(emb_obj, emb_obj->klass, op_type, op, p_list))
{
_eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
return EINA_TRUE;
}
_eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
}
}
return EINA_FALSE;
@ -392,7 +349,6 @@ _eo_dov_internal(Eo *obj, Eo_Op_Type op_type, va_list *p_list)
Eina_Bool prev_error;
Eina_Bool ret = EINA_TRUE;
Eo_Op op = EO_NOOP;
Eo_Kls_Itr prev_state;
prev_error = obj->do_error;
_eo_ref(obj);
@ -400,16 +356,13 @@ _eo_dov_internal(Eo *obj, Eo_Op_Type op_type, va_list *p_list)
op = va_arg(*p_list, Eo_Op);
while (op)
{
_eo_kls_itr_init(obj->klass, &obj->mro_itr, &prev_state);
if (!_eo_op_internal(obj, op_type, op, p_list))
if (!_eo_op_internal(obj, obj->klass, op_type, op, p_list))
{
_EO_OP_ERR_NO_OP_PRINT(op, obj->klass);
ret = EINA_FALSE;
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
break;
}
op = va_arg(*p_list, Eo_Op);
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
}
_eo_unref(obj);
@ -448,19 +401,19 @@ eo_vdo_internal(Eo *obj, Eo_Op_Type op_type, va_list *ops)
}
EAPI Eina_Bool
eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
eo_do_super_internal(Eo *obj, const Eo_Class *cur_klass, Eo_Op_Type op_type, Eo_Op op, ...)
{
const Eo_Class *nklass;
Eina_Bool ret = EINA_TRUE;
va_list p_list;
Eo_Kls_Itr prev_state;
EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE);
EO_MAGIC_RETURN_VAL(cur_klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
/* Advance the kls itr. */
nklass = _eo_kls_itr_next(obj->klass, &obj->mro_itr, &prev_state, op);
nklass = _eo_kls_itr_next(obj->klass, cur_klass, op);
va_start(p_list, op);
if (!_eo_op_internal(obj, op_type, op, &p_list))
if (!_eo_op_internal(obj, nklass, op_type, op, &p_list))
{
_EO_OP_ERR_NO_OP_PRINT(op, nklass);
ret = EINA_FALSE;
@ -470,12 +423,11 @@ eo_do_super_internal(Eo *obj, Eo_Op_Type op_type, Eo_Op op, ...)
if (obj->do_error)
ret = EINA_FALSE;
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
return ret;
}
static Eina_Bool
_eo_class_op_internal(Eo_Class *klass, Eo_Op op, va_list *p_list)
_eo_class_op_internal(Eo_Class *klass, const Eo_Class *cur_klass, Eo_Op op, va_list *p_list)
{
#ifdef EO_DEBUG
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op);
@ -491,8 +443,7 @@ _eo_class_op_internal(Eo_Class *klass, Eo_Op op, va_list *p_list)
#endif
{
const op_type_funcs *func =
_eo_kls_itr_func_get(&klass->mro_itr, op);
const op_type_funcs *func = _eo_kls_itr_func_get(cur_klass, op);
if (func)
{
((eo_op_func_type_class) func->func)(klass, p_list);
@ -508,7 +459,6 @@ eo_class_do_internal(const Eo_Class *klass, ...)
{
Eina_Bool ret = EINA_TRUE;
Eo_Op op = EO_NOOP;
Eo_Kls_Itr prev_state;
va_list p_list;
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
@ -518,15 +468,12 @@ eo_class_do_internal(const Eo_Class *klass, ...)
op = va_arg(p_list, Eo_Op);
while (op)
{
_eo_kls_itr_init(klass, &((Eo_Class *) klass)->mro_itr, &prev_state);
if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
if (!_eo_class_op_internal((Eo_Class *) klass, klass, op, &p_list))
{
_EO_OP_ERR_NO_OP_PRINT(op, klass);
ret = EINA_FALSE;
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
break;
}
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
op = va_arg(p_list, Eo_Op);
}
@ -536,26 +483,25 @@ eo_class_do_internal(const Eo_Class *klass, ...)
}
EAPI Eina_Bool
eo_class_do_super_internal(const Eo_Class *klass, Eo_Op op, ...)
eo_class_do_super_internal(const Eo_Class *klass, const Eo_Class *cur_klass, Eo_Op op, ...)
{
const Eo_Class *nklass;
Eina_Bool ret = EINA_TRUE;
va_list p_list;
Eo_Kls_Itr prev_state;
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
EO_MAGIC_RETURN_VAL(cur_klass, EO_CLASS_EINA_MAGIC, EINA_FALSE);
/* Advance the kls itr. */
nklass = _eo_kls_itr_next(klass, &((Eo_Class *) klass)->mro_itr, &prev_state, op);
nklass = _eo_kls_itr_next(klass, cur_klass, op);
va_start(p_list, op);
if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
if (!_eo_class_op_internal((Eo_Class *) klass, nklass, op, &p_list))
{
_EO_OP_ERR_NO_OP_PRINT(op, nklass);
ret = EINA_FALSE;
}
va_end(p_list);
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
return ret;
}

View File

@ -165,19 +165,20 @@ END_TEST
static Eina_Bool _man_should_con = EINA_TRUE;
static Eina_Bool _man_should_des = EINA_TRUE;
static const Eo_Class *cur_klass = NULL;
static void
_man_con(Eo *obj, void *data EINA_UNUSED, va_list *list EINA_UNUSED)
{
if (_man_should_con)
eo_manual_free_set(obj, EINA_TRUE);
eo_do_super(obj, eo_constructor());
eo_do_super(obj, cur_klass, eo_constructor());
}
static void
_man_des(Eo *obj, void *data EINA_UNUSED, va_list *list EINA_UNUSED)
{
eo_do_super(obj, eo_destructor());
eo_do_super(obj, cur_klass, eo_destructor());
if (_man_should_des)
eo_manual_free_set(obj, EINA_FALSE);
}
@ -214,6 +215,7 @@ START_TEST(eo_man_free)
const Eo_Class *klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
fail_if(!klass);
cur_klass = klass;
Eo *obj = eo_add(klass, NULL);
fail_if(!obj);
@ -226,6 +228,7 @@ START_TEST(eo_man_free)
_man_should_des = EINA_FALSE;
klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
cur_klass = klass;
fail_if(!klass);
obj = eo_add(klass, NULL);
@ -244,6 +247,7 @@ START_TEST(eo_man_free)
_man_should_con = EINA_FALSE;
klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
cur_klass = klass;
fail_if(!klass);
obj = eo_add(klass, NULL);
@ -577,12 +581,14 @@ START_TEST(eo_magic_checks)
fail_if(!obj);
fail_if(eo_do((Eo *) buf, EO_NOOP));
fail_if(eo_do_super((Eo *) buf, EO_NOOP));
fail_if(eo_do_super((Eo *) buf, SIMPLE_CLASS, EO_NOOP));
fail_if(eo_do_super(obj, (const Eo_Class *) buf, EO_NOOP));
fail_if(eo_class_get((Eo *) buf));
fail_if(eo_class_name_get((Eo_Class*) buf));
eo_class_funcs_set((Eo_Class *) buf, NULL);
eo_class_do((Eo_Class *) buf, NULL);
eo_class_do_super((Eo_Class *) buf, EO_NOOP);
eo_class_do_super((Eo_Class *) buf, SIMPLE_CLASS, EO_NOOP);
eo_class_do_super(SIMPLE_CLASS, (Eo_Class *) buf, EO_NOOP);
fail_if(eo_class_new(NULL, (Eo_Class *) buf), NULL);