Object.st
branchjv
changeset 18095 da0aa615ffdd
parent 18093 2b786a9af1d0
child 18098 2bbfe6952a44
--- a/Object.st	Thu Sep 05 02:20:15 2013 +0100
+++ b/Object.st	Mon Sep 09 14:18:46 2013 +0100
@@ -5343,15 +5343,11 @@
 
     if (InterruptPending == nil) {
         struct inlineCache *pIlc;
-    /* JV @ 2010-22-07: To improve performance I use 256 ILCs instead
-       of default 4. This significantly reduces ILC misses. The code
-       should be further optimized by remembering last selector index and
-       try a first shot on that index. Another option is to use kind of
-       hashing on lower bits of sel variable. However, a more detailed
-       statistical data should be gathered before doing further optimizations.
-    */
-
-#define SEL_AND_ILC_INIT_1(l)   { nil , __ILCPERF0(l) }
+
+#define nways 2
+#define nilcs 131
+
+#define SEL_AND_ILC_INIT_1(l)   { { nil, nil } , { __ILCPERF0(l) , __ILCPERF0(l) } , 0 }
 #define SEL_AND_ILC_INIT_2(l)   SEL_AND_ILC_INIT_1(l)   , SEL_AND_ILC_INIT_1(l)
 #define SEL_AND_ILC_INIT_4(l)   SEL_AND_ILC_INIT_2(l)   , SEL_AND_ILC_INIT_2(l)
 #define SEL_AND_ILC_INIT_8(l)   SEL_AND_ILC_INIT_4(l)   , SEL_AND_ILC_INIT_4(l)
@@ -5361,9 +5357,10 @@
 #define SEL_AND_ILC_INIT_64(l)  SEL_AND_ILC_INIT_32(l)  , SEL_AND_ILC_INIT_32(l)
 #define SEL_AND_ILC_INIT_128(l) SEL_AND_ILC_INIT_64(l)  , SEL_AND_ILC_INIT_64(l)
 #define SEL_AND_ILC_INIT_256(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_128(l)
-#define nilcs 256
-
-        static struct { OBJ sel; struct inlineCache ilc; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_256(29) };
+
+#define SEL_AND_ILC_INIT_131(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_2(l) , SEL_AND_ILC_INIT_1(l)
+
+        static struct { OBJ sel[nways]; struct inlineCache ilc[nways]; int flip; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_131(@line) };
 
 #undef SEL_AND_ILC_INIT_1
 #undef SEL_AND_ILC_INIT_2
@@ -5375,21 +5372,30 @@
 #undef SEL_AND_ILC_INIT_128
 #undef SEL_AND_ILC_INIT_256
 
-        static flip = 0;
-        int i;
-        for (i = 0; i < nilcs; i++) {
-           if (sel == sel_and_ilc[i].sel) {
-                pIlc = &sel_and_ilc[i].ilc;
-                goto perform0_send_and_return;
-           }
+#undef SEL_AND_ILC_INIT_131
+#undef SEL_AND_ILC_INIT_257
+
+#define TRY(n)                                  \
+        if (sel == sel_and_ilc[hash0].sel[n]) { \
+            pIlc = &sel_and_ilc[hash0].ilc[n];  \
+            goto perform0_send_and_return;      \
         }
+
+        
+        int hash0 = __MAKE_HASH__(__GET_HASH(sel)) % nilcs;
+
+        TRY(0);
+        TRY(1);
+
+#undef TRY
         /*printf("Object >> #perform: #%s --> no PIC found\n", __symbolVal(aSelector));*/
-        pIlc = &sel_and_ilc[flip].ilc;
-        sel_and_ilc[flip].sel = sel;
-        flip = (flip + 1) % nilcs;
+
+        pIlc = &sel_and_ilc[hash0].ilc[sel_and_ilc[hash0].flip];
+        sel_and_ilc[hash0].sel[sel_and_ilc[hash0].flip] = sel;
+        sel_and_ilc[hash0].flip = (sel_and_ilc[hash0].flip + 1) % nways;
         pIlc->ilc_func = __SEND0ADDR__;
         if (pIlc->ilc_poly) {
-             __flushPolyCache(pIlc->ilc_poly);
+            __flushPolyCache(pIlc->ilc_poly);
             pIlc->ilc_poly = 0;
         }
 perform0_send_and_return:
@@ -5611,10 +5617,10 @@
 
     if (InterruptPending == nil) {
         struct inlineCache *pIlc;
-    /* JV @ 2010-22-07: To improve performance I use 256 ILCs instead
-       of default 4. For details, see comment in perform: */
-
-#define SEL_AND_ILC_INIT_1(l)   { nil , __ILCPERF1(l) }
+#define nways 2
+#define nilcs 131
+
+#define SEL_AND_ILC_INIT_1(l)   { { nil, nil } , { __ILCPERF1(l) , __ILCPERF1(l)  } , 0 }
 #define SEL_AND_ILC_INIT_2(l)   SEL_AND_ILC_INIT_1(l)   , SEL_AND_ILC_INIT_1(l)
 #define SEL_AND_ILC_INIT_4(l)   SEL_AND_ILC_INIT_2(l)   , SEL_AND_ILC_INIT_2(l)
 #define SEL_AND_ILC_INIT_8(l)   SEL_AND_ILC_INIT_4(l)   , SEL_AND_ILC_INIT_4(l)
@@ -5624,9 +5630,10 @@
 #define SEL_AND_ILC_INIT_64(l)  SEL_AND_ILC_INIT_32(l)  , SEL_AND_ILC_INIT_32(l)
 #define SEL_AND_ILC_INIT_128(l) SEL_AND_ILC_INIT_64(l)  , SEL_AND_ILC_INIT_64(l)
 #define SEL_AND_ILC_INIT_256(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_128(l)
-#define nilcs 256
-
-        static struct { OBJ sel; struct inlineCache ilc; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_256(29) };
+
+#define SEL_AND_ILC_INIT_131(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_2(l) , SEL_AND_ILC_INIT_1(l)
+
+        static struct { OBJ sel[nways]; struct inlineCache ilc[nways]; int flip; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_131(@line) };
 
 #undef SEL_AND_ILC_INIT_1
 #undef SEL_AND_ILC_INIT_2
@@ -5638,23 +5645,33 @@
 #undef SEL_AND_ILC_INIT_128
 #undef SEL_AND_ILC_INIT_256
 
-        static flip = 0;
-        int i;
-        for (i = 0; i < nilcs; i++) {
-           if (sel == sel_and_ilc[i].sel) {
-                pIlc = &sel_and_ilc[i].ilc;
-                goto perform1_send_and_return;
-           }
+#undef SEL_AND_ILC_INIT_131
+#undef SEL_AND_ILC_INIT_257
+
+#define TRY(n)                                  \
+        if (sel == sel_and_ilc[hash0].sel[n]) { \
+            pIlc = &sel_and_ilc[hash0].ilc[n];  \
+            goto perform1_send_and_return;      \
         }
-        /*printf("Object >> #perform: #%s with: arg --> no PIC found\n", __symbolVal(aSelector));*/
-        pIlc = &sel_and_ilc[flip].ilc;
-        sel_and_ilc[flip].sel = sel;
-        flip = (flip + 1) % nilcs;
+
+        
+        int hash0 = __MAKE_HASH__(__GET_HASH(sel)) % nilcs;
+
+        TRY(0);
+        TRY(1);
+
+#undef TRY
+        /*printf("Object >> #perform: #%s --> no PIC found\n", __symbolVal(aSelector));*/
+
+        pIlc = &sel_and_ilc[hash0].ilc[sel_and_ilc[hash0].flip];
+        sel_and_ilc[hash0].sel[sel_and_ilc[hash0].flip] = sel;
+        sel_and_ilc[hash0].flip = (sel_and_ilc[hash0].flip + 1) % nways;
         pIlc->ilc_func = __SEND1ADDR__;
         if (pIlc->ilc_poly) {
-             __flushPolyCache(pIlc->ilc_poly);
+            __flushPolyCache(pIlc->ilc_poly);
             pIlc->ilc_poly = 0;
         }
+
 perform1_send_and_return:
         RETURN ( (*(pIlc->ilc_func))(self, sel, nil, pIlc, arg) );
     } else {
@@ -5674,11 +5691,10 @@
     struct inlineCache *pIlc;
 
     if (InterruptPending == nil) {
-
-    /* JV @ 2010-22-07: To improve performance I use 256 ILCs instead
-       of default 4. For details, see comment in perform: */
-
-#define SEL_AND_ILC_INIT_1(l)   { nil , __ILCPERF2(l) }
+#define nways 2
+#define nilcs 131
+
+#define SEL_AND_ILC_INIT_1(l)   { { nil, nil } , { __ILCPERF2(l) , __ILCPERF2(l) } , 0 }
 #define SEL_AND_ILC_INIT_2(l)   SEL_AND_ILC_INIT_1(l)   , SEL_AND_ILC_INIT_1(l)
 #define SEL_AND_ILC_INIT_4(l)   SEL_AND_ILC_INIT_2(l)   , SEL_AND_ILC_INIT_2(l)
 #define SEL_AND_ILC_INIT_8(l)   SEL_AND_ILC_INIT_4(l)   , SEL_AND_ILC_INIT_4(l)
@@ -5688,9 +5704,10 @@
 #define SEL_AND_ILC_INIT_64(l)  SEL_AND_ILC_INIT_32(l)  , SEL_AND_ILC_INIT_32(l)
 #define SEL_AND_ILC_INIT_128(l) SEL_AND_ILC_INIT_64(l)  , SEL_AND_ILC_INIT_64(l)
 #define SEL_AND_ILC_INIT_256(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_128(l)
-#define nilcs 256
-
-        static struct { OBJ sel; struct inlineCache ilc; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_256(29) };
+
+#define SEL_AND_ILC_INIT_131(l) SEL_AND_ILC_INIT_128(l) , SEL_AND_ILC_INIT_2(l) , SEL_AND_ILC_INIT_1(l)
+
+        static struct { OBJ sel[nways]; struct inlineCache ilc[nways]; int flip; } sel_and_ilc[nilcs] = { SEL_AND_ILC_INIT_131(@line) };
 
 #undef SEL_AND_ILC_INIT_1
 #undef SEL_AND_ILC_INIT_2
@@ -5702,23 +5719,33 @@
 #undef SEL_AND_ILC_INIT_128
 #undef SEL_AND_ILC_INIT_256
 
-        static flip = 0;
-        int i;
-        for (i = 0; i < nilcs; i++) {
-           if (sel == sel_and_ilc[i].sel) {
-                pIlc = &sel_and_ilc[i].ilc;
-                goto perform2_send_and_return;
-           }
+#undef SEL_AND_ILC_INIT_131
+#undef SEL_AND_ILC_INIT_257
+
+#define TRY(n)                                  \
+        if (sel == sel_and_ilc[hash0].sel[n]) { \
+            pIlc = &sel_and_ilc[hash0].ilc[n];  \
+            goto perform2_send_and_return;      \
         }
-        /*printf("Object >> #perform: #%s with: with: --> no PIC found\n", __symbolVal(aSelector));*/
-        pIlc = &sel_and_ilc[flip].ilc;
-        sel_and_ilc[flip].sel = sel;
-        flip = (flip + 1) % nilcs;
+
+        
+        int hash0 = __MAKE_HASH__(__GET_HASH(sel)) % nilcs;
+
+        TRY(0);
+        TRY(1);
+
+#undef TRY
+        /*printf("Object >> #perform: #%s --> no PIC found\n", __symbolVal(aSelector));*/
+
+        pIlc = &sel_and_ilc[hash0].ilc[sel_and_ilc[hash0].flip];
+        sel_and_ilc[hash0].sel[sel_and_ilc[hash0].flip] = sel;
+        sel_and_ilc[hash0].flip = (sel_and_ilc[hash0].flip + 1) % nways;
         pIlc->ilc_func = __SEND2ADDR__;
         if (pIlc->ilc_poly) {
-             __flushPolyCache(pIlc->ilc_poly);
+            __flushPolyCache(pIlc->ilc_poly);
             pIlc->ilc_poly = 0;
         }
+
 perform2_send_and_return:
         RETURN ( (*(pIlc->ilc_func))(self, aSelector, nil, pIlc, arg1, arg2) );
     } else {