summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-10-21 22:23:18 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-10-21 22:23:18 +0900
commit9ef9f2deb8b09eba0c6a432072dd0bb30abe2e87 (patch)
treef6824708007e73096ca90dd8b950dd2bd33e73fc
parentb1fa1c5aadc71881cb1e4e264d680ea5efa79a69 (diff)
eo resolv cache - remove params passed to resolv func for efficiency
we pass both the callcache and the op id - both are static and filled in at runtime, so merge them into the same struct. this should lead to better alignment/padding with the offset array and the next slot and op fields, probably saving about 4-8 bytes of rame per method with no downsides. also pass in only cache ptr, not both cache ptr and opid - less passing of stuff around and should be better.
-rw-r--r--src/lib/eo/Eo.h18
-rw-r--r--src/lib/eo/eo.c41
2 files changed, 30 insertions, 29 deletions
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 6f5e4bd425..38b60c2531 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -460,12 +460,15 @@ typedef struct _Eo_Call_Cache_Off
460 460
461typedef struct _Eo_Call_Cache 461typedef struct _Eo_Call_Cache
462{ 462{
463#if EO_CALL_CACHE_SIZE > 0
463 Eo_Call_Cache_Index index[EO_CALL_CACHE_SIZE]; 464 Eo_Call_Cache_Index index[EO_CALL_CACHE_SIZE];
464 Eo_Call_Cache_Entry entry[EO_CALL_CACHE_SIZE]; 465 Eo_Call_Cache_Entry entry[EO_CALL_CACHE_SIZE];
465 Eo_Call_Cache_Off off [EO_CALL_CACHE_SIZE]; 466 Eo_Call_Cache_Off off [EO_CALL_CACHE_SIZE];
466#if EO_CALL_CACHE_SIZE > 1 467# if EO_CALL_CACHE_SIZE > 1
467 int next_slot; 468 int next_slot;
469# endif
468#endif 470#endif
471 Eo_Op op;
469} Eo_Call_Cache; 472} Eo_Call_Cache;
470 473
471// to pass the internal function call to EO_FUNC_BODY (as Func parameter) 474// to pass the internal function call to EO_FUNC_BODY (as Func parameter)
@@ -479,12 +482,11 @@ typedef struct _Eo_Call_Cache
479 482
480// cache OP id, get real fct and object data then do the call 483// cache OP id, get real fct and object data then do the call
481#define EO_FUNC_COMMON_OP(Name, DefRet) \ 484#define EO_FUNC_COMMON_OP(Name, DefRet) \
482 static Eo_Call_Cache ___callcache; /* static 0 by default */ \ 485 static Eo_Call_Cache ___cache; /* static 0 by default */ \
483 static Eo_Op ___op; /* static 0 by default */ \
484 Eo_Op_Call_Data ___call; \ 486 Eo_Op_Call_Data ___call; \
485 if (___op == EO_NOOP) \ 487 if (___cache.op == EO_NOOP) \
486 ___op = _eo_api_op_id_get(EO_FUNC_COMMON_OP_FUNC(Name)); \ 488 ___cache.op = _eo_api_op_id_get(EO_FUNC_COMMON_OP_FUNC(Name)); \
487 if (!_eo_call_resolve(#Name, ___op, &___call, &___callcache, \ 489 if (!_eo_call_resolve(#Name, &___call, &___cache, \
488 __FILE__, __LINE__)) return DefRet; \ 490 __FILE__, __LINE__)) return DefRet; \
489 _Eo_##Name##_func _func_ = (_Eo_##Name##_func) ___call.func; \ 491 _Eo_##Name##_func _func_ = (_Eo_##Name##_func) ___call.func; \
490 492
@@ -544,7 +546,7 @@ typedef struct _Eo_Call_Cache
544EAPI Eo_Op _eo_api_op_id_get(const void *api_func); 546EAPI Eo_Op _eo_api_op_id_get(const void *api_func);
545 547
546// gets the real function pointer and the object data 548// gets the real function pointer and the object data
547EAPI Eina_Bool _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, Eo_Call_Cache *callcache, const char *file, int line); 549EAPI Eina_Bool _eo_call_resolve(const char *func_name, Eo_Op_Call_Data *call, Eo_Call_Cache *callcache, const char *file, int line);
548 550
549// start of eo_do barrier, gets the object pointer and ref it, put it on the stask 551// start of eo_do barrier, gets the object pointer and ref it, put it on the stask
550 EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, void *eo_stack); 552 EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, void *eo_stack);
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index b147ba56fd..af4a980bc7 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -521,10 +521,8 @@ _eo_do_end(void *eo_stack)
521 _eo_call_stack_resize(stack, EINA_FALSE); 521 _eo_call_stack_resize(stack, EINA_FALSE);
522} 522}
523 523
524#define EO_CALL_RESOLVE_CACHE 1
525
526EAPI Eina_Bool 524EAPI Eina_Bool
527_eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, Eo_Call_Cache *callcache, const char *file, int line) 525_eo_call_resolve(const char *func_name, Eo_Op_Call_Data *call, Eo_Call_Cache *cache, const char *file, int line)
528{ 526{
529 Eo_Stack_Frame *fptr; 527 Eo_Stack_Frame *fptr;
530 const _Eo_Class *klass, *inputklass; 528 const _Eo_Class *klass, *inputklass;
@@ -540,7 +538,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
540 538
541 inputklass = klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls; 539 inputklass = klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
542 540
543 if (op == EO_NOOP) 541 if (cache->op == EO_NOOP)
544 { 542 {
545 ERR("%s:%d: unable to resolve %s api func '%s' in class '%s'.", 543 ERR("%s:%d: unable to resolve %s api func '%s' in class '%s'.",
546 file, line, (!is_obj ? "class" : "regular"), 544 file, line, (!is_obj ? "class" : "regular"),
@@ -549,7 +547,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
549 return EINA_FALSE; 547 return EINA_FALSE;
550 } 548 }
551 549
552#ifdef EO_CALL_RESOLVE_CACHE 550# if EO_CALL_CACHE_SIZE > 0
553 if (!fptr->cur_klass) 551 if (!fptr->cur_klass)
554 { 552 {
555# if EO_CALL_CACHE_SIZE > 1 553# if EO_CALL_CACHE_SIZE > 1
@@ -560,9 +558,9 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
560 const int i = 0; 558 const int i = 0;
561# endif 559# endif
562 { 560 {
563 if ((const void *)inputklass == callcache->index[i].klass) 561 if ((const void *)inputklass == cache->index[i].klass)
564 { 562 {
565 func = (const op_type_funcs *)callcache->entry[i].func; 563 func = (const op_type_funcs *)cache->entry[i].func;
566 call->func = func->func; 564 call->func = func->func;
567 if (is_obj) 565 if (is_obj)
568 { 566 {
@@ -570,11 +568,11 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
570 if (func->src == fptr->o.obj->klass) 568 if (func->src == fptr->o.obj->klass)
571 { 569 {
572 if (fptr->obj_data == EO_INVALID_DATA) 570 if (fptr->obj_data == EO_INVALID_DATA)
573 fptr->obj_data = (char *)fptr->o.obj + callcache->off[i].off; 571 fptr->obj_data = (char *)fptr->o.obj + cache->off[i].off;
574 call->data = fptr->obj_data; 572 call->data = fptr->obj_data;
575 } 573 }
576 else 574 else
577 call->data = (char *)fptr->o.obj + callcache->off[i].off; 575 call->data = (char *)fptr->o.obj + cache->off[i].off;
578 } 576 }
579 else 577 else
580 { 578 {
@@ -589,7 +587,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
589 /* If we have a current class, we need to itr to the next. */ 587 /* If we have a current class, we need to itr to the next. */
590 if (fptr->cur_klass) 588 if (fptr->cur_klass)
591 { 589 {
592 func = _eo_kls_itr_next(klass, fptr->cur_klass, op); 590 func = _eo_kls_itr_next(klass, fptr->cur_klass, cache->op);
593 591
594 if (!func) 592 if (!func)
595 goto end; 593 goto end;
@@ -598,7 +596,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
598 } 596 }
599 else 597 else
600 { 598 {
601 func = _dich_func_get(klass, op); 599 func = _dich_func_get(klass, cache->op);
602 600
603 if (!func) 601 if (!func)
604 goto end; 602 goto end;
@@ -626,19 +624,20 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
626 call->data = NULL; 624 call->data = NULL;
627 } 625 }
628 626
629#ifdef EO_CALL_RESOLVE_CACHE 627# if EO_CALL_CACHE_SIZE > 0
628 #warning "blah"
630 if (!fptr->cur_klass) 629 if (!fptr->cur_klass)
631 { 630 {
632# if EO_CALL_CACHE_SIZE > 1 631# if EO_CALL_CACHE_SIZE > 1
633 const int slot = callcache->next_slot; 632 const int slot = cache->next_slot;
634# else 633# else
635 const int slot = 0; 634 const int slot = 0;
636# endif 635# endif
637 callcache->index[slot].klass = (const void *)inputklass; 636 cache->index[slot].klass = (const void *)inputklass;
638 callcache->entry[slot].func = (const void *)func; 637 cache->entry[slot].func = (const void *)func;
639 callcache->off[slot].off = (int)((long)((char *)call->data - (char *)fptr->o.obj)); 638 cache->off[slot].off = (int)((long)((char *)call->data - (char *)fptr->o.obj));
640# if EO_CALL_CACHE_SIZE > 1 639# if EO_CALL_CACHE_SIZE > 1
641 callcache->next_slot = (slot + 1) % EO_CALL_CACHE_SIZE; 640 cache->next_slot = (slot + 1) % EO_CALL_CACHE_SIZE;
642# endif 641# endif
643 } 642 }
644#endif 643#endif
@@ -649,7 +648,7 @@ _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Call_Data *call, E
649 if (func->src != NULL) 648 if (func->src != NULL)
650 { 649 {
651 ERR("in %s:%d: you called a pure virtual func '%s' (%d) of class '%s'.", 650 ERR("in %s:%d: you called a pure virtual func '%s' (%d) of class '%s'.",
652 file, line, func_name, op, klass->desc->name); 651 file, line, func_name, cache->op, klass->desc->name);
653 return EINA_FALSE; 652 return EINA_FALSE;
654 } 653 }
655 654
@@ -667,7 +666,7 @@ end:
667 if (!emb_obj) 666 if (!emb_obj)
668 continue; 667 continue;
669 668
670 func = _dich_func_get(emb_obj->klass, op); 669 func = _dich_func_get(emb_obj->klass, cache->op);
671 if (func == NULL) 670 if (func == NULL)
672 continue; 671 continue;
673 672
@@ -690,14 +689,14 @@ end:
690 if (fptr->cur_klass) 689 if (fptr->cur_klass)
691 { 690 {
692 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s' for super of '%s'.", 691 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s' for super of '%s'.",
693 file, line, func_name, op, main_klass->desc->name, 692 file, line, func_name, cache->op, main_klass->desc->name,
694 fptr->cur_klass->desc->name); 693 fptr->cur_klass->desc->name);
695 } 694 }
696 else 695 else
697 { 696 {
698 /* we should not be able to take this branch */ 697 /* we should not be able to take this branch */
699 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s'.", 698 ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s'.",
700 file, line, func_name, op, main_klass->desc->name); 699 file, line, func_name, cache->op, main_klass->desc->name);
701 } 700 }
702 } 701 }
703 return EINA_FALSE; 702 return EINA_FALSE;