From 435dfe2a2a99f5e31921156d9e2361941924fc19 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Thu, 21 Feb 2008 18:48:36 +0000 Subject: [PATCH] Reduce memory allocation for edje match. Just allocate and build the match automate for callbacks and programs only when required. On load for programs and when callbacks list has been updated. Patch by Cedric BAIL. (with minor fixes to use TABS where context was using) SVN revision: 33804 --- legacy/edje/src/lib/edje_load.c | 9 ++++ legacy/edje/src/lib/edje_match.c | 74 +++++++++++------------------- legacy/edje/src/lib/edje_private.h | 18 +++++++- legacy/edje/src/lib/edje_program.c | 60 ++++++++++++------------ 4 files changed, 81 insertions(+), 80 deletions(-) diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index 4f6a285775..07ce36735f 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -410,6 +410,15 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p rp->text.text_source = ed->table_parts[rp->param1.description->text.id_text_source % ed->table_parts_size]; } } + + if (ed->patterns.programs.signals_patterns) + { + edje_match_patterns_free(ed->patterns.programs.signals_patterns); + edje_match_patterns_free(ed->patterns.programs.sources_patterns); + } + ed->patterns.programs.signals_patterns = edje_match_programs_signal_init(ed->collection->programs); + ed->patterns.programs.sources_patterns = edje_match_programs_source_init(ed->collection->programs); + n = evas_list_count(ed->collection->programs); if (n > 0) { diff --git a/legacy/edje/src/lib/edje_match.c b/legacy/edje/src/lib/edje_match.c index 640f8c41c1..80c40c1a3c 100644 --- a/legacy/edje/src/lib/edje_match.c +++ b/legacy/edje/src/lib/edje_match.c @@ -14,7 +14,6 @@ struct _Edje_State size_t pos; }; -typedef struct _Edje_States Edje_States; struct _Edje_States { size_t size; @@ -37,12 +36,13 @@ _edje_match_states_free(Edje_States *states, Size++; \ }; -static Edje_States* -_edje_match_states_alloc(size_t n, - size_t patterns_size, - size_t patterns_max_length) +static int +_edje_match_states_alloc(Edje_Patterns *ppat, int n) { - Edje_States *l; + Edje_States *l; + + const size_t patterns_size = ppat->patterns_size; + const size_t patterns_max_length = ppat->max_length; const size_t array_len = (patterns_max_length + 1) * patterns_size; @@ -69,8 +69,9 @@ _edje_match_states_alloc(size_t n, struct_size += states_has_size; l = malloc(n * struct_size); - if (!l) return NULL; + if (!l) return 0; + ppat->states = l; states = (unsigned char *) (l + n); has = states + states_size; @@ -82,7 +83,7 @@ _edje_match_states_alloc(size_t n, has += states_has_size; } - return l; + return 1; } static void @@ -295,6 +296,12 @@ _edje_match_patterns_exec_init_states(Edje_States *states, lst = evas_list_next(lst); \ } \ \ + if (!_edje_match_states_alloc(r, 2)) \ + { \ + free(r); \ + return NULL; \ + } \ + \ return r; \ } @@ -451,22 +458,16 @@ int edje_match_collection_dir_exec(const Edje_Patterns *ppat, const char *string) { - Edje_States *states = _edje_match_states_alloc(2, - ppat->patterns_size, - ppat->max_length); Edje_States *result; int r = 0; - if (!states) - return 0; - _edje_match_patterns_exec_init_states(states, ppat->patterns_size, ppat->max_length); + _edje_match_patterns_exec_init_states(ppat->states, ppat->patterns_size, ppat->max_length); - result = _edje_match_fn(ppat, string, states); + result = _edje_match_fn(ppat, string, ppat->states); if (result) r = _edje_match_collection_dir_exec_finals(ppat->finals, result); - _edje_match_states_free(states, 2); return r; } @@ -479,28 +480,19 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal, int (*func)(Edje_Program *pr, void *data), void *data) { - Edje_States *signal_states = _edje_match_states_alloc(2, - ppat_signal->patterns_size, - ppat_signal->max_length); - Edje_States *source_states = _edje_match_states_alloc(2, - ppat_source->patterns_size, - ppat_source->max_length); Edje_States *signal_result; Edje_States *source_result; int r = 0; - if (!signal_states || !source_states) - return 0; - - _edje_match_patterns_exec_init_states(signal_states, + _edje_match_patterns_exec_init_states(ppat_signal->states, ppat_signal->patterns_size, ppat_signal->max_length); - _edje_match_patterns_exec_init_states(source_states, + _edje_match_patterns_exec_init_states(ppat_source->states, ppat_source->patterns_size, ppat_source->max_length); - signal_result = _edje_match_fn(ppat_signal, signal, signal_states); - source_result = _edje_match_fn(ppat_source, source, source_states); + signal_result = _edje_match_fn(ppat_signal, signal, ppat_signal->states); + source_result = _edje_match_fn(ppat_source, source, ppat_source->states); if (signal_result && source_result) r = edje_match_programs_exec_check_finals(ppat_signal->finals, @@ -510,9 +502,6 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal, programs, func, data); - - _edje_match_states_free(source_states, 2); - _edje_match_states_free(signal_states, 2); return r; } @@ -524,28 +513,19 @@ edje_match_callback_exec(const Edje_Patterns *ppat_signal, Evas_List *callbacks, Edje *ed) { - Edje_States *signal_states = _edje_match_states_alloc(2, - ppat_signal->patterns_size, - ppat_signal->max_length); - Edje_States *source_states = _edje_match_states_alloc(2, - ppat_source->patterns_size, - ppat_source->max_length); Edje_States *signal_result; Edje_States *source_result; int r = 0; - if (!signal_states || !source_states) - return 0; - - _edje_match_patterns_exec_init_states(signal_states, + _edje_match_patterns_exec_init_states(ppat_signal->states, ppat_signal->patterns_size, ppat_signal->max_length); - _edje_match_patterns_exec_init_states(source_states, + _edje_match_patterns_exec_init_states(ppat_source->states, ppat_source->patterns_size, ppat_source->max_length); - signal_result = _edje_match_fn(ppat_signal, signal, signal_states); - source_result = _edje_match_fn(ppat_source, source, source_states); + signal_result = _edje_match_fn(ppat_signal, signal, ppat_signal->states); + source_result = _edje_match_fn(ppat_source, source, ppat_source->states); if (signal_result && source_result) r = edje_match_callback_exec_check_finals(ppat_signal->finals, @@ -556,15 +536,13 @@ edje_match_callback_exec(const Edje_Patterns *ppat_signal, source, callbacks, ed); - - _edje_match_states_free(source_states, 2); - _edje_match_states_free(signal_states, 2); return r; } void edje_match_patterns_free(Edje_Patterns *ppat) { + _edje_match_states_free(ppat->states, 2); free(ppat); } diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index edb9c33242..15c3f3c29e 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -122,6 +122,7 @@ typedef struct _Edje_Part Edje_Part; typedef struct _Edje_Part_Image_Id Edje_Part_Image_Id; typedef struct _Edje_Part_Description Edje_Part_Description; typedef struct _Edje_Spectrum_Color Edje_Spectrum_Color; +typedef struct _Edje_Patterns Edje_Patterns; #define PI 3.14159265358979323846 @@ -606,6 +607,17 @@ struct _Edje int table_programs_size; int table_parts_size; + struct { + struct { + Edje_Patterns *signals_patterns; + Edje_Patterns *sources_patterns; + } callbacks; + struct { + Edje_Patterns *signals_patterns; + Edje_Patterns *sources_patterns; + } programs; + } patterns; + int references; int block; int load_error; @@ -913,14 +925,16 @@ typedef enum _Edje_Match_Error } Edje_Match_Error; -typedef struct _Edje_Patterns Edje_Patterns; +typedef struct _Edje_States Edje_States; struct _Edje_Patterns { const char **patterns; + + Edje_States *states; + size_t patterns_size; size_t max_length; size_t finals[]; - }; Edje_Patterns *edje_match_collection_dir_init(Evas_List *lst); diff --git a/legacy/edje/src/lib/edje_program.c b/legacy/edje/src/lib/edje_program.c index ab5b5c74ff..2b4339aa7e 100644 --- a/legacy/edje/src/lib/edje_program.c +++ b/legacy/edje/src/lib/edje_program.c @@ -5,6 +5,7 @@ #include "edje_private.h" static void _edje_emit_cb(Edje *ed, const char *sig, const char *src); +static void _edje_clean_callbacks_patterns(Edje *ed); int _edje_anim_count = 0; Ecore_Animator *_edje_timer = NULL; @@ -105,6 +106,7 @@ edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const ch escb->just_added = 1; ed->just_added_callbacks = 1; } + _edje_clean_callbacks_patterns(ed); } /** Remove a callback from an object @@ -150,6 +152,8 @@ edje_object_signal_callback_del(Evas_Object *obj, const char *emission, const ch } else { + _edje_clean_callbacks_patterns(ed); + ed->callbacks = evas_list_remove_list(ed->callbacks, l); if (escb->signal) evas_stringshare_del(escb->signal); if (escb->source) evas_stringshare_del(escb->source); @@ -926,29 +930,16 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src) data.matched = 0; data.matches = NULL; #endif - Edje_Patterns *signals_patterns; - Edje_Patterns *sources_patterns; - if (ed->collection->programs) { - signals_patterns = edje_match_programs_signal_init(ed->collection->programs); - sources_patterns = edje_match_programs_source_init(ed->collection->programs); - - if (edje_match_programs_exec(signals_patterns, - sources_patterns, + if (edje_match_programs_exec(ed->patterns.programs.signals_patterns, + ed->patterns.programs.sources_patterns, sig, src, ed->collection->programs, _edje_glob_callback, &data) == 0) - { - edje_match_patterns_free(signals_patterns); - edje_match_patterns_free(sources_patterns); - goto break_prog; - } - - edje_match_patterns_free(signals_patterns); - edje_match_patterns_free(sources_patterns); + goto break_prog; } #ifdef EDJE_PROGRAM_CACHE @@ -979,8 +970,6 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src) static void _edje_emit_cb(Edje *ed, const char *sig, const char *src) { - Edje_Patterns *signals_patterns; - Edje_Patterns *sources_patterns; Evas_List *l; if (ed->delete_me) return; @@ -993,25 +982,21 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src) { int r; - signals_patterns = edje_match_callback_signal_init(ed->callbacks); - sources_patterns = edje_match_callback_source_init(ed->callbacks); + if (!ed->patterns.callbacks.signals_patterns) + { + ed->patterns.callbacks.signals_patterns = edje_match_callback_signal_init(ed->callbacks); + ed->patterns.callbacks.sources_patterns = edje_match_callback_source_init(ed->callbacks); + } - r = edje_match_callback_exec(signals_patterns, - sources_patterns, + r = edje_match_callback_exec(ed->patterns.callbacks.signals_patterns, + ed->patterns.callbacks.sources_patterns, sig, src, ed->callbacks, ed); if (!r) - { - edje_match_patterns_free(signals_patterns); - edje_match_patterns_free(sources_patterns); - goto break_prog; - } - - edje_match_patterns_free(signals_patterns); - edje_match_patterns_free(sources_patterns); + goto break_prog; } ed->walking_callbacks = 0; @@ -1030,6 +1015,8 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src) escb->just_added = 0; if (escb->delete_me) { + _edje_clean_callbacks_patterns(ed); + ed->callbacks = evas_list_remove_list(ed->callbacks, l); if (escb->signal) evas_stringshare_del(escb->signal); if (escb->source) evas_stringshare_del(escb->source); @@ -1043,3 +1030,16 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src) _edje_thaw(ed); _edje_unref(ed); } + +static void +_edje_clean_callbacks_patterns(Edje *ed) +{ + if (ed->patterns.callbacks.signals_patterns) + { + edje_match_patterns_free(ed->patterns.callbacks.signals_patterns); + edje_match_patterns_free(ed->patterns.callbacks.sources_patterns); + ed->patterns.callbacks.signals_patterns = NULL; + ed->patterns.callbacks.sources_patterns = NULL; + } +} +