Author: Maciej Fijalkowski <[email protected]>
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.
[email protected]_inside_iff(lambda d, key, value, hash, i: jit.isvirtual(d) and
jit.isconstant(key))
[email protected]_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
[email protected]_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)
+
[email protected]_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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit