From 83180acf2668d1992941a83329547e662b0369ba Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Wed, 13 Mar 2013 16:04:04 +0000 Subject: [PATCH] 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. --- src/lib/eo/Eo.h | 12 ++-- src/lib/eo/eo.c | 94 ++++++---------------------- src/tests/eo/suite/eo_test_general.c | 14 +++-- 3 files changed, 38 insertions(+), 82 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 867d26a13f..4b44505324 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -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. diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index c936f99ab0..d14920e518 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -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; } diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index d340907805..d6a4eec7de 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -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);