Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: rdict-experiments-2
Changeset: r59813:0d9d5d21c955
Date: 2013-01-06 20:28 +0200
http://bitbucket.org/pypy/pypy/changeset/0d9d5d21c955/

Log:    hack hack fix fix test test

diff --git a/pypy/rpython/lltypesystem/opimpl.py 
b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -525,6 +525,8 @@
     A = lltype.typeOf(source)
     assert A == lltype.typeOf(dest)
     assert isinstance(A.TO, lltype.GcArray)
+    if isinstance(A.TO.OF, lltype.Struct):
+        return True
     assert isinstance(A.TO.OF, lltype.Ptr)
     assert A.TO.OF.TO._gckind == 'gc'
     assert type(source_start) is int
diff --git a/pypy/rpython/lltypesystem/rdict.py 
b/pypy/rpython/lltypesystem/rdict.py
--- a/pypy/rpython/lltypesystem/rdict.py
+++ b/pypy/rpython/lltypesystem/rdict.py
@@ -78,10 +78,12 @@
     DICTENTRY = lltype.Struct("dictentry", *entryfields)
     DICTENTRYARRAY = lltype.GcArray(DICTENTRY,
                                     adtmeths=entrymeths)
+    array_adtmeths = {'allocate': lltype.typeMethod(_ll_malloc_items)}
     fields = [("num_items", lltype.Signed),
               ("resize_counter", lltype.Signed),
               ("entries", lltype.Ptr(DICTENTRYARRAY)),
-              ("indexes", lltype.Ptr(lltype.GcArray(lltype.Signed)))]
+              ("indexes", lltype.Ptr(lltype.GcArray(lltype.Signed,
+                                     adtmeths=array_adtmeths)))]
     if get_custom_eq_hash is not None:
         r_rdict_eqfn, r_rdict_hashfn = get_custom_eq_hash()
         fields.extend([ ("fnkeyeq", r_rdict_eqfn.lowleveltype),
@@ -368,9 +370,12 @@
     i = ll_dict_lookup(d, key, hash)
     return _ll_dict_setitem_lookup_done(d, key, value, hash, i)
 
+def _look_inside_setitem(d, key, value, hash, i):
+    return jit.isvirtual(d) and jit.isconstant(key)
+
 # It may be safe to look inside always, it has a few branches though, and their
 # frequencies needs to be investigated.
-@jit.look_inside_iff(lambda d, key, value, hash, i: jit.isvirtual(d) and 
jit.isconstant(key))
+@jit.look_inside_iff(_look_inside_setitem)
 def _ll_dict_setitem_lookup_done(d, key, value, hash, i):
     valid = (i & HIGHEST_BIT) == 0
     i = i & MASK
@@ -384,7 +389,7 @@
         rc = d.resize_counter - 3
         if rc <= 0:       # if needed, resize the dict -- before the insertion
             ll_dict_resize(d)
-            index = d.indexes[ll_dict_lookup_clean(d, hash)]
+            i = ll_dict_lookup_clean(d, hash)
             # then redo the lookup for 'key'
             entry = d.entries[index]
             rc = d.resize_counter - 3
@@ -483,7 +488,7 @@
     #
     new_item_size = new_size // 3 * 2 + 1
     d.entries = lltype.typeOf(old_entries).TO.allocate(new_item_size)
-    d.indexes = lltype.malloc(lltype.typeOf(d).TO.indexes.TO, new_size)
+    d.indexes = lltype.typeOf(d).TO.indexes.TO.allocate(new_size)
     d.num_items = len(old_entries)
     d.resize_counter = new_size * 2
     i = 0
@@ -499,11 +504,13 @@
 # ------- a port of CPython's dictobject.c's lookdict implementation -------
 PERTURB_SHIFT = 5
 
-@jit.look_inside_iff(lambda d, key, hash: jit.isvirtual(d) and 
jit.isconstant(key))
+_look_inside_lookup = lambda d, key, hash: jit.isvirtual(d) and 
jit.isconstant(key)
+
+@jit.look_inside_iff(_look_inside_lookup)
 def ll_dict_lookup(d, key, hash):
     entries = d.entries
     indexes = d.indexes
-    mask = len(entries) - 1
+    mask = len(indexes) - 1
     i = hash & mask
     # do the first try before any looping
     index = indexes[i]
@@ -572,7 +579,7 @@
     mask = len(indexes) - 1
     i = hash & mask
     perturb = r_uint(hash)
-    while i != FREE:
+    while d.indexes[i] != FREE:
         i = r_uint(i)
         i = (i << 2) + i + perturb + 1
         i = intmask(i) & mask
@@ -584,11 +591,13 @@
 #  Irregular operations.
 
 DICT_INITSIZE = 8
-DICT_ITEMS_INITSIZE = 5
+DICT_ITEMS_INITSIZE = 6
 
 @jit.unroll_safe # we always unroll the small allocation
 def ll_newdict(DICT):
     d = DICT.allocate()
+    # XXX don't use _ll_items_allocate because of jit.unroll_safe,
+    #     should be *really* jit_unroll_iff
     d.indexes = lltype.malloc(DICT.indexes.TO, DICT_INITSIZE)
     for i in range(DICT_INITSIZE):
         d.indexes[i] = FREE
@@ -605,7 +614,7 @@
     items_size = n // 3 * 2 + 1
     d = DICT.allocate()
     d.entries = DICT.entries.TO.allocate(items_size)
-    d.indexes = lltype.malloc(DICT.indexes.TO, n)
+    d.indexes = DICT.indexes.TO.allocate(n)
     d.num_items = 0
     d.resize_counter = n * 2
     return d
@@ -617,7 +626,13 @@
     return lltype.malloc(DICT)
 def _ll_malloc_entries(ENTRIES, n):
     return lltype.malloc(ENTRIES, n, zero=True)
-
+def _ll_malloc_items(ITEMS, n):
+    res = lltype.malloc(ITEMS, n)
+    i = 0
+    while i < n:
+        res[i] = FREE
+        i += 1
+    return res
 
 def rtype_r_dict(hop):
     r_dict = hop.r_result
@@ -739,12 +754,12 @@
 ll_copy.oopspec = 'dict.copy(dict)'
 
 def ll_clear(d):
-    xxx
-    if (len(d.entries) == DICT_INITSIZE and
+    if (len(d.indexes) == DICT_INITSIZE and
         d.resize_counter == DICT_INITSIZE * 2):
         return
     old_entries = d.entries
-    d.entries = lltype.typeOf(old_entries).TO.allocate(DICT_INITSIZE)
+    d.entries = lltype.typeOf(old_entries).TO.allocate(DICT_ITEMS_INITSIZE)
+    d.indexes = lltype.typeOf(d).TO.indexes.TO.allocate(DICT_INITSIZE)
     d.num_items = 0
     d.resize_counter = DICT_INITSIZE * 2
 ll_clear.oopspec = 'dict.clear(d)'
diff --git a/pypy/rpython/test/test_rdict.py b/pypy/rpython/test/test_rdict.py
--- a/pypy/rpython/test/test_rdict.py
+++ b/pypy/rpython/test/test_rdict.py
@@ -63,6 +63,18 @@
                 rdict.DICT_INITSIZE - 2)
         assert (len([i for i in ll_d.indexes if i == rdict.DELETED]) == 1)
 
+    def test_dict_resize(self):
+        DICT = self._get_str_dict()
+        ll_d = rdict.ll_newdict(DICT) 
+        rdict.ll_dict_setitem(ll_d, llstr("a"), 1)        
+        rdict.ll_dict_setitem(ll_d, llstr("b"), 2)        
+        rdict.ll_dict_setitem(ll_d, llstr("c"), 3)        
+        rdict.ll_dict_setitem(ll_d, llstr("d"), 4)        
+        rdict.ll_dict_setitem(ll_d, llstr("e"), 5)
+        assert len(ll_d.indexes) == 8
+        rdict.ll_dict_setitem(ll_d, llstr("f"), 6)
+        assert len(ll_d.indexes) == 32
+
 class BaseTestRdict(BaseRtypingTest):
 
     def test_dict_creation(self):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to