summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2018-01-10 20:44:43 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2018-02-05 18:48:45 +0900
commitb2713c9287c83e7a3437e2bbdebf143665fd542b (patch)
treeabc3c745adc5f9134363006145d75aacac662295
parent26d73cbae1f28567673d5711e5dbbc964769aa67 (diff)
eo: Remove goto in _efl_object_destructor
EINA_LIKELY and EINA_UNLIKELY work as expected under GCC -O2. goto without EINA_UNLIKELY is completely useless as it will inline the goto'd segment of code. Clang produces different code though I suspect its optimized code isn't actually quite as good as GCC's (I saw a lot more nopw instructions). Anyway the C code is absolutely unreadable with those crazy goto. I really think we should remove all those goto, especially in Eo.h
-rw-r--r--src/lib/eo/eo_base_class.c91
1 files changed, 33 insertions, 58 deletions
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index a5295fa373..9ef4b4fe15 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -2028,38 +2028,44 @@ EOLIAN static void
2028_efl_object_destructor(Eo *obj, Efl_Object_Data *pd) 2028_efl_object_destructor(Eo *obj, Efl_Object_Data *pd)
2029{ 2029{
2030 Eo *child; 2030 Eo *child;
2031 Efl_Object_Extension *ext;
2032 _Eo_Object *obj_data2 = NULL;
2033 2031
2034 DBG("%p - %s.", obj, efl_class_name_get(obj)); 2032 DBG("%p - %s.", obj, efl_class_name_get(obj));
2035 2033
2036 // special removal - remove from children list by hand after getting 2034 // special removal - remove from children list by hand after getting
2037 // child handle in case unparent method is overridden and does 2035 // child handle in case unparent method is overridden and does
2038 // extra things like removes other children too later on in the list 2036 // extra things like removes other children too later on in the list
2039 // this is a goto because more often than not objects do not have children 2037 if (EINA_UNLIKELY(pd->children != NULL))
2040 // so it's unlikely they will need the child cleanup code to so to have 2038 {
2041 // better l1 cache instruction coherency, move this to the end 2039 while (pd->children)
2042 if (pd->children) goto children; 2040 {
2043children_back: 2041 child = _eo_obj_id_get(EINA_INLIST_CONTAINER_GET(pd->children, _Eo_Object));
2042 efl_parent_set(child, NULL);
2043 }
2044 }
2044 2045
2045 // If we are a composite object, detach children. it is quite unlikely 2046 // If we are a composite object, detach children.
2046 // we are a composite object, so put the core of this handling
2047 // at the end out of l1 cache prefetch
2048 { 2047 {
2049 EO_OBJ_POINTER_RETURN(obj, obj_data); 2048 EO_OBJ_POINTER_RETURN(obj, obj_data);
2050 obj_data2 = obj_data; 2049 if (EINA_UNLIKELY(obj_data->opt->composite_objects != NULL))
2051 if (obj_data->opt->composite_objects) goto composite_obj; 2050 {
2052composite_obj_back: 2051 Eina_List *itr, *next;
2052 Eo *emb_obj_id;
2053
2054 EINA_LIST_FOREACH_SAFE(obj_data->opt->composite_objects, itr, next, emb_obj_id)
2055 efl_composite_detach(obj, emb_obj_id);
2056 }
2053 EO_OBJ_DONE(obj); 2057 EO_OBJ_DONE(obj);
2054 } 2058 }
2055 2059
2056 if (pd->ext && pd->ext->composite_parent) 2060 if (pd->ext && pd->ext->composite_parent)
2057 efl_composite_detach(pd->ext->composite_parent, obj); 2061 efl_composite_detach(pd->ext->composite_parent, obj);
2058 2062
2059 // parent still being here is unlikely, so move error handling out of the 2063 if (EINA_UNLIKELY(pd->parent != NULL))
2060 // code execution path 2064 {
2061 if (pd->parent) goto err_parent; 2065 if (EINA_LIKELY(!pd->allow_parent_unref))
2062err_parent_back: 2066 ERR("Object '%p' still has a parent at the time of destruction.", obj);
2067 efl_parent_set(obj, NULL);
2068 }
2063 2069
2064 _efl_pending_futures_clear(pd); 2070 _efl_pending_futures_clear(pd);
2065 _wref_destruct(pd); 2071 _wref_destruct(pd);
@@ -2074,50 +2080,19 @@ err_parent_back:
2074 _eo_generic_data_del_all(obj, pd); 2080 _eo_generic_data_del_all(obj, pd);
2075 _eo_callback_remove_all(pd); 2081 _eo_callback_remove_all(pd);
2076 2082
2077 ext = pd->ext; 2083 if (EINA_UNLIKELY(pd->ext != NULL))
2078 // it is rather likely we dont have any extension section for most objects
2079 // so return immediately here to avoid pulling in more instructions to
2080 // the 1l cache if we can
2081 if (!ext)
2082 {
2083 _eo_condtor_done(obj);
2084 return;
2085 }
2086 eina_stringshare_del(ext->name);
2087 ext->name = NULL;
2088 eina_stringshare_del(ext->comment);
2089 ext->comment = NULL;
2090 while (pd->ext && ext->futures)
2091 efl_future_cancel(eina_list_data_get(ext->futures));
2092 _efl_object_extension_noneed(pd);
2093 _eo_condtor_done(obj);
2094 return;
2095
2096children:
2097 while (pd->children)
2098 {
2099 child = _eo_obj_id_get(EINA_INLIST_CONTAINER_GET(pd->children, _Eo_Object));
2100 efl_parent_set(child, NULL);
2101 }
2102 goto children_back;
2103
2104composite_obj:
2105 { 2084 {
2106 Eina_List *itr, *next; 2085 Efl_Object_Extension *ext = pd->ext;
2107 Eo *emb_obj_id; 2086 eina_stringshare_del(ext->name);
2108 2087 ext->name = NULL;
2109 EINA_LIST_FOREACH_SAFE(obj_data2->opt->composite_objects, itr, next, emb_obj_id) 2088 eina_stringshare_del(ext->comment);
2110 { 2089 ext->comment = NULL;
2111 efl_composite_detach(obj, emb_obj_id); 2090 while (pd->ext && ext->futures)
2112 } 2091 efl_future_cancel(eina_list_data_get(ext->futures));
2092 _efl_object_extension_noneed(pd);
2113 } 2093 }
2114 goto composite_obj_back;
2115 2094
2116err_parent: 2095 _eo_condtor_done(obj);
2117 if (EINA_LIKELY(!pd->allow_parent_unref))
2118 ERR("Object '%p' still has a parent at the time of destruction.", obj);
2119 efl_parent_set(obj, NULL);
2120 goto err_parent_back;
2121} 2096}
2122 2097
2123EOLIAN static void 2098EOLIAN static void