On Thursday 11 July 2013  19:11, Cedric BAIL wrote :
> On Thu, Jul 11, 2013 at 5:36 PM, Jérémy Zurcher <jer...@asynk.ch> wrote:
> > On Thursday 11 July 2013  03:28, Cedric BAIL wrote :
> >> On Wed, Jul 10, 2013 at 4:06 PM, Jérémy Zurcher <jer...@asynk.ch> wrote:
> >> > still not fully functional,
> >> >
> >> > here is the concept:
> >> >
> >> >   - enhance const Eo_Op_Description *descs; in  Eo_Class_Description 
> >> > into:
> >> >
> >> >   typedef struct _Eo_Op_Description
> >> >    {
> >> >       void *func;             /**< The static function to call for the 
> >> > op. */
> >> >       void *api_func;         /**< The EAPI function offering this op. */
> >> >       Eo_Op op;               /**< The op. */
> >> >       Eo_Op_Type op_type;     /**< The type of the Op. */
> >> >       const char *doc;        /**< Explanation about the Op. */
> >> >    }  Eo_Op_Description;
> >>
> >> Yeah, good idea to remove that second array.
> >>
> >> >   - remove the following from class declaration and definition
> >> >     _Eo_Op_Func_Description []
> >> >     BASE_ID = 0;
> >> >     enum { OP_ID,  ID_LAST };
> >> >     etc…
> >> >
> >> >   - but add
> >> >     static Eo_Class_Id class_id;
> >> >
> >> >   - on class elaboration:
> >> >     init class_id as BASE_ID was
> >> >     sort Eo_Op_Description by api_func, and set op (using base_op_id)
> >> >
> >> >   - now EO_FUNC_BODY can do:
> >> >      static volatile Eo_Op op = NOOP;
> >> >      if ( op == NOOP ) op = eo2_get_op_id(class_id, Name);
> >> >         -> search (Name==api_func) in class_id(_Eo_Op_Description)
> >> >
> >> >      then resolve the op given the calling object as usual
> >> >
> >> >    - overriding does not use EO_FUNC_BODY()
> >> >      but overrides *func in _Eo_Op_Description -> usual _dich stuff
> >> >
> >> >    so that's a little overhead on first call to resolve the OP
> >> >
> >> > Am I on the right thack ??
> >>
> >> Sounds like a good direction to follow. I would still like to expose
> >> the klass where the op is found in the object instead of directly
> >> doing eo2_call_resolve. This way we could add a hook before and after
> >> the function call to do tracing. It will also make it possible for all
> >> those functions to be pure const functions, this will help the
> >> compiler greatly I believe. Note a pure const function doesn't modify
> >> any of its parameter and the result is the same if the same data is
> >> given to them. Think strlen.
> 
> > function pointer and associated class are both int the Dich_Chain (what
> > does Dich Chain mean ??), for sure we don't want to do the lookup twice,
> > (but if the pure fct is optimized, why not?)
> 
> The problem is with eo2_call_resolve as it does modify the content of
> call and that make it not a pure function anymore in my understanding.
that's exactly what the theory says.
> That's why I want to split it, so that the compiler can merge and
> remove calls to eo2_call_resolve at the end. Well, in fact, I do hope
> that if the compiler is smart enough it will be able to move that
> evaluation outside of the loop and remove it from the hot path
> completely. That should be the case in the end for all call to eo2_do
> and give it an unfair advantage over eo_do.
> 
> > maybe we should expose op_type_funcs, but _Eo_Class is not public,
> > sometimes anoying that strict separation, I'll figure something out now.
> >
> > I'm _aware_ of pure fcts, what do you think about
> >    static Eo_Op op = EO_NOOP;
> >    if ( op == EO_NOOP ) op = eo2_get_op_id(OpDescs, (void*)Name);
> > vs
> >    op = eo2_get_op_id(OpDescs, (void*)Name);
> >
> > I wonder, I'll give a try all pure now!
> 
> Let's see that :-)
sadly it doesn't look to be smart enough or I missed something, see (out vs 
out-pure).

