From 6a84ffbe5b476b6569d78e4a8216d25c90300cad Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Sun, 24 Apr 2016 14:38:02 +0900 Subject: [PATCH] eo base - optimize memory by extending extension memory so geneirc data, wrefs, comments and id's are not that common so put them all into their own memory segment that's allocated separately to the core object so we only use this memory when needed. we already had an extension section anyway so it's not new - just using it now for more of the rarer bits of data. 2 more pointers gone from most objects anyway and now extension code handling is a bit cleaner. --- src/lib/eo/eo_base_class.c | 356 +++++++++++++++++++++---------------- 1 file changed, 199 insertions(+), 157 deletions(-) diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index a525886ca6..7e3c4421cf 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -19,6 +19,8 @@ typedef struct { const char *id; const char *comment; + Eina_Inlist *generic_data; + Eo ***wrefs; } Eo_Base_Extension; typedef struct @@ -27,10 +29,7 @@ typedef struct Eo *parent; Eina_List *parent_list; - Eina_Inlist *generic_data; - Eo ***wrefs; - - Eo_Base_Extension *extension; + Eo_Base_Extension *ext; Eo_Callback_Description *callbacks; Eina_Inlist *current; @@ -56,19 +55,30 @@ typedef struct Eo_Callback_Description *current; } Eo_Current_Callback_Description; -static Eo_Base_Extension * -_eo_base_extension_new(void) +static inline void +_eo_base_extension_free(Eo_Base_Extension *ext) { - Eo_Base_Extension *extension = calloc(1, sizeof(Eo_Base_Extension)); - return extension; + free(ext); } -static void -_eo_base_extension_free(Eo_Base_Extension *extension) +static inline void +_eo_base_extension_need(Eo_Base_Data *pd) { - free(extension); + if (pd->ext) return; + pd->ext = calloc(1, sizeof(Eo_Base_Extension)); } +static inline void +_eo_base_extension_noneed(Eo_Base_Data *pd) +{ + Eo_Base_Extension *ext = pd->ext; + if ((!ext) || (ext->id) || (ext->comment) || (ext->generic_data) || + (ext->wrefs)) return; + _eo_base_extension_free(pd->ext); + pd->ext = NULL; +} + + static void @@ -87,13 +97,15 @@ _eo_base_cb_key_obj_del(void *data, const Eo_Event *event) if (pd) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (!ext) return EINA_TRUE; + EINA_INLIST_FOREACH(ext->generic_data, node) { if ((node->data_is_obj) && (node->data == event->obj)) { - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); + ext->generic_data = eina_inlist_remove + (ext->generic_data, EINA_INLIST_GET(node)); eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, _eo_base_cb_key_obj_del, data); _eo_generic_data_node_free(node); @@ -108,12 +120,14 @@ static void _eo_generic_data_del_all(Eo *obj, Eo_Base_Data *pd) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; - while (pd->generic_data) + if (!ext) return; + while (ext->generic_data) { - node = (Eo_Generic_Data_Node *)pd->generic_data; - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); + node = (Eo_Generic_Data_Node *)ext->generic_data; + ext->generic_data = eina_inlist_remove(ext->generic_data, + EINA_INLIST_GET(node)); if (node->data_is_obj) { eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, @@ -129,51 +143,62 @@ EOLIAN static void _eo_base_key_data_set(Eo *obj, Eo_Base_Data *pd, const char *key, const void *data) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (ext) { - if (!strcmp(node->key, key)) + EINA_INLIST_FOREACH(ext->generic_data, node) { - if ((!node->data_is_obj) && (!node->data_is_value) && - (node->data == data)) return; - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); - if (node->data_is_obj) + if (!strcmp(node->key, key)) { - eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, - _eo_base_cb_key_obj_del, obj); - eo_unref(node->data); + if ((!node->data_is_obj) && (!node->data_is_value) && + (node->data == data)) return; + ext->generic_data = eina_inlist_remove + (ext->generic_data, EINA_INLIST_GET(node)); + if (node->data_is_obj) + { + eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, + _eo_base_cb_key_obj_del, obj); + eo_unref(node->data); + } + else if (node->data_is_value) eina_value_free(node->data); + _eo_generic_data_node_free(node); + break; } - else if (node->data_is_value) eina_value_free(node->data); - _eo_generic_data_node_free(node); - break; } } - node = calloc(1, sizeof(Eo_Generic_Data_Node)); - if (!node) return; - node->key = eina_stringshare_add(key); - node->data = (void *)data; - node->data_is_obj = EINA_FALSE; - pd->generic_data = eina_inlist_prepend(pd->generic_data, - EINA_INLIST_GET(node)); + _eo_base_extension_need(pd); + ext = pd->ext; + if (ext) + { + node = calloc(1, sizeof(Eo_Generic_Data_Node)); + if (!node) return; + node->key = eina_stringshare_add(key); + node->data = (void *)data; + node->data_is_obj = EINA_FALSE; + ext->generic_data = eina_inlist_prepend + (ext->generic_data, EINA_INLIST_GET(node)); + } } EOLIAN static void * _eo_base_key_data_get(const Eo *obj, Eo_Base_Data *pd, const char *key) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return NULL; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (!ext) return NULL; + EINA_INLIST_FOREACH(ext->generic_data, node) { if (!strcmp(node->key, key)) { if ((!node->data_is_obj) && (!node->data_is_value)) { - pd->generic_data = eina_inlist_promote(pd->generic_data, - EINA_INLIST_GET(node)); + ext->generic_data = eina_inlist_promote + (ext->generic_data, EINA_INLIST_GET(node)); return node->data; } else @@ -191,14 +216,16 @@ EOLIAN static void _eo_base_key_del(Eo *obj, Eo_Base_Data *pd, const char *key) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (!ext) return; + EINA_INLIST_FOREACH(ext->generic_data, node) { if (!strcmp(node->key, key)) { - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); + ext->generic_data = eina_inlist_remove + (ext->generic_data, EINA_INLIST_GET(node)); if (node->data_is_obj) { eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, @@ -216,53 +243,64 @@ EOLIAN static void _eo_base_key_obj_set(Eo *obj, Eo_Base_Data *pd, const char *key, Eo *objdata) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (ext) { - if (!strcmp(node->key, key)) + EINA_INLIST_FOREACH(ext->generic_data, node) { - if ((node->data_is_obj) && (node->data == objdata)) return; - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); - if (node->data_is_obj) + if (!strcmp(node->key, key)) { - eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, - _eo_base_cb_key_obj_del, obj); - eo_unref(node->data); + if ((node->data_is_obj) && (node->data == objdata)) return; + ext->generic_data = eina_inlist_remove + (ext->generic_data, EINA_INLIST_GET(node)); + if (node->data_is_obj) + { + eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, + _eo_base_cb_key_obj_del, obj); + eo_unref(node->data); + } + else if (node->data_is_value) eina_value_free(node->data); + _eo_generic_data_node_free(node); + break; } - else if (node->data_is_value) eina_value_free(node->data); - _eo_generic_data_node_free(node); - break; } } - node = calloc(1, sizeof(Eo_Generic_Data_Node)); - if (!node) return; - node->key = eina_stringshare_add(key); - node->data = (void *)objdata; - node->data_is_obj = EINA_TRUE; - eo_event_callback_add(node->data, EO_BASE_EVENT_DEL, - _eo_base_cb_key_obj_del, obj); - eo_ref(node->data); - pd->generic_data = eina_inlist_prepend(pd->generic_data, - EINA_INLIST_GET(node)); + _eo_base_extension_need(pd); + ext = pd->ext; + if (ext) + { + node = calloc(1, sizeof(Eo_Generic_Data_Node)); + if (!node) return; + node->key = eina_stringshare_add(key); + node->data = (void *)objdata; + node->data_is_obj = EINA_TRUE; + eo_event_callback_add(node->data, EO_BASE_EVENT_DEL, + _eo_base_cb_key_obj_del, obj); + eo_ref(node->data); + ext->generic_data = eina_inlist_prepend + (ext->generic_data, EINA_INLIST_GET(node)); + } } EOLIAN static Eo * _eo_base_key_obj_get(const Eo *obj, Eo_Base_Data *pd, const char *key) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return NULL; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (!ext) return NULL; + EINA_INLIST_FOREACH(ext->generic_data, node) { if (!strcmp(node->key, key)) { if (node->data_is_obj) { - pd->generic_data = eina_inlist_promote(pd->generic_data, - EINA_INLIST_GET(node)); + ext->generic_data = eina_inlist_promote + (ext->generic_data, EINA_INLIST_GET(node)); return node->data; } else @@ -280,52 +318,63 @@ EOLIAN static void _eo_base_key_value_set(Eo *obj, Eo_Base_Data *pd, const char *key, Eina_Value *value) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (ext) { - if (!strcmp(node->key, key)) + EINA_INLIST_FOREACH(ext->generic_data, node) { - if ((node->data_is_value) && (node->data == value)) return; - pd->generic_data = eina_inlist_remove(pd->generic_data, - EINA_INLIST_GET(node)); - if (node->data_is_obj) + if (!strcmp(node->key, key)) { - eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, - _eo_base_cb_key_obj_del, obj); - eo_unref(node->data); + if ((node->data_is_value) && (node->data == value)) return; + ext->generic_data = eina_inlist_remove + (ext->generic_data, EINA_INLIST_GET(node)); + if (node->data_is_obj) + { + eo_event_callback_del(node->data, EO_BASE_EVENT_DEL, + _eo_base_cb_key_obj_del, obj); + eo_unref(node->data); + } + else if (node->data_is_value) eina_value_free(node->data); + _eo_generic_data_node_free(node); + break; } - else if (node->data_is_value) eina_value_free(node->data); - _eo_generic_data_node_free(node); - break; } } - node = calloc(1, sizeof(Eo_Generic_Data_Node)); - if (!node) return; - node->key = eina_stringshare_add(key); - node->data = (void *)value; - node->data_is_value = EINA_TRUE; - eo_event_callback_add(node->data, EO_BASE_EVENT_DEL, - _eo_base_cb_key_obj_del, obj); - pd->generic_data = eina_inlist_prepend(pd->generic_data, - EINA_INLIST_GET(node)); + _eo_base_extension_need(pd); + ext = pd->ext; + if (ext) + { + node = calloc(1, sizeof(Eo_Generic_Data_Node)); + if (!node) return; + node->key = eina_stringshare_add(key); + node->data = (void *)value; + node->data_is_value = EINA_TRUE; + eo_event_callback_add(node->data, EO_BASE_EVENT_DEL, + _eo_base_cb_key_obj_del, obj); + ext->generic_data = eina_inlist_prepend + (ext->generic_data, EINA_INLIST_GET(node)); + } } EOLIAN static Eina_Value * _eo_base_key_value_get(const Eo *obj, Eo_Base_Data *pd, const char *key) { Eo_Generic_Data_Node *node; + Eo_Base_Extension *ext = pd->ext; if (!key) return NULL; - EINA_INLIST_FOREACH(pd->generic_data, node) + if (!ext) return NULL; + EINA_INLIST_FOREACH(ext->generic_data, node) { if (!strcmp(node->key, key)) { if (node->data_is_value) { - pd->generic_data = eina_inlist_promote(pd->generic_data, - EINA_INLIST_GET(node)); + ext->generic_data = eina_inlist_promote + (ext->generic_data, EINA_INLIST_GET(node)); return node->data; } else @@ -345,22 +394,16 @@ _eo_base_id_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *id) if ((id) && (!id[0])) id = NULL; if (id) { - if (!pd->extension) - pd->extension = _eo_base_extension_new(); - if (pd->extension) - eina_stringshare_replace(&(pd->extension->id), id); + _eo_base_extension_need(pd); + if (pd->ext) eina_stringshare_replace(&(pd->ext->id), id); } else { - if (!pd->extension) return; - if (pd->extension->id) + if (!pd->ext) return; + if (pd->ext->id) { - eina_stringshare_replace(&(pd->extension->id), id); - if (!pd->extension->comment) - { - _eo_base_extension_free(pd->extension); - pd->extension = NULL; - } + eina_stringshare_replace(&(pd->ext->id), id); + _eo_base_extension_noneed(pd); } } } @@ -368,8 +411,8 @@ _eo_base_id_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *id) EOLIAN static const char * _eo_base_id_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd) { - if (!pd->extension) return NULL; - return pd->extension->id; + if (!pd->ext) return NULL; + return pd->ext->id; } static inline Eina_Bool @@ -530,22 +573,16 @@ _eo_base_comment_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *comment) if ((comment) && (!comment[0])) comment = NULL; if (comment) { - if (!pd->extension) - pd->extension = _eo_base_extension_new(); - if (pd->extension) - eina_stringshare_replace(&(pd->extension->comment), comment); + _eo_base_extension_need(pd); + if (pd->ext) eina_stringshare_replace(&(pd->ext->comment), comment); } else { - if (!pd->extension) return; - if (pd->extension->comment) + if (!pd->ext) return; + if (pd->ext->comment) { - eina_stringshare_replace(&(pd->extension->comment), comment); - if (!pd->extension->id) - { - _eo_base_extension_free(pd->extension); - pd->extension = NULL; - } + eina_stringshare_replace(&(pd->ext->comment), comment); + _eo_base_extension_noneed(pd); } } } @@ -553,8 +590,8 @@ _eo_base_comment_set(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *comment) EOLIAN static const char * _eo_base_comment_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd) { - if (!pd->extension) return NULL; - return pd->extension->comment; + if (!pd->ext) return NULL; + return pd->ext->comment; } @@ -740,13 +777,12 @@ _eo_base_dbg_info_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd EINA_UNUSED, Eo_Dbg_ static inline size_t _wref_count(Eo_Base_Data *pd) { - size_t count = 0; - if (!pd->wrefs) - return 0; - Eo ***itr; - for (itr = pd->wrefs; *itr; itr++) - count++; + size_t count = 0; + Eo_Base_Extension *ext = pd->ext; + + if ((!ext) || (!ext->wrefs)) return 0; + for (itr = ext->wrefs; *itr; itr++) count++; return count; } @@ -756,16 +792,21 @@ _eo_base_wref_add(Eo *obj, Eo_Base_Data *pd, Eo **wref) { size_t count; Eo ***tmp; + Eo_Base_Extension *ext; count = _wref_count(pd); count += 1; /* New wref. */ - tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * (count + 1)); - if (!tmp) return; - pd->wrefs = tmp; + _eo_base_extension_need(pd); + ext = pd->ext; + if (!ext) return; - pd->wrefs[count - 1] = wref; - pd->wrefs[count] = NULL; + tmp = realloc(ext->wrefs, sizeof(*ext->wrefs) * (count + 1)); + if (!tmp) return; + ext->wrefs = tmp; + + ext->wrefs[count - 1] = wref; + ext->wrefs[count] = NULL; *wref = obj; } @@ -773,15 +814,16 @@ EOLIAN static void _eo_base_wref_del(Eo *obj, Eo_Base_Data *pd, Eo **wref) { size_t count; + Eo_Base_Extension *ext = pd->ext; if (*wref != obj) { ERR("Wref is a weak ref to %p, while this function was called on %p.", - *wref, obj); + *wref, obj); return; } - if (!pd->wrefs) + if ((!ext) || (!ext->wrefs)) { ERR("There are no weak refs for object %p", obj); *wref = NULL; @@ -793,11 +835,11 @@ _eo_base_wref_del(Eo *obj, Eo_Base_Data *pd, Eo **wref) { Eo ***itr; - for (itr = pd->wrefs; *itr; itr++) + for (itr = ext->wrefs; *itr; itr++) { if (*itr == wref) { - *itr = pd->wrefs[count - 1]; + *itr = ext->wrefs[count - 1]; break; } } @@ -813,16 +855,17 @@ _eo_base_wref_del(Eo *obj, Eo_Base_Data *pd, Eo **wref) if (count > 1) { Eo ***tmp; - // No count--; because of the NULL that is not included in the count. */ - tmp = realloc(pd->wrefs, sizeof(*pd->wrefs) * count); + // No count--; because of the NULL that is not included in the count + tmp = realloc(ext->wrefs, sizeof(*ext->wrefs) * count); if (!tmp) return; - pd->wrefs = tmp; - pd->wrefs[count - 1] = NULL; + ext->wrefs = tmp; + ext->wrefs[count - 1] = NULL; } else { - free(pd->wrefs); - pd->wrefs = NULL; + free(ext->wrefs); + ext->wrefs = NULL; + _eo_base_extension_noneed(pd); } *wref = NULL; @@ -832,15 +875,12 @@ static inline void _wref_destruct(Eo_Base_Data *pd) { Eo ***itr; - if (!pd->wrefs) - return; + Eo_Base_Extension *ext = pd->ext; - for (itr = pd->wrefs; *itr; itr++) - { - **itr = NULL; - } - - free(pd->wrefs); + if ((!ext) || (!ext->wrefs)) return; + for (itr = ext->wrefs; *itr; itr++) **itr = NULL; + free(ext->wrefs); + ext->wrefs = NULL; } /* EOF Weak reference. */ @@ -1478,6 +1518,7 @@ EOLIAN static void _eo_base_destructor(Eo *obj, Eo_Base_Data *pd) { Eo *child; + Eo_Base_Extension *ext; DBG("%p - %s.", obj, eo_class_name_get(obj)); @@ -1501,14 +1542,15 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data *pd) _wref_destruct(pd); _eo_callback_remove_all(pd); - if (pd->extension) + ext = pd->ext; + if (ext) { - eina_stringshare_del(pd->extension->id); - pd->extension->id = NULL; - eina_stringshare_del(pd->extension->comment); - pd->extension->comment = NULL; - _eo_base_extension_free(pd->extension); - pd->extension = NULL; + eina_stringshare_del(ext->id); + ext->id = NULL; + eina_stringshare_del(ext->comment); + ext->comment = NULL; + _eo_base_extension_free(ext); + pd->ext = NULL; } _eo_condtor_done(obj);