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 */
 

Reply via email to