From 79575d89430c0ceffd51d32b64e00d1708c90b44 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 17 May 2016 10:25:31 +0100 Subject: [PATCH] Eo children: Make children tracking an inlist instead of a list. This saves us a pointer in every eo object and a pointer indirection when accessing children. --- src/lib/eo/eo_base_class.c | 37 ++++++++++++++++++++------------- src/lib/eo/eo_private.h | 1 + src/lib/eo/eo_ptr_indirection.h | 20 ++++++++++++++++++ 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index 6492607b1c..75c0941e1b 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -26,9 +26,8 @@ typedef struct typedef struct { - Eina_List *children; + Eina_Inlist *children; Eo *parent; - Eina_List *parent_list; Eo_Base_Extension *ext; Eo_Callback_Description *callbacks; @@ -340,8 +339,8 @@ _ismultiglob(const char *match) EOLIAN static Eo_Base * _eo_base_id_find(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *search) { - Eina_List *l; Eo *child; + _Eo_Object *child_eo; const char *id, *p, *klass_name; // notes: @@ -389,8 +388,9 @@ _eo_base_id_find(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *search) // figure out if class or name are globs klass_glob = _hasglob(klass); name_glob = _hasglob(name); - EINA_LIST_FOREACH(pd->children, l, child) + EINA_INLIST_FOREACH(pd->children, child_eo) { + child = _eo_id_get(child_eo); id = eo_id_get(child); klass_name = eo_class_name_get(eo_class_get(child)); if (_idmatch(klass, klass_glob, klass_name) && @@ -406,8 +406,9 @@ _eo_base_id_find(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *search) if (_hasglob(search)) { // we have a glob - fnmatch - EINA_LIST_FOREACH(pd->children, l, child) + EINA_INLIST_FOREACH(pd->children, child_eo) { + child = _eo_id_get(child_eo); id = eo_id_get(child); if ((id) && (_idmatch(search, EINA_TRUE, id))) return child; @@ -418,8 +419,9 @@ _eo_base_id_find(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *search) else { // fast path for simple "name" - EINA_LIST_FOREACH(pd->children, l, child) + EINA_INLIST_FOREACH(pd->children, child_eo) { + child = _eo_id_get(child_eo); id = eo_id_get(child); if ((id) && (_idmatch(search, EINA_FALSE, id))) return child; @@ -478,6 +480,8 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id) if (pd->parent == parent_id) return; + EO_OBJ_POINTER(obj, eo_obj); + if (pd->parent) { Eo_Base_Data *old_parent_pd; @@ -485,9 +489,8 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id) old_parent_pd = eo_data_scope_get(pd->parent, EO_BASE_CLASS); if (old_parent_pd) { - old_parent_pd->children = eina_list_remove_list(old_parent_pd->children, - pd->parent_list); - pd->parent_list = NULL; + old_parent_pd->children = eina_inlist_remove(old_parent_pd->children, + EINA_INLIST_GET(eo_obj)); } else { @@ -511,8 +514,8 @@ _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id) if (EINA_LIKELY(parent_pd != NULL)) { pd->parent = parent_id; - parent_pd->children = eina_list_append(parent_pd->children, obj); - pd->parent_list = eina_list_last(parent_pd->children); + parent_pd->children = eina_inlist_append(parent_pd->children, + EINA_INLIST_GET(eo_obj)); } else { @@ -554,7 +557,7 @@ typedef struct _Eo_Children_Iterator Eo_Children_Iterator; struct _Eo_Children_Iterator { Eina_Iterator iterator; - Eina_List *current; + Eina_Inlist *current; _Eo_Object *obj; Eo *obj_id; }; @@ -564,8 +567,12 @@ _eo_children_iterator_next(Eo_Children_Iterator *it, void **data) { if (!it->current) return EINA_FALSE; - if (data) *data = eina_list_data_get(it->current); - it->current = eina_list_next(it->current); + if (data) + { + _Eo_Object *eo_obj = EINA_INLIST_CONTAINER_GET(it->current, _Eo_Object); + *data = _eo_id_get(eo_obj); + } + it->current = it->current->next; return EINA_TRUE; } @@ -1413,7 +1420,7 @@ _eo_base_destructor(Eo *obj, Eo_Base_Data *pd) // extra things like removes other children too later on in the list while (pd->children) { - child = eina_list_data_get(pd->children); + child = _eo_id_get(EINA_INLIST_CONTAINER_GET(pd->children, _Eo_Object)); eo_parent_set(child, NULL); } diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h index 10606f80d1..69c5dff26c 100644 --- a/src/lib/eo/eo_private.h +++ b/src/lib/eo/eo_private.h @@ -88,6 +88,7 @@ struct _Eo_Header struct _Eo_Object { Eo_Header header; + EINA_INLIST; const _Eo_Class *klass; #ifdef EO_DEBUG Eina_Inlist *xrefs; diff --git a/src/lib/eo/eo_ptr_indirection.h b/src/lib/eo/eo_ptr_indirection.h index f2b6f658d7..07ccc476d3 100644 --- a/src/lib/eo/eo_ptr_indirection.h +++ b/src/lib/eo/eo_ptr_indirection.h @@ -15,6 +15,16 @@ void _eo_pointer_error(const char *msg); #define _EO_POINTER_ERR(fmt, ptr) \ do { char buf[256]; sprintf(buf, fmt, ptr); _eo_pointer_error(buf); } while (0) +#define EO_OBJ_POINTER(obj_id, obj) \ + _Eo_Object *obj = NULL; \ + do { \ + if (!obj_id) break; \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!obj) { \ + _EO_POINTER_ERR("Obj (%p) is an invalid ref.", obj_id); \ + } \ + } while (0) + #define EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, ret) \ _Eo_Object *obj; \ do { \ @@ -61,6 +71,16 @@ void _eo_pointer_error(const char *msg); #else +#define EO_OBJ_POINTER(obj_id, obj) \ + _Eo_Object *obj = NULL; \ + do { \ + if (!obj_id) break; \ + obj = _eo_obj_pointer_get((Eo_Id)obj_id); \ + if (!EINA_MAGIC_CHECK((Eo_Header *) obj, EO_EINA_MAGIC)) { \ + EINA_MAGIC_FAIL((Eo_Header *) obj, EO_EINA_MAGIC); \ + } \ + } while (0) + #define EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, ret) \ _Eo_Object *obj; \ do { \