[pypy-commit] pypy rdict-experiments-2: bring this branch to the state where it passes tests

fijal noreply at buildbot.pypy.org
Mon Jan 7 15:42:52 CET 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: rdict-experiments-2
Changeset: r59841:09ee3d8253c3
Date: 2013-01-07 16:34 +0200
http://bitbucket.org/pypy/pypy/changeset/09ee3d8253c3/

Log:	bring this branch to the state where it passes tests

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
@@ -2,7 +2,7 @@
 from pypy.objspace.flow.model import Constant
 from pypy.rpython.rdict import (AbstractDictRepr, AbstractDictIteratorRepr,
                                 rtype_newdict)
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib import objectmodel, jit, rgc
 from pypy.rlib.debug import ll_assert
@@ -84,7 +84,7 @@
               ("resize_counter", lltype.Signed),
               ("size", lltype.Signed),
               ("entries", lltype.Ptr(DICTENTRYARRAY)),
-              ("indexes", DICTINDEXARRAY)]
+              ("indexes", llmemory.GCREF)]
     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),
@@ -340,26 +340,31 @@
 
 # --------------------- indexes ------------------
 
-DICTINDEXARRAY = lltype.Ptr(lltype.GcArray(lltype.Signed))
+DICTINDEX_SIGNED = lltype.Ptr(lltype.GcArray(lltype.Signed))
+DICTINDEX_INT = lltype.Ptr(lltype.GcArray(rffi.INT_real))
+MAX_INT = 2 ** 31 - 1
 
 def _ll_malloc_indexes(n):
-    res = lltype.malloc(DICTINDEXARRAY.TO, n)
+    # XXXX 64 bit only
+    res = lltype.cast_opaque_ptr(llmemory.GCREF,
+                 lltype.malloc(DICTINDEX_SIGNED.TO, n))
     i = 0
     while i < n:
-        res[i] = FREE
+        ll_index_setitem(n, res, i, FREE)
         i += 1
     return res
 
 def ll_index_getitem(size, indexes, i):
-    return indexes[i]
+    return lltype.cast_opaque_ptr(DICTINDEX_SIGNED, indexes)[i]
 
 def ll_index_setitem(size, indexes, i, v):
-    indexes[i] = v
+    lltype.cast_opaque_ptr(DICTINDEX_SIGNED, indexes)[i] = v
 
 def ll_dict_copy_indexes(size, from_indexes, to_indexes):
     i = 0
     while i < size:
-        ll_index_setitem(size, i, ll_index_getitem(size, from_indexes, i))
+        ll_index_setitem(size, to_indexes, i,
+                         ll_index_getitem(size, from_indexes, i))
         i += 1
 
 # ---------------------- hashes -------------------
@@ -632,16 +637,11 @@
 DICT_INITSIZE = 8
 DICT_ITEMS_INITSIZE = 5
 
- at 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)
+    d.indexes = _ll_malloc_indexes(DICT_INITSIZE)
     d.size = DICT_INITSIZE
     d.num_items = 0
-    for i in range(DICT_INITSIZE):
-        ll_index_setitem(d.size, d.indexes, i, FREE)
     d.entries = DICT.entries.TO.allocate(DICT_ITEMS_INITSIZE)    
     d.resize_counter = DICT_ITEMS_INITSIZE
     return 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
@@ -23,6 +23,16 @@
         assert 0 <= x < 4
         yield x
 
+def foreach_index(ll_d):
+    for i in range(ll_d.size):
+        yield rdict.ll_index_getitem(ll_d.size, ll_d.indexes, i)
+
+def count_items(ll_d, ITEM):
+    c = 0
+    for item in foreach_index(ll_d):
+        if item == ITEM:
+            c += 1
+    return c
 
 class TestRDictDirect(object):
     def _get_str_dict(self):
@@ -37,8 +47,7 @@
         DICT = self._get_str_dict()
         ll_d = rdict.ll_newdict(DICT)
         rdict.ll_dict_setitem(ll_d, llstr("abc"), 13)
