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. * @brief Calls the super function for the specific op.
* @param obj The object to work on * @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. * @param ... list of parameters.
* @return @c EINA_TRUE on success. * @return @c EINA_TRUE on success.
* *
@ -637,11 +638,12 @@ EAPI Eina_Bool eo_class_do_internal(const Eo_Class *klass, ...);
* *
* @see #eo_do * @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. * @brief Calls the super function for the specific op.
* @param klass The klass to work on * @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. * @param ... list of parameters.
* @return @c EINA_TRUE on success. * @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 * @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. * @brief Calls the super function for the specific op.
* @param obj The object to work on * @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_type The type of the ops that are passed.
* @param op The wanted op. * @param op The wanted op.
* @param ... list of parameters. * @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
* @see #eo_do_super * @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. * @brief Calls the super function for the specific op.
* @param klass The klass to work on * @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 op The wanted op.
* @param ... list of parameters. * @param ... list of parameters.
* @return @c EINA_TRUE on success. * @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
* @see #eo_class_do_super * @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. * @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_Class *_eo_op_class_get(Eo_Op op);
static const Eo_Op_Description *_eo_op_id_desc_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 { struct _Eo {
EINA_MAGIC EINA_MAGIC
EINA_INLIST; EINA_INLIST;
@ -44,8 +39,6 @@ struct _Eo {
Eina_List *composite_objects; Eina_List *composite_objects;
Eo_Kls_Itr mro_itr;
int refcount; int refcount;
Eina_Bool do_error:1; Eina_Bool do_error:1;
@ -106,7 +99,6 @@ struct _Eo_Class
Eo_Extension_Data_Offset *extn_data_off; Eo_Extension_Data_Offset *extn_data_off;
const Eo_Class **mro; const Eo_Class **mro;
Eo_Kls_Itr mro_itr;
unsigned int extn_data_size; unsigned int extn_data_size;
unsigned int chain_size; unsigned int chain_size;
@ -253,40 +245,14 @@ _eo_op_id_name_get(Eo_Op op)
return (desc) ? desc->name : NULL; 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 * static inline const Eo_Class *
_eo_kls_itr_get(Eo_Kls_Itr *cur) _eo_kls_itr_next(const Eo_Class *orig_kls, const Eo_Class *cur_klass, Eo_Op op)
{
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)
{ {
const Eo_Class **kls_itr = NULL; const Eo_Class **kls_itr = NULL;
memcpy(prev_state, cur, sizeof(*cur));
/* Find the kls itr. */ /* Find the kls itr. */
kls_itr = orig_kls->mro; kls_itr = orig_kls->mro;
while (*kls_itr && (*kls_itr != cur->kls)) while (*kls_itr && (*kls_itr != cur_klass))
kls_itr++; kls_itr++;
if (*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++; kls_itr++;
continue; continue;
} }
cur->kls = fsrc->src; return fsrc->src;
return cur->kls;
} }
} }
cur->kls = NULL;
return NULL; return NULL;
} }
static inline const op_type_funcs * 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) if (klass)
{ {
const op_type_funcs *func = _dich_func_get(klass, op); const op_type_funcs *func = _dich_func_get(klass, op);
if (func && func->func) if (func && func->func)
{ {
_eo_kls_itr_set(mro_itr, func->src);
return func; return func;
} }
} }
_eo_kls_itr_set(mro_itr, NULL);
return NULL; return NULL;
} }
@ -340,7 +302,7 @@ _eo_kls_itr_func_get(Eo_Kls_Itr *mro_itr, Eo_Op op)
while (0) while (0)
static Eina_Bool 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 #ifdef EO_DEBUG
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op); 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 #endif
{ {
const op_type_funcs *func = const op_type_funcs *func = _eo_kls_itr_func_get(cur_klass, op);
_eo_kls_itr_func_get(&obj->mro_itr, op);
if (EINA_LIKELY(func != NULL)) if (EINA_LIKELY(func != NULL))
{ {
void *func_data =_eo_data_get(obj, func->src); 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) EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj)
{ {
/* FIXME: Clean this up a bit. */ /* FIXME: Clean this up a bit. */
Eo_Kls_Itr prev_state; if (_eo_op_internal(emb_obj, emb_obj->klass, op_type, op, p_list))
_eo_kls_itr_init(emb_obj->klass, &emb_obj->mro_itr, &prev_state);
if (_eo_op_internal(emb_obj, op_type, op, p_list))
{ {
_eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
return EINA_TRUE; return EINA_TRUE;
} }
_eo_kls_itr_end(&emb_obj->mro_itr, &prev_state);
} }
} }
return EINA_FALSE; 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 prev_error;
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
Eo_Op op = EO_NOOP; Eo_Op op = EO_NOOP;
Eo_Kls_Itr prev_state;
prev_error = obj->do_error; prev_error = obj->do_error;
_eo_ref(obj); _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); op = va_arg(*p_list, Eo_Op);
while (op) while (op)
{ {
_eo_kls_itr_init(obj->klass, &obj->mro_itr, &prev_state); if (!_eo_op_internal(obj, obj->klass, op_type, op, p_list))
if (!_eo_op_internal(obj, op_type, op, p_list))
{ {
_EO_OP_ERR_NO_OP_PRINT(op, obj->klass); _EO_OP_ERR_NO_OP_PRINT(op, obj->klass);
ret = EINA_FALSE; ret = EINA_FALSE;
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
break; break;
} }
op = va_arg(*p_list, Eo_Op); op = va_arg(*p_list, Eo_Op);
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
} }
_eo_unref(obj); _eo_unref(obj);
@ -448,19 +401,19 @@ eo_vdo_internal(Eo *obj, Eo_Op_Type op_type, va_list *ops)
} }
EAPI Eina_Bool 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; const Eo_Class *nklass;
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
va_list p_list; va_list p_list;
Eo_Kls_Itr prev_state;
EO_MAGIC_RETURN_VAL(obj, EO_EINA_MAGIC, EINA_FALSE); 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. */ /* 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); 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); _EO_OP_ERR_NO_OP_PRINT(op, nklass);
ret = EINA_FALSE; 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) if (obj->do_error)
ret = EINA_FALSE; ret = EINA_FALSE;
_eo_kls_itr_end(&obj->mro_itr, &prev_state);
return ret; return ret;
} }
static Eina_Bool 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 #ifdef EO_DEBUG
const Eo_Op_Description *op_desc = _eo_op_id_desc_get(op); 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 #endif
{ {
const op_type_funcs *func = const op_type_funcs *func = _eo_kls_itr_func_get(cur_klass, op);
_eo_kls_itr_func_get(&klass->mro_itr, op);
if (func) if (func)
{ {
((eo_op_func_type_class) func->func)(klass, p_list); ((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; Eina_Bool ret = EINA_TRUE;
Eo_Op op = EO_NOOP; Eo_Op op = EO_NOOP;
Eo_Kls_Itr prev_state;
va_list p_list; va_list p_list;
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE); 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); op = va_arg(p_list, Eo_Op);
while (op) while (op)
{ {
_eo_kls_itr_init(klass, &((Eo_Class *) klass)->mro_itr, &prev_state); if (!_eo_class_op_internal((Eo_Class *) klass, klass, op, &p_list))
if (!_eo_class_op_internal((Eo_Class *) klass, op, &p_list))
{ {
_EO_OP_ERR_NO_OP_PRINT(op, klass); _EO_OP_ERR_NO_OP_PRINT(op, klass);
ret = EINA_FALSE; ret = EINA_FALSE;
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
break; break;
} }
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
op = va_arg(p_list, Eo_Op); op = va_arg(p_list, Eo_Op);
} }
@ -536,26 +483,25 @@ eo_class_do_internal(const Eo_Class *klass, ...)
} }
EAPI Eina_Bool 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; const Eo_Class *nklass;
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
va_list p_list; va_list p_list;
Eo_Kls_Itr prev_state;
EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, EINA_FALSE); 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. */ /* 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); 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); _EO_OP_ERR_NO_OP_PRINT(op, nklass);
ret = EINA_FALSE; ret = EINA_FALSE;
} }
va_end(p_list); va_end(p_list);
_eo_kls_itr_end(&((Eo_Class *) klass)->mro_itr, &prev_state);
return ret; return ret;
} }

View File

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