summaryrefslogtreecommitdiff
path: root/src/lib/eo
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-04-18 14:16:31 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-18 18:52:27 +0900
commit86d1f2b6cd25ca6359b6388ec9b1be268b5599bf (patch)
treecdcb0e2801454ce9a305dca420bca485733fb58e /src/lib/eo
parente8711baec3201bfe06be7da551e199b96a238c86 (diff)
eo: Use COW to save 8~16 bytes per object
Summary: This uses Eina_Cow to implement support for rarely used features in EO objects. This covers: - composite objects (eg. UI widgets: combobox, text, video, win) - vtable for efl_object_override - del_intercept All of these features are quite tricky to get right and while very useful, should still be used with great care. With this patch, the size of an _Eo_Object struct comes down from 80 bytes (rounded up from 72b) to 64 bytes (rounded up from 56b) on 64 bits. Also I haven't measured precisely but I don't expect any performance impact since the COW data is more likely to remain in L1/L2 cache, as the default one will be used most often. Unfortunately, the results of "make benchmark" have been quite inconsistent over multiple runs. This saves ~64kb in elementary_test (>4k objects) at the cost of ~100 calls to COW write (del intercept on some events). @optimization Reviewers: raster, cedric Differential Revision: https://phab.enlightenment.org/D4796
Diffstat (limited to 'src/lib/eo')
-rw-r--r--src/lib/eo/eo.c84
-rw-r--r--src/lib/eo/eo_base_class.c19
-rw-r--r--src/lib/eo/eo_private.h33
3 files changed, 87 insertions, 49 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 988487840e..ae06df74f0 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -71,6 +71,9 @@ static Efl_Object_Op _eo_ops_last_id = 0;
71static Eina_Hash *_ops_storage = NULL; 71static Eina_Hash *_ops_storage = NULL;
72static Eina_Spinlock _ops_storage_lock; 72static Eina_Spinlock _ops_storage_lock;
73 73
74static const Efl_Object_Optional efl_object_optional_cow_default = {};
75Eina_Cow *efl_object_optional_cow = NULL;
76
74static size_t _eo_sz = 0; 77static size_t _eo_sz = 0;
75static size_t _eo_class_sz = 0; 78static size_t _eo_class_sz = 0;
76 79
@@ -432,7 +435,7 @@ _efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Da
432 435
433 obj = _obj; 436 obj = _obj;
434 klass = _obj->klass; 437 klass = _obj->klass;
435 vtable = obj->vtable; 438 vtable = EO_VTABLE(obj);
436 439
437 if (_obj_is_override(obj) && cur_klass && 440 if (_obj_is_override(obj) && cur_klass &&
438 (_eo_class_id_get(cur_klass) == EFL_OBJECT_OVERRIDE_CLASS)) 441 (_eo_class_id_get(cur_klass) == EFL_OBJECT_OVERRIDE_CLASS))
@@ -536,12 +539,12 @@ end:
536 { 539 {
537 Eina_List *itr; 540 Eina_List *itr;
538 Eo *emb_obj_id; 541 Eo *emb_obj_id;
539 EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj_id) 542 EINA_LIST_FOREACH(obj->opt->composite_objects, itr, emb_obj_id)
540 { 543 {
541 EO_OBJ_POINTER_PROXY(emb_obj_id, emb_obj); 544 EO_OBJ_POINTER_PROXY(emb_obj_id, emb_obj);
542 if (EINA_UNLIKELY(!emb_obj)) continue; 545 if (EINA_UNLIKELY(!emb_obj)) continue;
543 546
544 func = _vtable_func_get(emb_obj->vtable, cache->op); 547 func = _vtable_func_get(EO_VTABLE(emb_obj), cache->op);
545 if (func == NULL) goto composite_continue; 548 if (func == NULL) goto composite_continue;
546 549
547 if (EINA_LIKELY(func->func && func->src)) 550 if (EINA_LIKELY(func->func && func->src))
@@ -833,9 +836,9 @@ _efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, E
833 } 836 }
834 eina_spinlock_release(&klass->objects.trash_lock); 837 eina_spinlock_release(&klass->objects.trash_lock);
835 838
839 obj->opt = eina_cow_alloc(efl_object_optional_cow);
836 obj->refcount++; 840 obj->refcount++;
837 obj->klass = klass; 841 obj->klass = klass;
838 obj->vtable = &klass->vtable;
839 842
840#ifndef HAVE_EO_ID 843#ifndef HAVE_EO_ID
841 EINA_MAGIC_SET((Eo_Header *) obj, EO_EINA_MAGIC); 844 EINA_MAGIC_SET((Eo_Header *) obj, EO_EINA_MAGIC);
@@ -966,7 +969,6 @@ efl_reuse(const Eo *_obj)
966 _efl_object_parent_sink_set(obj, EINA_FALSE); 969 _efl_object_parent_sink_set(obj, EINA_FALSE);
967} 970}
968 971
969
970void 972void
971_eo_free(_Eo_Object *obj, Eina_Bool manual_free EINA_UNUSED) 973_eo_free(_Eo_Object *obj, Eina_Bool manual_free EINA_UNUSED)
972{ 974{
@@ -1013,12 +1015,13 @@ _eo_free(_Eo_Object *obj, Eina_Bool manual_free EINA_UNUSED)
1013#endif 1015#endif
1014 if (_obj_is_override(obj)) 1016 if (_obj_is_override(obj))
1015 { 1017 {
1016 _vtable_func_clean_all(obj->vtable); 1018 _vtable_func_clean_all(obj->opt->vtable);
1017 eina_freeq_ptr_main_add(obj->vtable, free, 0); 1019 eina_freeq_ptr_main_add(obj->opt->vtable, free, 0);
1018 obj->vtable = &klass->vtable; 1020 EO_OPTIONAL_COW_SET(obj, vtable, NULL);
1019 } 1021 }
1020 1022
1021 _eo_id_release((Eo_Id) _eo_obj_id_get(obj)); 1023 _eo_id_release((Eo_Id) _eo_obj_id_get(obj));
1024 eina_cow_free(efl_object_optional_cow, (Eina_Cow_Data *) &obj->opt);
1022 1025
1023 eina_spinlock_take(&klass->objects.trash_lock); 1026 eina_spinlock_take(&klass->objects.trash_lock);
1024 if ((klass->objects.trash_count <= 8) && (EINA_LIKELY(!_eo_trash_bypass))) 1027 if ((klass->objects.trash_count <= 8) && (EINA_LIKELY(!_eo_trash_bypass)))
@@ -1576,44 +1579,45 @@ EAPI Eina_Bool
1576efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops) 1579efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
1577{ 1580{
1578 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE); 1581 EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
1579 EO_CLASS_POINTER_GOTO(EFL_OBJECT_OVERRIDE_CLASS, klass, err_done); 1582 EO_CLASS_POINTER_GOTO(EFL_OBJECT_OVERRIDE_CLASS, klass, err);
1580 Eo_Vtable *previous = obj->vtable;
1581 1583
1582 if (ops) 1584 if (ops)
1583 { 1585 {
1584 if (obj->vtable == &obj->klass->vtable) 1586 Eo_Vtable *vtable;
1587
1588 if (EINA_UNLIKELY(obj->opt->vtable != NULL))
1585 { 1589 {
1586 obj->vtable = calloc(1, sizeof(*obj->vtable)); 1590 ERR("Function table already overridden, not allowed to override again. "
1587 _vtable_init(obj->vtable, previous->size); 1591 "Call with NULL to reset the function table first.");
1588 _vtable_copy_all(obj->vtable, previous); 1592 goto err;
1589 // rare so move error handling to end to save l1 instruction cache
1590 if (!_eo_class_funcs_set(obj->vtable, ops, obj->klass,
1591 klass, 0, EINA_TRUE))
1592 goto err;
1593 goto done;
1594 } 1593 }
1595 // rare so move error handling to end to save l1 instruction cache 1594
1596 else goto err_already; 1595 vtable = calloc(1, sizeof(*vtable));
1596 _vtable_init(vtable, obj->klass->vtable.size);
1597 _vtable_copy_all(vtable, &obj->klass->vtable);
1598 if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, 0, EINA_TRUE))
1599 {
1600 // FIXME: Maybe leaking some chain stuff from copy above?
1601 ERR("Failed to override functions for %p", eo_id);
1602 free(vtable);
1603 goto err;
1604 }
1605
1606 EO_OPTIONAL_COW_SET(obj, vtable, vtable);
1597 } 1607 }
1598 else 1608 else
1599 { 1609 {
1600 if (obj->vtable != &obj->klass->vtable) 1610 if (obj->opt->vtable)
1601 { 1611 {
1602 eina_freeq_ptr_main_add(obj->vtable, free, 0); 1612 eina_freeq_ptr_main_add(obj->opt->vtable, free, 0);
1603 obj->vtable = (Eo_Vtable *) &obj->klass->vtable; 1613 EO_OPTIONAL_COW_SET(obj, vtable, NULL);
1604 } 1614 }
1605 } 1615 }
1606done: 1616
1607 EO_OBJ_DONE(eo_id); 1617 EO_OBJ_DONE(eo_id);
1608 return EINA_TRUE; 1618 return EINA_TRUE;
1609 1619
1610err_already:
1611 ERR("Function table already overridden, not allowed to override again. "
1612 "Call with NULL to reset the function table first.");
1613 goto err_done;
1614err: 1620err:
1615 ERR("Failed to override functions for %p", eo_id);
1616err_done:
1617 EO_OBJ_DONE(eo_id); 1621 EO_OBJ_DONE(eo_id);
1618 return EINA_FALSE; 1622 return EINA_FALSE;
1619} 1623}
@@ -1644,7 +1648,7 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
1644 EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj); 1648 EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj);
1645 EO_CLASS_POINTER_GOTO(klass_id, klass, err_class); 1649 EO_CLASS_POINTER_GOTO(klass_id, klass, err_class);
1646 const op_type_funcs *func = _vtable_func_get 1650 const op_type_funcs *func = _vtable_func_get
1647 (obj->vtable, klass->base_id + klass->ops_count); 1651 (EO_VTABLE(obj), klass->base_id + klass->ops_count);
1648 1652
1649 // Caching the result as we do a lot of serial efl_isa due to evas_object_image using it. 1653 // Caching the result as we do a lot of serial efl_isa due to evas_object_image using it.
1650 tdata->cache.isa_id = eo_id; 1654 tdata->cache.isa_id = eo_id;
@@ -1672,7 +1676,7 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
1672 EO_OBJ_POINTER_GOTO(eo_id, obj, err_shared_obj); 1676 EO_OBJ_POINTER_GOTO(eo_id, obj, err_shared_obj);
1673 EO_CLASS_POINTER_GOTO(klass_id, klass, err_shared_class); 1677 EO_CLASS_POINTER_GOTO(klass_id, klass, err_shared_class);
1674 const op_type_funcs *func = _vtable_func_get 1678 const op_type_funcs *func = _vtable_func_get
1675 (obj->vtable, klass->base_id + klass->ops_count); 1679 (EO_VTABLE(obj), klass->base_id + klass->ops_count);
1676 1680
1677 // Caching the result as we do a lot of serial efl_isa due to evas_object_image using it. 1681 // Caching the result as we do a lot of serial efl_isa due to evas_object_image using it.
1678 tdata->cache.isa_id = eo_id; 1682 tdata->cache.isa_id = eo_id;
@@ -1826,16 +1830,17 @@ EAPI void
1826efl_del_intercept_set(Eo *obj_id, Efl_Del_Intercept del_intercept_func) 1830efl_del_intercept_set(Eo *obj_id, Efl_Del_Intercept del_intercept_func)
1827{ 1831{
1828 EO_OBJ_POINTER_RETURN(obj_id, obj); 1832 EO_OBJ_POINTER_RETURN(obj_id, obj);
1829 obj->del_intercept = del_intercept_func; 1833 EO_OPTIONAL_COW_SET(obj, del_intercept, del_intercept_func);
1830 EO_OBJ_DONE(obj_id); 1834 EO_OBJ_DONE(obj_id);
1831} 1835}
1832 1836
1833EAPI Efl_Del_Intercept 1837EAPI Efl_Del_Intercept
1834efl_del_intercept_get(const Eo *obj_id) 1838efl_del_intercept_get(const Eo *obj_id)
1835{ 1839{
1836 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
1837 Efl_Del_Intercept func; 1840 Efl_Del_Intercept func;
1838 func = obj->del_intercept; 1841
1842 EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, NULL);
1843 func = obj->opt->del_intercept;
1839 EO_OBJ_DONE(obj_id); 1844 EO_OBJ_DONE(obj_id);
1840 return func; 1845 return func;
1841} 1846}
@@ -2148,6 +2153,10 @@ efl_object_init(void)
2148 _eo_class_isa_func(NULL, NULL); 2153 _eo_class_isa_func(NULL, NULL);
2149#endif 2154#endif
2150 2155
2156 efl_object_optional_cow =
2157 eina_cow_add("Efl Object Optional Data", sizeof(Efl_Object_Optional),
2158 64, &efl_object_optional_cow_default, EINA_TRUE);
2159
2151 _efl_add_fallback_init(); 2160 _efl_add_fallback_init();
2152 2161
2153 eina_log_timing(_eo_log_dom, 2162 eina_log_timing(_eo_log_dom,
@@ -2202,6 +2211,9 @@ efl_object_shutdown(void)
2202 _eo_table_data_shared_data = NULL; 2211 _eo_table_data_shared_data = NULL;
2203 } 2212 }
2204 2213
2214 eina_cow_del(efl_object_optional_cow);
2215 efl_object_optional_cow = NULL;
2216
2205 _eo_log_obj_shutdown(); 2217 _eo_log_obj_shutdown();
2206 2218
2207 eina_log_domain_unregister(_eo_log_dom); 2219 eina_log_domain_unregister(_eo_log_dom);
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index c6b4775b0a..f8a12c9505 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -1610,6 +1610,7 @@ _efl_object_event_global_freeze_count_get(Eo *klass EINA_UNUSED, void *pd EINA_U
1610EOLIAN static Eina_Bool 1610EOLIAN static Eina_Bool
1611_efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id) 1611_efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
1612{ 1612{
1613 Efl_Object_Optional *opt;
1613 Eo *emb_obj_id = NULL; 1614 Eo *emb_obj_id = NULL;
1614 1615
1615 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); 1616 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
@@ -1620,7 +1621,7 @@ _efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo
1620 /* Don't composite if we already have a composite object of this type */ 1621 /* Don't composite if we already have a composite object of this type */
1621 { 1622 {
1622 Eina_List *itr; 1623 Eina_List *itr;
1623 EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id) 1624 EINA_LIST_FOREACH(parent->opt->composite_objects, itr, emb_obj_id)
1624 { 1625 {
1625 EO_OBJ_POINTER_GOTO(emb_obj_id, emb_obj, err_klass); 1626 EO_OBJ_POINTER_GOTO(emb_obj_id, emb_obj, err_klass);
1626 if (EINA_UNLIKELY(emb_obj->klass == comp_obj->klass)) goto err_klass; 1627 if (EINA_UNLIKELY(emb_obj->klass == comp_obj->klass)) goto err_klass;
@@ -1637,7 +1638,9 @@ _efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo
1637 _efl_object_extension_need(comp_pd); 1638 _efl_object_extension_need(comp_pd);
1638 comp_pd->ext->composite_parent = parent_id; 1639 comp_pd->ext->composite_parent = parent_id;
1639 1640
1640 parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id); 1641 opt = EO_OPTIONAL_COW_WRITE(parent);
1642 opt->composite_objects = eina_list_prepend(opt->composite_objects, comp_obj_id);
1643 EO_OPTIONAL_COW_END(opt, parent);
1641 1644
1642 if (emb_obj_id) EO_OBJ_DONE(emb_obj_id); 1645 if (emb_obj_id) EO_OBJ_DONE(emb_obj_id);
1643 EO_OBJ_DONE(parent_id); 1646 EO_OBJ_DONE(parent_id);
@@ -1655,13 +1658,18 @@ err_parent:
1655EOLIAN static Eina_Bool 1658EOLIAN static Eina_Bool
1656_efl_object_composite_detach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id) 1659_efl_object_composite_detach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
1657{ 1660{
1661 Efl_Object_Optional *opt;
1662
1658 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE); 1663 EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
1659 EO_OBJ_POINTER_GOTO(parent_id, parent, err_parent); 1664 EO_OBJ_POINTER_GOTO(parent_id, parent, err_parent);
1660 1665
1661 // unlikely so improve l1 instr cache by using goto 1666 // unlikely so improve l1 instr cache by using goto
1662 if (!efl_composite_part_is(comp_obj_id)) goto err_part; 1667 if (!efl_composite_part_is(comp_obj_id)) goto err_part;
1663 1668
1664 parent->composite_objects = eina_list_remove(parent->composite_objects, comp_obj_id); 1669 opt = EO_OPTIONAL_COW_WRITE(parent);
1670 opt->composite_objects = eina_list_remove(opt->composite_objects, comp_obj_id);
1671 EO_OPTIONAL_COW_END(opt, parent);
1672
1665 /* Clear the comp parent on the child. */ 1673 /* Clear the comp parent on the child. */
1666 { 1674 {
1667 Efl_Object_Data *comp_pd = efl_data_scope_get(comp_obj_id, EFL_OBJECT_CLASS); 1675 Efl_Object_Data *comp_pd = efl_data_scope_get(comp_obj_id, EFL_OBJECT_CLASS);
@@ -1819,7 +1827,7 @@ children_back:
1819 { 1827 {
1820 EO_OBJ_POINTER_RETURN(obj, obj_data); 1828 EO_OBJ_POINTER_RETURN(obj, obj_data);
1821 obj_data2 = obj_data; 1829 obj_data2 = obj_data;
1822 if (obj_data->composite_objects) goto composite_obj; 1830 if (obj_data->opt->composite_objects) goto composite_obj;
1823composite_obj_back: 1831composite_obj_back:
1824 EO_OBJ_DONE(obj); 1832 EO_OBJ_DONE(obj);
1825 } 1833 }
@@ -1867,7 +1875,8 @@ composite_obj:
1867 { 1875 {
1868 Eina_List *itr, *next; 1876 Eina_List *itr, *next;
1869 Eo *emb_obj_id; 1877 Eo *emb_obj_id;
1870 EINA_LIST_FOREACH_SAFE(obj_data2->composite_objects, itr, next, emb_obj_id) 1878
1879 EINA_LIST_FOREACH_SAFE(obj_data2->opt->composite_objects, itr, next, emb_obj_id)
1871 { 1880 {
1872 efl_composite_detach(obj, emb_obj_id); 1881 efl_composite_detach(obj, emb_obj_id);
1873 } 1882 }
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 84974da7d5..e115451caa 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -60,6 +60,7 @@ extern int _eo_log_dom;
60typedef uintptr_t Eo_Id; 60typedef uintptr_t Eo_Id;
61typedef struct _Efl_Class _Efl_Class; 61typedef struct _Efl_Class _Efl_Class;
62typedef struct _Eo_Header Eo_Header; 62typedef struct _Eo_Header Eo_Header;
63typedef struct _Efl_Object_Optional Efl_Object_Optional;
63 64
64/* Allocates an entry for the given object */ 65/* Allocates an entry for the given object */
65static inline Eo_Id _eo_id_allocate(const _Eo_Object *obj, const Eo *parent_id); 66static inline Eo_Id _eo_id_allocate(const _Eo_Object *obj, const Eo *parent_id);
@@ -88,6 +89,13 @@ struct _Eo_Header
88 Eo_Id id; 89 Eo_Id id;
89}; 90};
90 91
92struct _Efl_Object_Optional
93{
94 Eo_Vtable *vtable;
95 Eina_List *composite_objects;
96 Efl_Del_Intercept del_intercept;
97};
98
91struct _Eo_Object 99struct _Eo_Object
92{ 100{
93 Eo_Header header; 101 Eo_Header header;
@@ -98,10 +106,7 @@ struct _Eo_Object
98 Eina_Inlist *data_xrefs; 106 Eina_Inlist *data_xrefs;
99#endif 107#endif
100 108
101 Eo_Vtable *vtable; 109 const Efl_Object_Optional *opt; // eina cow
102
103 Eina_List *composite_objects;
104 Efl_Del_Intercept del_intercept;
105 110
106 short refcount; 111 short refcount;
107 short user_refcount; 112 short user_refcount;
@@ -123,6 +128,18 @@ struct _Eo_Object
123#define DICH_CHAIN1(x) ((x) >> DICH_CHAIN_LAST_BITS) 128#define DICH_CHAIN1(x) ((x) >> DICH_CHAIN_LAST_BITS)
124#define DICH_CHAIN_LAST(x) ((x) & ((1 << DICH_CHAIN_LAST_BITS) - 1)) 129#define DICH_CHAIN_LAST(x) ((x) & ((1 << DICH_CHAIN_LAST_BITS) - 1))
125 130
131extern Eina_Cow *efl_object_optional_cow;
132#define EO_OPTIONAL_COW_WRITE(_obj) ({ Efl_Object_Optional *_cow = eina_cow_write(efl_object_optional_cow, (const Eina_Cow_Data**)&(_obj->opt)); _cow; })
133#define EO_OPTIONAL_COW_END(_cow, _obj) eina_cow_done(efl_object_optional_cow, (const Eina_Cow_Data**)&(_obj->opt), _cow, EINA_TRUE)
134#define EO_OPTIONAL_COW_SET(_obj, _field, _value) do { \
135 typeof (_value) _val = _value; \
136 if (_obj->opt->_field != _val) {\
137 Efl_Object_Optional *_obj##_cow = EO_OPTIONAL_COW_WRITE(_obj); \
138 _obj##_cow->_field = _val; \
139 EO_OPTIONAL_COW_END(_obj##_cow, _obj); \
140 }} while (0)
141#define EO_VTABLE(_obj) ((_obj)->opt->vtable ?: &((_obj)->klass->vtable))
142
126typedef void (*Eo_Op_Func_Type)(Eo *, void *class_data); 143typedef void (*Eo_Op_Func_Type)(Eo *, void *class_data);
127 144
128typedef struct 145typedef struct
@@ -257,7 +274,7 @@ _efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int
257 { 274 {
258 Eina_List *itr, *itr_n; 275 Eina_List *itr, *itr_n;
259 Eo *emb_obj; 276 Eo *emb_obj;
260 EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj) 277 EINA_LIST_FOREACH_SAFE(obj->opt->composite_objects, itr, itr_n, emb_obj)
261 { 278 {
262 efl_composite_detach(_eo_obj_id_get(obj), emb_obj); 279 efl_composite_detach(_eo_obj_id_get(obj), emb_obj);
263 } 280 }
@@ -270,7 +287,7 @@ _efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int
270static inline Eina_Bool 287static inline Eina_Bool
271_obj_is_override(_Eo_Object *obj) 288_obj_is_override(_Eo_Object *obj)
272{ 289{
273 return (obj->vtable != &obj->klass->vtable); 290 return obj->opt->vtable != NULL;
274} 291}
275 292
276void _eo_free(_Eo_Object *obj, Eina_Bool manual_free); 293void _eo_free(_Eo_Object *obj, Eina_Bool manual_free);
@@ -310,11 +327,11 @@ _efl_unref_internal(_Eo_Object *obj, const char *func_name, const char *file, in
310 return; 327 return;
311 } 328 }
312 329
313 if (obj->del_intercept) 330 if (obj->opt->del_intercept)
314 { 331 {
315 Eo *obj_id = _eo_obj_id_get(obj); 332 Eo *obj_id = _eo_obj_id_get(obj);
316 efl_ref(obj_id); 333 efl_ref(obj_id);
317 obj->del_intercept(obj_id); 334 obj->opt->del_intercept(obj_id);
318 return; 335 return;
319 } 336 }
320 337