-        assert (len([i for i in ll_d.indexes if i == rdict.FREE]) ==
-                rdict.DICT_INITSIZE - 1)
+        assert count_items(ll_d, rdict.FREE) == rdict.DICT_INITSIZE - 1
         assert rdict.ll_dict_getitem(ll_d, llstr("abc")) == 13
 
     def test_dict_del_lastitem(self):
@@ -48,9 +57,8 @@
         rdict.ll_dict_setitem(ll_d, llstr("abc"), 13)
         py.test.raises(KeyError, rdict.ll_dict_delitem, ll_d, llstr("def"))
         rdict.ll_dict_delitem(ll_d, llstr("abc"))
-        assert (len([i for i in ll_d.indexes if i == rdict.FREE]) ==
-                rdict.DICT_INITSIZE - 1)
-        assert (len([i for i in ll_d.indexes if i == rdict.DELETED]) == 1)
+        assert count_items(ll_d, rdict.FREE) == rdict.DICT_INITSIZE - 1
+        assert count_items(ll_d, rdict.DELETED) == 1
         py.test.raises(KeyError, rdict.ll_dict_getitem, ll_d, llstr("abc"))
 
     def test_dict_del_not_lastitem(self):
@@ -59,9 +67,8 @@
         rdict.ll_dict_setitem(ll_d, llstr("abc"), 13)
         rdict.ll_dict_setitem(ll_d, llstr("def"), 15)
         rdict.ll_dict_delitem(ll_d, llstr("abc"))
-        assert (len([i for i in ll_d.indexes if i == rdict.FREE]) ==
-                rdict.DICT_INITSIZE - 2)
-        assert (len([i for i in ll_d.indexes if i == rdict.DELETED]) == 1)
+        assert count_items(ll_d, rdict.FREE) == rdict.DICT_INITSIZE - 2
+        assert count_items(ll_d, rdict.DELETED) == 1
 
     def test_dict_resize(self):
         DICT = self._get_str_dict()
@@ -70,10 +77,10 @@
         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)         
-        assert len(ll_d.indexes) == 8
+        assert ll_d.size == 8
         rdict.ll_dict_setitem(ll_d, llstr("e"), 5)
         rdict.ll_dict_setitem(ll_d, llstr("f"), 6)
-        assert len(ll_d.indexes) == 32
+        assert ll_d.size == 32
         for item in ['a', 'b', 'c', 'd', 'e', 'f']:
             assert rdict.ll_dict_getitem(ll_d, llstr(item)) == ord(item) - ord('a') + 1
 
@@ -115,7 +122,7 @@
         for num in numbers:
             rdict.ll_dict_setitem(ll_d, num, 1)
             rdict.ll_dict_delitem(ll_d, num)
-            for k in ll_d.indexes:
+            for k in foreach_index(ll_d):
                 assert k < 0
 
 class BaseTestRdict(BaseRtypingTest):
@@ -829,7 +836,7 @@
             return d
 
         res = self.interpret(func2, [ord(x), ord(y)])
-        assert len([i for i in res.indexes if i >= 0]) == 2
+        assert len([i for i in foreach_index(res) if i >= 0]) == 2
 
         def func3(c0, c1, c2, c3, c4, c5, c6, c7):
             d = {}
@@ -848,7 +855,7 @@
         res = self.interpret(func3, [ord(char_by_hash[i][0])
                                    for i in range(rdict.DICT_INITSIZE)])
         count_frees = 0
-        for i in res.indexes:
+        for i in foreach_index(res):
             if i == -1:
                 count_frees += 1
         assert count_frees >= 3
@@ -870,9 +877,9 @@
                     del d[chr(ord('A') - i)]
             return d
         res = self.interpret(func, [0])
-        assert len(res.indexes) > rdict.DICT_INITSIZE
+        assert res.size > rdict.DICT_INITSIZE
         res = self.interpret(func, [1])
-        assert len(res.indexes) == rdict.DICT_INITSIZE
+        assert res.size == rdict.DICT_INITSIZE
 
     def test_dict_valid_resize(self):
         # see if we find our keys after resize
@@ -884,7 +891,6 @@
             # delete again
             for i in range(10):
                 del d[str(i)]
-            res = 0
         # if it does not crash, we are fine. It crashes if you forget the hash field.
         self.interpret(func, [])
 


More information about the pypy-commit mailing list