Author: Maciej Fijalkowski <[email protected]>
Branch: rdict-experiments-3
Changeset: r67573:3b14a46a82d9
Date: 2013-10-24 17:09 +0200
http://bitbucket.org/pypy/pypy/changeset/3b14a46a82d9/

Log:    implement fast function lookup (by hand a bit)

diff --git a/rpython/rtyper/lltypesystem/rdict.py 
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -32,7 +32,7 @@
 #        int resize_counter;
 #        {byte, short, int, long} *indexes;
 #        dictentry *entries;
-#        lookup_function; # one of the four possible functions for different
+#        lookup_function_no; # one of the four possible functions for different
 #                         # size dicts
 #        (Function DICTKEY, DICTKEY -> bool) *fnkeyeq;
 #        (Function DICTKEY -> int) *fnkeyhash;
@@ -40,6 +40,29 @@
 #
 #
 
+def ll_call_lookup_function(d, key, hash, flag):
+    DICT = lltype.typeOf(d).TO
+    if IS_64BIT:
+        fun = d.lookup_function_no
+        if fun == FUNC_BYTE:
+            return DICT.lookup_family.byte_lookup_function(d, key, hash, flag)
+        elif fun == FUNC_SHORT:
+            return DICT.lookup_family.short_lookup_function(d, key, hash, flag)
+        elif fun == FUNC_INT:
+            return DICT.lookup_family.int_lookup_function(d, key, hash, flag)
+        elif fun == FUNC_LONG:
+            return DICT.lookup_family.long_lookup_function(d, key, hash, flag)
+        assert False
+    else:
+        fun = d.lookup_function_no
+        if fun == FUNC_BYTE:
+            return DICT.lookup_family.byte_lookup_function(d, key, hash, flag)
+        elif fun == FUNC_SHORT:
+            return DICT.lookup_family.short_lookup_function(d, key, hash, flag)
+        elif fun == FUNC_LONG:
+            return DICT.lookup_family.long_lookup_function(d, key, hash, flag)
+        assert False
+
 def get_ll_dict(DICTKEY, DICTVALUE, get_custom_eq_hash=None, DICT=None,
                 ll_fasthash_function=None, ll_hash_function=None,
                 ll_eq_function=None, method_cache={},
@@ -100,15 +123,11 @@
     DICTENTRY = lltype.Struct("dictentry", *entryfields)
     DICTENTRYARRAY = lltype.GcArray(DICTENTRY,
                                     adtmeths=entrymeths)
-    LOOKUP_FUNC = lltype.Ptr(lltype.FuncType([lltype.Ptr(DICT), DICTKEY,
-                                              lltype.Signed, lltype.Signed],
-                                             lltype.Signed))
-
     fields =          [ ("num_items", lltype.Signed),
                         ("num_used_items", lltype.Signed),
                         ("resize_counter", lltype.Signed),
                         ("indexes", llmemory.GCREF),
-                        ("lookup_function", LOOKUP_FUNC),
+                        ("lookup_function_no", lltype.Signed),
                         ("entries", lltype.Ptr(DICTENTRYARRAY)) ]
     if get_custom_eq_hash is not None:
         r_rdict_eqfn, r_rdict_hashfn = get_custom_eq_hash()
@@ -135,6 +154,7 @@
             }
     adtmeths['KEY']   = DICTKEY
     adtmeths['VALUE'] = DICTVALUE
+    adtmeths['lookup_function'] = 
lltype.staticAdtMethod(ll_call_lookup_function)
     adtmeths['allocate'] = lltype.typeMethod(_ll_malloc_dict)
 
     family = LookupFamily()
@@ -145,10 +165,16 @@
 
     family.empty_array = DICTENTRYARRAY.allocate(0)
     if setup_lookup_funcs:
-        _setup_lookup_funcs(LOOKUP_FUNC, DICT, rtyper, family)
+        _setup_lookup_funcs(DICT, rtyper, family)
     return DICT
 
-def _setup_lookup_funcs(LOOKUP_FUNC, DICT, rtyper, family):
+def _setup_lookup_funcs(DICT, rtyper, family):
+    DICTKEY = DICT.entries.TO.OF.key
+    LOOKUP_FUNC = lltype.Ptr(lltype.FuncType([lltype.Ptr(DICT), DICTKEY,
+                                              lltype.Signed, lltype.Signed],
+                                              lltype.Signed))
+
+
     STORECLEAN_FUNC = lltype.Ptr(lltype.FuncType([lltype.Ptr(DICT),
                                                   lltype.Signed,
                                                   lltype.Signed],
@@ -239,10 +265,8 @@
 
     def _setup_repr_final(self):
         if not self.finalized:
-            LOOKUP_FUNC = self.lowleveltype.TO.lookup_function
             family = self.lowleveltype.TO.lookup_family
-            _setup_lookup_funcs(LOOKUP_FUNC, self.lowleveltype.TO, self.rtyper,
-                                family)
+            _setup_lookup_funcs(self.lowleveltype.TO, self.rtyper, family)
             self.finalized = True
 
 
@@ -432,40 +456,43 @@
 
 IS_64BIT = sys.maxint != 2 ** 31 - 1
 
+if IS_64BIT:
+    FUNC_BYTE, FUNC_SHORT, FUNC_INT, FUNC_LONG = range(4)
+else:
+    FUNC_BYTE, FUNC_SHORT, FUNC_LONG = range(3)
+
 def ll_malloc_indexes_and_choose_lookup(d, n):
-    DICT = lltype.typeOf(d).TO
     if n <= 256:
         d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF,
                                            lltype.malloc(DICTINDEX_BYTE.TO, n,
                                                          zero=True))
-        d.lookup_function = DICT.lookup_family.byte_lookup_function
+        d.lookup_function_no = FUNC_BYTE
     elif n <= 65536:
         d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF,
                                            lltype.malloc(DICTINDEX_SHORT.TO, n,
                                                          zero=True))
-        d.lookup_function = DICT.lookup_family.short_lookup_function
+        d.lookup_function_no = FUNC_SHORT
     elif IS_64BIT and n <= 2 ** 32:
         d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF,
                                            lltype.malloc(DICTINDEX_INT.TO, n,
                                                          zero=True))
-        d.lookup_function = DICT.lookup_family.int_lookup_function
+        d.lookup_function_no = FUNC_INT
     else:
         d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF,
                                            lltype.malloc(DICTINDEX_LONG.TO, n,
                                                          zero=True))
-        d.lookup_function = DICT.lookup_family.long_lookup_function
-ll_malloc_indexes_and_choose_lookup._always_inline_ = True
+        d.lookup_function_no = FUNC_LONG
 
 def ll_pick_insert_clean_function(d):
     DICT = lltype.typeOf(d).TO
-    if d.lookup_function == DICT.lookup_family.byte_lookup_function:
+    if d.lookup_function_no == FUNC_BYTE:
         return DICT.lookup_family.byte_insert_clean_function
-    if d.lookup_function == DICT.lookup_family.short_lookup_function:
+    if d.lookup_function_no == FUNC_SHORT:
         return DICT.lookup_family.short_insert_clean_function
     if IS_64BIT:
-        if d.lookup_function == DICT.lookup_family.int_lookup_function:
+        if d.lookup_function_no == FUNC_INT:
             return DICT.lookup_family.int_insert_clean_function
-    if d.lookup_function == DICT.lookup_family.long_lookup_function:
+    if d.lookup_function_no == FUNC_LONG:
         return DICT.lookup_family.long_insert_clean_function
     assert False
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to