Author: Armin Rigo <[email protected]>
Branch:
Changeset: r70157:7e2b44e79080
Date: 2014-03-22 09:17 +0100
http://bitbucket.org/pypy/pypy/changeset/7e2b44e79080/
Log: Test and fix for the issue of dicts occasionally not updating their
cached status on a "del". The fix is to record the whole array-of-
struct in the 'write_descrs_arrays' as soon as we write in one
interior field, which is probably a good idea.
This removes the last usage of
effectinfo.write_descrs_interiorfields, which will no longer be
translated right now -- but I'm leaving it in as the way forward.
diff --git a/rpython/jit/codewriter/effectinfo.py
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -224,6 +224,18 @@
descr = cpu.interiorfielddescrof(T, fieldname)
descrs_interiorfields.append(descr)
+ # a read or a write to an interiorfield, inside an array of
+ # structs, is additionally recorded as a read or write of
+ # the array itself
+ extraef = set()
+ for tup in effects:
+ if tup[0] == "interiorfield" or tup[0] == "readinteriorfield":
+ T = deref(tup[1])
+ if isinstance(T, lltype.Array) and consider_array(T):
+ extraef.add((tup[0].replace("interiorfield", "array"),
+ tup[1]))
+ effects |= extraef
+
for tup in effects:
if tup[0] == "struct":
add_struct(write_descrs_fields, tup)
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1854,8 +1854,7 @@
def _handle_dict_lookup_call(self, op, oopspec_name, args):
extradescr1 = self.cpu.fielddescrof(op.args[1].concretetype.TO,
'entries')
- extradescr2 = self.cpu.interiorfielddescrof(
- op.args[1].concretetype.TO.entries.TO, 'key')
+ extradescr2 =
self.cpu.arraydescrof(op.args[1].concretetype.TO.entries.TO)
return self._handle_oopspec_call(op, args, EffectInfo.OS_DICT_LOOKUP,
extradescr=[extradescr1, extradescr2])
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -177,7 +177,7 @@
self.cached_arrayitems = {}
# cached dict items: {dict descr: {(optval, index): box-or-const}}
self.cached_dict_reads = {}
- # cache of corresponding array descrs
+ # cache of corresponding {array descrs: dict 'entries' field descr}
self.corresponding_array_descrs = {}
#
self._lazy_setfields_and_arrayitems = []
@@ -346,9 +346,8 @@
self.force_lazy_setfield(fielddescr, can_cache=False)
for arraydescr in effectinfo.write_descrs_arrays:
self.force_lazy_setarrayitem(arraydescr, can_cache=False)
- for descr in effectinfo.write_descrs_interiorfields:
- if descr in self.corresponding_array_descrs:
- dictdescr = self.corresponding_array_descrs.pop(descr)
+ if arraydescr in self.corresponding_array_descrs:
+ dictdescr = self.corresponding_array_descrs.pop(arraydescr)
try:
del self.cached_dict_reads[dictdescr]
except KeyError:
diff --git a/rpython/jit/metainterp/test/test_dict.py
b/rpython/jit/metainterp/test/test_dict.py
--- a/rpython/jit/metainterp/test/test_dict.py
+++ b/rpython/jit/metainterp/test/test_dict.py
@@ -327,6 +327,21 @@
self.check_simple_loop(call_may_force=4, # ll_dict_lookup_trampoline
call=1) # ll_dict_setitem_lookup_done_trampoline
+ def test_bug42(self):
+ myjitdriver = JitDriver(greens = [], reds = 'auto')
+ def f(n):
+ mdict = {0: None, 1: None, 2: None, 3: None, 4: None,
+ 5: None, 6: None, 7: None, 8: None, 9: None}
+ while n > 0:
+ myjitdriver.jit_merge_point()
+ n -= 1
+ if n in mdict:
+ del mdict[n]
+ if n in mdict:
+ raise Exception
+ self.meta_interp(f, [10])
+ self.check_simple_loop(call_may_force=0, call=3)
+
class TestLLtype(DictTests, LLJitMixin):
pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit