forked from enlightenment/efl
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
This commit is contained in:
parent
44071e3102
commit
b05110609b
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue