--- 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 {