raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=b05110609b38b24f5a11b78bf9a92212da713ce3

commit b05110609b38b24f5a11b78bf9a92212da713ce3
Author: Marcel Hollerbach <[email protected]>
Date:   Fri Mar 20 11:32:44 2020 +0000

    eo: redo vtable mro creation
    
    Summary:
    up to now we have created the vtable of a class by walking the mro from
    the most upper element to the klass itself. To give a broader view, the
    mro of a klass X that extends the class Y and implements A,B,C,D
    
    The mro of X is then equal to [A,B,C,D] + the mro of Y. Which means, we
    can simply copy over the vtables of Y, and start walking at D, which
    will result in the same vtable.
    
    The sideeffect of doing that is, that we do not allocate that much
    memory anymore. Reason for this is quite simple:
    For every mixin that is part of the mro, we are copying the vtable node,
    to insert new API implemented by the mixin. However, the resulting new
    vtable is every time the same. Which means, we could actaully copy them.
    
    The same messurements as in the previous commits are taken:
    malloc tracking:
      new: 452128
      old: 556656
      Safeup: ~102 KB
    
    pmap:
      new: 542884K
      old: 542168K
      Safeup: ~716 KB
    Depends on D11538
    
    Reviewers: zmike, stefan_schmidt, tasn, raster, woohyun
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D11539
---
 src/lib/eo/eo.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index ae956a2149..83d3e5e752 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -920,17 +920,35 @@ efl_class_functions_set(const Efl_Class *klass_id, const 
Efl_Object_Ops *object_
 
    hitmap = alloca(klass->vtable.size);
    memset(hitmap, 0, klass->vtable.size);
-   /* Flatten the function array */
+   /* Merge in all required vtable entries */
      {
         const _Efl_Class **mro_itr = klass->mro;
-        for (  ; *mro_itr ; mro_itr++) ;
-
-        /* Skip ourselves. */
+        /* take over everything from the parent */
+        if (klass->parent)
+          {
+             _vtable_take_over(&klass->vtable, &klass->parent->vtable);
+          }
+        /*
+         * - jump to the mro entry containing the parent
+         * - everything further from the parent to the next elements is already
+         *   represented in the vtable of the parent.
+         */
+        for (  ; *mro_itr ; mro_itr++)
+          {
+             if (*mro_itr == klass->parent)
+               break;
+          }
+        /**
+         * merge in all the APIs that are extended in the current klass for 
this first time.
+         * That means, they are not extended anywhere from the parent further 
up.
+         */
         for ( mro_itr-- ; mro_itr > klass->mro ; mro_itr--)
           {
              _vtable_merge_defined_api(&klass->vtable, &(*mro_itr)->vtable, 
hitmap);
           }
-        /*add slots for the interfaces we are inheriting from*/
+        /*
+         * add slots for the interfaces and mixins we are inheriting from
+         */
         for (int i = 0; klass->extensions[i]; i++)
           {
              const _Efl_Class *ext = klass->extensions[i];

-- 


Reply via email to