time to eat now!!
> --
> Cedric BAIL
> 
> ------------------------------------------------------------------------------
> See everything from the browser to the database with AppDynamics
> Get end-to-end visibility with application monitoring from AppDynamics
> Isolate bottlenecks and diagnose root cause in seconds.
> Start your free trial of AppDynamics Pro today!
> http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
> _______________________________________________
> enlightenment-devel mailing list
> enlightenment-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
--- Hell'O from Yverdoom

Jérémy (jeyzu)
gcc -O2
50 92
 EO : time      88 [ms]
 EO2: time      91 [ms]

clang -O2
50 92
 EO : time     119 [ms]
 EO2: time      86 [ms]

g++ -O2
Signal/Basic Tests: OK
Signal/CollectorVector: OK
Signal/CollectorUntil0: OK
Signal/CollectorWhile0: OK
Signal/Benchmark: Simple::Signal: OK
  Benchmark: Simple::Signal: 14.172239ns per emission (size=8): OK
Signal/Benchmark: callback loop: OK
  Benchmark: callback loop: 2.056402ns per round: OK
Signal/Benchmark: eo event: OK
  Benchmark: callback loop: 49.471638ns per round: OK
Signal/Benchmark: eo call: OK
  Benchmark: callback loop: 30.372430ns per round: OK
Signal/Benchmark: eo2 event: OK
  Benchmark: callback loop: 47.565633ns per round: OK
Signal/Benchmark: eo2 call: OK
  Benchmark: callback loop: 20.726474ns per round: OK
gcc -O2
50 92
 EO : time      88 [ms]
 EO2: time     127 [ms]

clang -O2
50 92
 EO : time     119 [ms]
 EO2: time     128 [ms]

g++ -O2
Signal/Basic Tests: OK
Signal/CollectorVector: OK
Signal/CollectorUntil0: OK
Signal/CollectorWhile0: OK
Signal/Benchmark: Simple::Signal: OK
  Benchmark: Simple::Signal: 8.665719ns per emission (size=8): OK
Signal/Benchmark: callback loop: OK
  Benchmark: callback loop: 2.410394ns per round: OK
Signal/Benchmark: eo event: OK
  Benchmark: callback loop: 48.747044ns per round: OK
Signal/Benchmark: eo call: OK
  Benchmark: callback loop: 30.351716ns per round: OK
Signal/Benchmark: eo2 event: OK
  Benchmark: callback loop: 48.880526ns per round: OK
Signal/Benchmark: eo2 call: OK
  Benchmark: callback loop: 27.798920ns per round: OK
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 5c45b98..0ba26c6 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -603,20 +603,20 @@ typedef struct _Eo2_Op_Call_Data
    void *data;
 } Eo2_Op_Call_Data;
 
