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]; --
