diff options
author | Jérémy Zurcher <jeremy@asynk.ch> | 2013-12-30 15:24:15 +0100 |
---|---|---|
committer | Jérémy Zurcher <jeremy@asynk.ch> | 2014-01-03 16:22:21 +0100 |
commit | 77bd3ce6c678066164126251f93f2053ea599aea (patch) | |
tree | 7771401c8b158361dbff521b0e4e1f302d1d0673 | |
parent | 0bb069a31dce42ccc50be23a0b98340371c94243 (diff) | |
download | efl-77bd3ce6c678066164126251f93f2053ea599aea.tar.gz |
eo2: call stack grows and shrinks
-rw-r--r-- | src/lib/eo/eo.c | 70 |
1 files changed, 56 insertions, 14 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index ca9eee8b48..86a648e3ea 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -268,9 +268,9 @@ _eo_kls_itr_func_get(const _Eo_Class *cur_klass, Eo_Op op) EAPI Eo2_Hook_Call eo2_hook_call_pre = NULL; EAPI Eo2_Hook_Call eo2_hook_call_post = NULL; -// FIXME: per thread stack, grow/shrink +// FIXME: Thread Local Storage #define EO2_INVALID_DATA (void *) -1 -#define EO2_CALL_STACK_DEPTH 100 +#define EO2_CALL_STACK_DEPTH 30 typedef struct _Eo2_Stack_Frame { @@ -286,9 +286,11 @@ typedef struct _Eo2_Stack_Frame typedef struct _Eo2_Call_Stack { Eo2_Stack_Frame *stack; Eo2_Stack_Frame *frame_ptr; + Eo2_Stack_Frame *last_frame; + Eo2_Stack_Frame *shrink_frame; } Eo2_Call_Stack; -static Eo2_Call_Stack eo2_call_stack = { NULL, NULL }; +static Eo2_Call_Stack eo2_call_stack = { NULL, NULL, NULL, NULL }; static Eina_Bool _eo2_call_stack_init() @@ -298,7 +300,9 @@ _eo2_call_stack_init() return EINA_FALSE; // first frame is never used - eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0]; + eo2_call_stack.frame_ptr = eo2_call_stack.stack; + eo2_call_stack.last_frame = &eo2_call_stack.stack[EO2_CALL_STACK_DEPTH - 1]; + eo2_call_stack.shrink_frame = eo2_call_stack.stack; return EINA_TRUE; } @@ -310,6 +314,40 @@ _eo2_call_stack_free() free(eo2_call_stack.stack); } + +static inline void +_eo2_call_stack_resize(Eina_Bool grow) +{ + size_t sz, next_sz; + int frame_offset; + + frame_offset = eo2_call_stack.frame_ptr - eo2_call_stack.stack; + sz = eo2_call_stack.last_frame - eo2_call_stack.stack + 1; + if (grow) + next_sz = sz << 1; + else + next_sz = sz >> 1; + + DBG("resize from %lu to %lu", sz, next_sz); + eo2_call_stack.stack = realloc(eo2_call_stack.stack, next_sz * sizeof(Eo2_Stack_Frame)); + if(!eo2_call_stack.stack) + { + CRI("unable to resize call stack, abort."); + abort(); + } + + eo2_call_stack.frame_ptr = &eo2_call_stack.stack[frame_offset]; + eo2_call_stack.last_frame = &eo2_call_stack.stack[next_sz - 1]; + + if (grow) + frame_offset = (sz >> 1); + if (next_sz == EO2_CALL_STACK_DEPTH) + frame_offset = 0; + else + frame_offset = (next_sz >> 1); + eo2_call_stack.shrink_frame = &eo2_call_stack.stack[frame_offset]; +} + static inline Eina_Bool _eo2_do_internal(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, Eo2_Stack_Frame *fptr, Eo2_Stack_Frame *pfptr) @@ -345,18 +383,16 @@ _eo2_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, { Eo2_Stack_Frame *fptr, *pfptr; + if (eo2_call_stack.frame_ptr == eo2_call_stack.last_frame) + _eo2_call_stack_resize(EINA_TRUE); + fptr = eo2_call_stack.frame_ptr; - if (((fptr - eo2_call_stack.stack) + 1) >= EO2_CALL_STACK_DEPTH) - { - ERR("eo2 call stack overflow !!!"); - return EINA_FALSE; - } pfptr = ((eo_id) && (fptr->eo_id == eo_id) ? fptr : NULL); fptr++; if (!_eo2_do_internal(eo_id, cur_klass_id, is_super, fptr, pfptr)) - return EINA_FALSE; + return EINA_FALSE; if(_eo_is_a_class(eo_id)) { @@ -388,10 +424,16 @@ _eo2_do_end(const Eo **eo_id EINA_UNUSED) memset(fptr, 0, sizeof (Eo2_Stack_Frame)); fptr->obj_data = EO2_INVALID_DATA; - if (fptr == &eo2_call_stack.stack[0]) - ERR("eo2 call stack underflow !!!"); - else - eo2_call_stack.frame_ptr--; + if (fptr == eo2_call_stack.stack) + { + CRI("call stack underflow, abort."); + abort(); + } + + eo2_call_stack.frame_ptr--; + + if (fptr == eo2_call_stack.shrink_frame) + _eo2_call_stack_resize(EINA_FALSE); } EAPI Eina_Bool |