-#define EO_FUNC_CALL() func(objid, call.data)
-#define EO_FUNC_CALLV(...) func(objid, call.data, __VA_ARGS__)
+#define EO_FUNC_CALL() func(objid, obj_data)
+#define EO_FUNC_CALLV(...) func(objid, obj_data, __VA_ARGS__)
 
 /* XXX: Essential, because we need to adjust objid for comp objects. */
 #define EO_FUNC_BODY(Name, Ret, Func, DefRet, OpDescs)                  \
   Ret                                                                   \
   Name(_Eo *obj, Eo *objid)                                             \
   {                                                                     \
-     static Eo_Op op = EO_NOOP;                                         \
-     if ( op == EO_NOOP ) op = eo2_get_op_id(OpDescs, (void*)Name);     \
      typedef Ret (*__##Name##_func)(Eo *, void *obj_data);              \
-     Eo2_Op_Call_Data call;                                             \
-     if (!eo2_call_resolve(obj, op, &call)) return DefRet;              \
-     __##Name##_func func = (__##Name##_func) call.func;                \
+     Eo_Op op = eo2_get_op_id(OpDescs, (void*)Name);                    \
+     __##Name##_func func = (__##Name##_func) eo2_func_get(obj, op);    \
+     if (!func) return DefRet;                                          \
+     const Eo_Class *klass_id= eo2_func_class_get(obj, op);             \
+     void* obj_data = eo2_data_scope_get(obj, klass_id);                \
      return Func;                                                       \
   }
 
@@ -624,12 +624,12 @@ typedef struct _Eo2_Op_Call_Data
   Ret                                                                   \
   Name(_Eo *obj, Eo *objid, __VA_ARGS__)                                \
   {                                                                     \
-     static Eo_Op op = EO_NOOP;                                         \
-     if ( op == EO_NOOP ) op = eo2_get_op_id(OpDescs, (void*)Name);     \
      typedef Ret (*__##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
-     Eo2_Op_Call_Data call;                                             \
-     if (!eo2_call_resolve(obj, op, &call)) return DefRet;              \
-     __##Name##_func func = (__##Name##_func) call.func;                \
+     Eo_Op op = eo2_get_op_id(OpDescs, (void*)Name);                    \
+     __##Name##_func func = (__##Name##_func) eo2_func_get(obj, op);    \
+     if (!func) return DefRet;                                          \
+     const Eo_Class *klass_id= eo2_func_class_get(obj, op);             \
+     void* obj_data = eo2_data_scope_get(obj, klass_id);                \
      return Func;                                                       \
   }
 
@@ -638,7 +638,15 @@ EAPI _Eo * eo2_do_start(Eo *obj_id);
 #define eo2_call_resolve(obj_id, op, call) eo2_call_resolve_internal(obj_id, NULL, op, call)
 EAPI Eina_Bool eo2_call_resolve_internal(_Eo *obj, const Eo_Class *klass, Eo_Op op, Eo2_Op_Call_Data *call);
 
-EAPI Eo_Op eo2_get_op_id(Eo2_Op_Description *op_descs, void *api_func);
+#define eo2_func_get(obj_id, op) eo2_func_get_internal(obj_id, NULL, op)
+EAPI const void* eo2_func_get_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op) EINA_PURE;
+
+#define eo2_func_class_get(obj_id, op) eo2_func_class_get_internal(obj_id, NULL, op)
+EAPI const Eo_Class* eo2_func_class_get_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op) EINA_PURE;
+
+EAPI Eo_Op eo2_get_op_id(Eo2_Op_Description *op_descs, void *api_func) EINA_PURE;
+
+EAPI void* eo2_data_scope_get(_Eo *obj, const Eo_Class *klass_id) EINA_PURE;
 
 #define OP_DESC_SIZE(desc) (sizeof(desc)/sizeof(Eo2_Op_Description) -1 )
 
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index f1b7adf..661fa73 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -282,6 +282,58 @@ eo2_call_resolve_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op, Eo2_Op_C
    return EINA_FALSE;
 }
 
+EAPI const void*
+eo2_func_get_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op)
+{
+   const _Eo_Class *klass;
+   const op_type_funcs *func;
+
+   if (klass_id)
+      klass = _eo_class_pointer_get(klass_id);
+   else
+      klass = obj->klass;
+
+   func = _eo_kls_itr_func_get(klass, op);
+   if (EINA_LIKELY(func != NULL))
+     {
+        return func->func;
+     }
+
+   /* Try composite objects */
+   /* FIXME!!! */
+   return NULL;
+}
+
+EAPI const Eo_Class*
+eo2_func_class_get_internal(_Eo *obj, const Eo_Class *klass_id, Eo_Op op)
+{
+   const _Eo_Class *klass;
+   const op_type_funcs *func;
+
+   if (klass_id)
+      klass = _eo_class_pointer_get(klass_id);
+   else
+      klass = obj->klass;
+
+   func = _eo_kls_itr_func_get(klass, op);
+   if (EINA_LIKELY(func != NULL))
+     {
+        return _eo_class_id_get(func->src);
+     }
+
+   /* Try composite objects */
+   /* FIXME!!! */
+   return NULL;
+}
+
+EAPI void *
+eo2_data_scope_get(_Eo *obj, const Eo_Class *klass_id)
+{
+   const _Eo_Class *klass = _eo_class_pointer_get(klass_id);
+
+   return _eo_data_scope_get(obj, klass);
+}
+
 
 EAPI Eo_Op
 eo2_get_op_id(Eo2_Op_Description *op_descs, void *api_func)
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to