Author: Armin Rigo <[email protected]>
Branch: rdict-experiments-3
Changeset: r67301:162eedd7917a
Date: 2013-10-11 08:15 +0200
http://bitbucket.org/pypy/pypy/changeset/162eedd7917a/
Log: Cannot use llhelper() in case we want to translate the
ll_dict_lookup() function
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
@@ -43,7 +43,7 @@
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={},
- dummykeyobj=None, dummyvalueobj=None):
+ dummykeyobj=None, dummyvalueobj=None, rtyper=None):
# get the actual DICT type. if DICT is None, it's created, otherwise
# forward reference is becoming DICT
if DICT is None:
@@ -141,6 +141,11 @@
adtmeths['allocate'] = lltype.typeMethod(_ll_malloc_dict)
family = LookupFamily()
+ adtmeths['lookup_family'] = family
+
+ DICT.become(lltype.GcStruct("dicttable", adtmeths=adtmeths,
+ *fields))
+
family.empty_array = DICTENTRYARRAY.allocate(0)
for name, T in [('byte', rffi.UCHAR),
('short', rffi.USHORT),
@@ -149,14 +154,17 @@
if name == 'int' and not IS_64BIT:
continue
lookupfn, storecleanfn = new_lookup_functions(LOOKUP_FUNC,
- STORECLEAN_FUNC, T=T)
+ STORECLEAN_FUNC, T=T,
+ rtyper=rtyper)
setattr(family, '%s_lookup_function' % name, lookupfn)
setattr(family, '%s_insert_clean_function' % name, storecleanfn)
- adtmeths['lookup_family'] = family
+ return DICT
- DICT.become(lltype.GcStruct("dicttable", adtmeths=adtmeths,
- *fields))
- return DICT
+def llhelper_or_compile(rtyper, FUNCPTR, ll_func):
+ if rtyper is None:
+ return llhelper(FUNCPTR, ll_func)
+ else:
+ return rtyper.annotate_helper(ll_func, FUNCPTR.TO.ARGS)
class LookupFamily:
def _freeze_(self):
@@ -219,7 +227,8 @@
kwd['dummyvalueobj'] = self.value_repr.get_ll_dummyval_obj(
self.rtyper, s_value)
- get_ll_dict(DICTKEY, DICTVALUE, DICT=self.DICT, **kwd)
+ get_ll_dict(DICTKEY, DICTVALUE, DICT=self.DICT,
+ rtyper=self.rtyper, **kwd)
def convert_const(self, dictobj):
from rpython.rtyper.lltypesystem import llmemory
@@ -251,14 +260,16 @@
for dictkeycontainer, dictvalue in dictobj._dict.items():
llkey = r_key.convert_const(dictkeycontainer.key)
llvalue = r_value.convert_const(dictvalue)
- ll_dict_setitem(l_dict, llkey, llvalue)
+ _ll_dict_insertclean(l_dict, llkey, llvalue,
+ dictkeycontainer.hash)
return l_dict
else:
for dictkey, dictvalue in dictobj.items():
llkey = r_key.convert_const(dictkey)
llvalue = r_value.convert_const(dictvalue)
- ll_dict_setitem(l_dict, llkey, llvalue)
+ _ll_dict_insertclean(l_dict, llkey, llvalue,
+ l_dict.keyhash(llkey))
return l_dict
def rtype_len(self, hop):
@@ -530,6 +541,23 @@
ll_assert(rc > 0, "ll_dict_resize failed?")
d.resize_counter = rc
+def _ll_dict_insertclean(d, key, value, hash):
+ ENTRY = lltype.typeOf(d.entries).TO.OF
+ insertcleanfn = ll_pick_insert_clean_function(d)
+ insertcleanfn(d, hash, d.num_used_items)
+ entry = d.entries[d.num_used_items]
+ entry.key = key
+ entry.value = value
+ if hasattr(ENTRY, 'f_hash'):
+ entry.f_hash = hash
+ if hasattr(ENTRY, 'f_valid'):
+ entry.f_valid = True
+ d.num_used_items += 1
+ d.num_items += 1
+ rc = d.resize_counter - 3
+ ll_assert(rc > 0, "_ll_dict_insertclean: overflow")
+ d.resize_counter = rc
+
def _ll_len_of_d_indexes(d):
# xxx Haaaack: returns len(d.indexes). Works independently of
# the exact type pointed to by d, using a forced cast...
@@ -691,7 +719,7 @@
FLAG_DELETE = 2
FLAG_DELETE_TRY_HARD = 3
-def new_lookup_functions(LOOKUP_FUNC, STORECLEAN_FUNC, T):
+def new_lookup_functions(LOOKUP_FUNC, STORECLEAN_FUNC, T, rtyper=None):
INDEXES = lltype.Ptr(lltype.GcArray(T))
def ll_kill_something(d):
@@ -816,8 +844,8 @@
perturb >>= PERTURB_SHIFT
indexes[i] = rffi.cast(T, index + VALID_OFFSET)
- return (llhelper(LOOKUP_FUNC, ll_dict_lookup),
- llhelper(STORECLEAN_FUNC, ll_dict_store_clean))
+ return (llhelper_or_compile(rtyper, LOOKUP_FUNC, ll_dict_lookup),
+ llhelper_or_compile(rtyper, STORECLEAN_FUNC, ll_dict_store_clean))
# ____________________________________________________________
#
diff --git a/rpython/rtyper/test/test_rdict.py
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -856,6 +856,23 @@
res = self.interpret(f, [5])
assert res == 25019999
+ def test_prebuilt_r_dict(self):
+ def myeq(n, m):
+ return n // 2 == m // 2
+ def myhash(n):
+ return n // 2
+ d = r_dict(myeq, myhash)
+ for i in range(10):
+ d[i] = i*i
+ def f(n):
+ assert len(d) == 5
+ return d[n]
+ assert f(6) == 49
+ res = self.interpret(f, [6])
+ assert res == 49
+ res = self.interpret(f, [5])
+ assert res == 25
+
def test_resize_during_iteration(self):
def func():
d = {5: 1, 6: 2, 7: 3}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit