Add one flavor of interface dispatch. Benchmark interface method dispatch which adds one level of indirection (to look up an itable).
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/8362e4bf Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/8362e4bf Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/8362e4bf Branch: refs/heads/master Commit: 8362e4bfc94ecd58a29ce4c713fd70c7c0c05327 Parents: e28b811 Author: Marvin Humphrey <[email protected]> Authored: Mon Sep 15 16:20:48 2014 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Mon Sep 15 19:08:45 2014 -0700 ---------------------------------------------------------------------- devel/benchmarks/method_dispatch/dso.c | 6 ++++++ devel/benchmarks/method_dispatch/dso.h | 1 + devel/benchmarks/method_dispatch/exe.c | 23 +++++++++++++++++++++++ devel/benchmarks/method_dispatch/oo.h | 14 +++++++++++--- 4 files changed, 41 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8362e4bf/devel/benchmarks/method_dispatch/dso.c ---------------------------------------------------------------------- diff --git a/devel/benchmarks/method_dispatch/dso.c b/devel/benchmarks/method_dispatch/dso.c index d0f323f..c8706e2 100644 --- a/devel/benchmarks/method_dispatch/dso.c +++ b/devel/benchmarks/method_dispatch/dso.c @@ -26,6 +26,7 @@ void thunk3(obj_t *obj); class_t *OBJ; size_t Obj_Hello_OFFSET; method_t Obj_Hello_THUNK_PTR; +unsigned int Obj_Hello_INTERFACE_OFFSET; void bootstrap() { @@ -41,6 +42,11 @@ bootstrap() { + METHOD_IDX * sizeof(method_t); OBJ->vtable[METHOD_IDX] = Obj_hello; Obj_Hello_THUNK_PTR = thunk3; + + // Interface ID 0, slot 0. + Obj_Hello_INTERFACE_OFFSET = Obj_Hello_OFFSET; + OBJ->itables[0] = (interface_t**)malloc(sizeof(void*)); + OBJ->itables[0][0] = (interface_t*)OBJ; } obj_t* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8362e4bf/devel/benchmarks/method_dispatch/dso.h ---------------------------------------------------------------------- diff --git a/devel/benchmarks/method_dispatch/dso.h b/devel/benchmarks/method_dispatch/dso.h index 587a2c4..702057d 100644 --- a/devel/benchmarks/method_dispatch/dso.h +++ b/devel/benchmarks/method_dispatch/dso.h @@ -25,6 +25,7 @@ extern method_t Obj_Hello_THUNK_PTR; #define METHOD_IDX 3 #define Obj_Hello_FIXED_OFFSET \ (offsetof(class_t, vtable) + METHOD_IDX * sizeof(method_t)) +extern unsigned Obj_Hello_INTERFACE_OFFSET; void bootstrap(); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8362e4bf/devel/benchmarks/method_dispatch/exe.c ---------------------------------------------------------------------- diff --git a/devel/benchmarks/method_dispatch/exe.c b/devel/benchmarks/method_dispatch/exe.c index 1747386..9774387 100644 --- a/devel/benchmarks/method_dispatch/exe.c +++ b/devel/benchmarks/method_dispatch/exe.c @@ -18,6 +18,7 @@ #include <stdio.h> #include <stdlib.h> #include <sys/time.h> +#include <assert.h> #include "dso.h" @@ -46,6 +47,20 @@ Obj_Hello_FIXED(obj_t *obj) { method(obj); } +static inline void +Obj_Hello_INTERFACE(obj_t *obj) { + unsigned offset = Obj_Hello_INTERFACE_OFFSET; + unsigned itable_array_slot + = (offset & ITABLE_ARRAY_MASK) >> ITABLE_ARRAY_SHIFT; + interface_t **itables = obj->klass->itables[itable_array_slot]; + unsigned interface_id + = (offset & INTERFACE_ID_MASK) >> INTERFACE_ID_SHIFT; + interface_t *interface = itables[interface_id]; + char *ptr = (char*)interface + (offset & IMETHOD_OFFSET_MASK); + method_t method = *(method_t*)ptr; + method(obj); +} + void loop_with_method_ptr(obj_t *obj) { method_t method = Obj_Hello_PTR(obj); @@ -69,6 +84,13 @@ loop_with_fixed_offset_wrapper(obj_t *obj) { } } +void +loop_with_interface(obj_t *obj) { + for (uint64_t i = 0; i < ITERATIONS; ++i) { + Obj_Hello_INTERFACE(obj); + } +} + #ifdef HAS_ALIAS void loop_with_thunk(obj_t *obj) { @@ -166,6 +188,7 @@ main(int argc, char **argv) { bench(loop_with_method_ptr, "method ptr loop"); bench(loop_with_wrapper, "wrapper loop"); bench(loop_with_fixed_offset_wrapper, "fixed offset wrapper loop"); + bench(loop_with_interface, "interface loop"); #ifdef HAS_ALIAS bench(loop_with_thunk, "thunk loop"); bench(loop_with_thunk_ptr, "thunk ptr loop"); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8362e4bf/devel/benchmarks/method_dispatch/oo.h ---------------------------------------------------------------------- diff --git a/devel/benchmarks/method_dispatch/oo.h b/devel/benchmarks/method_dispatch/oo.h index d2d0190..61ebbc3 100644 --- a/devel/benchmarks/method_dispatch/oo.h +++ b/devel/benchmarks/method_dispatch/oo.h @@ -21,6 +21,7 @@ #include <stdint.h> typedef struct class_t class_t; +typedef struct class_t interface_t; typedef struct obj_t { size_t refcount; @@ -31,10 +32,17 @@ typedef struct obj_t { typedef void (*method_t)(obj_t *obj); struct class_t { - char *name; - size_t class_size; - method_t vtable[1]; + char *name; + size_t class_size; + interface_t **itables[8]; + method_t vtable[1]; }; +#define ITABLE_ARRAY_SHIFT 16 +#define ITABLE_ARRAY_MASK 0xFFFF0000 +#define INTERFACE_ID_SHIFT 8 +#define INTERFACE_ID_MASK 0x0000FF00 +#define IMETHOD_OFFSET_MASK 0x000000FF + #endif /* OO_H */
