eo: redo vtable mro creation

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

Differential Revision: https://phab.enlightenment.org/D11539
This commit is contained in:
Marcel Hollerbach 2020-03-18 21:41:29 +01:00
parent 228aacf593
commit 79d9b20aab
1 changed files with 23 additions and 5 deletions

View File

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