Eo: Added cur_klass as a parameter to eo_*_do_super.
authorTom Hacohen <tom@stosb.com>
Wed, 13 Mar 2013 16:04:04 +0000 (16:04 +0000)
committerTom Hacohen <tom@stosb.com>
Mon, 18 Mar 2013 16:14:18 +0000 (16:14 +0000)
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
src/lib/eo/eo.c
src/tests/eo/suite/eo_test_general.c

index 867d26a..4b44505 100644 (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.
index c936f99..d14920e 100644 (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;
 }
 
index d340907..d6a4eec 100644 (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);