[pypy-svn] r40632 - in pypy/branch/jit-virtual-world/pypy: jit/goal jit/timeshifter jit/timeshifter/test rpython rpython/lltypesystem

arigo at codespeak.net arigo at codespeak.net
Sat Mar 17 13:09:32 CET 2007


Author: arigo
Date: Sat Mar 17 13:09:28 2007
New Revision: 40632

Modified:
   pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py
   pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py
   pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py
   pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py
   pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py
   pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py
   pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rdict.py
   pypy/branch/jit-virtual-world/pypy/rpython/rlist.py
Log:
(pedronis, arigo)

Fix the tests showing cases where the JIT compilation process
can segfault while trying to constant-fold bogus paths.


Modified: pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/goal/jitstep.py	Sat Mar 17 13:09:28 2007
@@ -181,7 +181,6 @@
     for graphname in graphnames:
         print graphname
     print '-' * 20
-    import pdb; pdb.set_trace()
 
     hannotator = HintAnnotator(base_translator=t, policy=POLICY)
     hs = hannotator.build_types(portal_graph,

Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/oop.py	Sat Mar 17 13:09:28 2007
@@ -4,8 +4,12 @@
 from pypy.jit.timeshifter import rvalue, rtimeshift
 from pypy.translator.c import exceptiontransform
 from pypy.rlib.unroll import unrolling_iterable
+from pypy.tool.sourcetools import func_with_new_name
 
 
+class SegfaultException(Exception):
+    "Signals a run-time segfault detected at compile-time."
+
 class Index:
     def __init__(self, n):
         self.n = n
@@ -34,10 +38,15 @@
         self.argtuple = eval(args, d)
         # end of rather XXX'edly hackish parsing
 
+        OOPARGTYPES = []
         arg_llsig_to_oopsig = {}
         for i, obj in enumerate(self.argtuple):
             if isinstance(obj, Index):
                 arg_llsig_to_oopsig[obj.n] = i
+                OOPARG = FUNCTYPE.ARGS[obj.n]
+            else:
+                OOPARG = lltype.typeOf(obj)
+            OOPARGTYPES.append(OOPARG)
 
         self.residualargsources = []
         for i in range(nb_args):
@@ -82,11 +91,22 @@
         self.couldfold = getattr(self.ll_handler, 'couldfold', False)
 
         if self.couldfold:
+            oopargcheck = ll_func.oopargcheck    # required if couldfold=True
+            # make a copy of the function, for specialization purposes
+            oopargcheck = func_with_new_name(oopargcheck,
+                                             'argcheck_%s' % (method,))
             ARGS = FUNCTYPE.ARGS
             residualargsources = self.residualargsources
             unrolling_ARGS = unrolling_iterable(ARGS)
+            unrolling_OOPARGS = unrolling_iterable(enumerate(OOPARGTYPES))
 
             def do_call(jitstate, argboxes):
+                oopargs = ()
+                for i, ARG in unrolling_OOPARGS:
+                    v = rvalue.ll_getvalue(argboxes[i], ARG)
+                    oopargs += (v,)
+                if not oopargcheck(*oopargs):
+                    raise SegfaultException
                 args = ()
                 j = 0
                 for ARG in unrolling_ARGS:
@@ -95,7 +115,7 @@
                     else:
                         argsrc = residualargsources[j]
                         j = j + 1
-                        v = rvalue.ll_getvalue(argboxes[argsrc], ARG)
+                        v = oopargs[argsrc]
                     args += (v,)
                 result = fnptr(*args)
                 if FUNCTYPE.RESULT == lltype.Void:

Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rtimeshift.py	Sat Mar 17 13:09:28 2007
@@ -145,9 +145,10 @@
 
 def ll_gengetfield(jitstate, deepfrozen, fielddesc, argbox):
     if (fielddesc.immutable or deepfrozen) and argbox.is_constant():
-        res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE),
-                      fielddesc.fieldname)
-        return rvalue.ll_fromvalue(jitstate, res)
+        ptr = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
+        if ptr:    # else don't constant-fold the segfault...
+            res = getattr(ptr, fielddesc.fieldname)
+            return rvalue.ll_fromvalue(jitstate, res)
     return argbox.op_getfield(jitstate, fielddesc)
 
 def ll_gensetfield(jitstate, fielddesc, destbox, valuebox):
@@ -155,17 +156,20 @@
 
 def ll_gengetsubstruct(jitstate, fielddesc, argbox):
     if argbox.is_constant():
-        res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE),
-                      fielddesc.fieldname)
-        return rvalue.ll_fromvalue(jitstate, res)
+        ptr = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
+        if ptr:    # else don't constant-fold - we'd get a bogus pointer
+            res = getattr(ptr, fielddesc.fieldname)
+            return rvalue.ll_fromvalue(jitstate, res)
     return argbox.op_getsubstruct(jitstate, fielddesc)
 
 def ll_gengetarrayitem(jitstate, deepfrozen, fielddesc, argbox, indexbox):
     if ((fielddesc.immutable or deepfrozen) and argbox.is_constant()
                                             and indexbox.is_constant()):
         array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
-        res = array[rvalue.ll_getvalue(indexbox, lltype.Signed)]
-        return rvalue.ll_fromvalue(jitstate, res)
+        index = rvalue.ll_getvalue(indexbox, lltype.Signed)
+        if array and 0 <= index < len(array):  # else don't constant-fold
+            res = array[index]
+            return rvalue.ll_fromvalue(jitstate, res)
     genvar = jitstate.curbuilder.genop_getarrayitem(
         fielddesc.arraytoken,
         argbox.getgenvar(jitstate),
@@ -176,8 +180,10 @@
 def ll_gengetarraysubstruct(jitstate, fielddesc, argbox, indexbox):
     if argbox.is_constant() and indexbox.is_constant():
         array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
-        res = array[rvalue.ll_getvalue(indexbox, lltype.Signed)]
-        return rvalue.ll_fromvalue(jitstate, res)
+        index = rvalue.ll_getvalue(indexbox, lltype.Signed)
+        if array and 0 <= index < len(array):  # else don't constant-fold
+            res = array[index]
+            return rvalue.ll_fromvalue(jitstate, res)
     genvar = jitstate.curbuilder.genop_getarraysubstruct(
         fielddesc.arraytoken,
         argbox.getgenvar(jitstate),
@@ -197,8 +203,9 @@
 def ll_gengetarraysize(jitstate, fielddesc, argbox):
     if argbox.is_constant():
         array = rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE)
-        res = len(array)
-        return rvalue.ll_fromvalue(jitstate, res)
+        if array:    # else don't constant-fold the segfault...
+            res = len(array)
+            return rvalue.ll_fromvalue(jitstate, res)
     genvar = jitstate.curbuilder.genop_getarraysize(
         fielddesc.arraytoken,
         argbox.getgenvar(jitstate))
@@ -386,8 +393,9 @@
         node = resuming.path.pop()
         assert isinstance(node, PromotionPathSplit)
         if ptrbox is not None:
-            ptrbox.learn_nonzeroness(jitstate,
-                                     nonzeroness = node.answer ^ reverse)
+            ok = ptrbox.learn_nonzeroness(jitstate,
+                                          nonzeroness = node.answer ^ reverse)
+            assert ok
         return node.answer
     later_gv = jitstate.get_locals_gv() # alive gvs on the later path
     if ll_evalue:    # special case - we want jump_if_true in split_raisingop
@@ -397,13 +405,15 @@
     memo = rvalue.copy_memo()
     jitstate2 = jitstate.split(later_builder, resumepoint, greens_gv, memo)
     if ptrbox is not None:
-        ptrbox.learn_nonzeroness(jitstate, nonzeroness = True ^ reverse)
+        ok = ptrbox.learn_nonzeroness(jitstate, nonzeroness = True ^ reverse)
+        assert ok
         try:
             copybox = memo.boxes[ptrbox]
         except KeyError:
             pass
         else:
-            copybox.learn_nonzeroness(jitstate2, nonzeroness = reverse)
+            ok = copybox.learn_nonzeroness(jitstate2, nonzeroness = reverse)
+            assert ok
     if ll_evalue:
         jitstate2.residual_ll_exception(ll_evalue)
     if resuming is None:
@@ -524,8 +534,11 @@
     jitstate.exc_value_box = box
 
 def setexception(jitstate, typebox, valuebox):
-    typebox .learn_nonzeroness(jitstate, True)
-    valuebox.learn_nonzeroness(jitstate, True)
+    ok1 = typebox .learn_nonzeroness(jitstate, True)
+    ok2 = valuebox.learn_nonzeroness(jitstate, True)
+    assert ok1 & ok2       # probably... maybe it's false but it would be
+                           # nice to see what kind of contrieved code can
+                           # make this fail :-)
     jitstate.exc_type_box = typebox
     jitstate.exc_value_box = valuebox
 

Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/rvalue.py	Sat Mar 17 13:09:28 2007
@@ -194,17 +194,19 @@
         self.known_nonzero = known_nonzero
 
     def learn_nonzeroness(self, jitstate, nonzeroness):
+        ok = True
         if nonzeroness:
             if self.is_constant():
-                assert self.known_nonzero   # already
+                ok = self.known_nonzero   # not ok if constant zero
             else:
                 self.known_nonzero = True
         else:
             if self.is_constant():
-                assert not self.genvar.revealconst(llmemory.Address)
+                ok = not self.genvar.revealconst(llmemory.Address) # ok if null
             else:
                 gv_null = jitstate.curbuilder.rgenop.genzeroconst(self.kind)
                 self.setgenvar_hint(gv_null, known_nonzero=False)
+        return ok
 
     def __repr__(self):
         if not self.genvar and self.content is not None:

Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_timeshift.py	Sat Mar 17 13:09:28 2007
@@ -1531,7 +1531,6 @@
         self.check_insns({})
 
     def test_nonzeroness_assert_while_compiling(self):
-        import py; py.test.skip("in-progress")
         class X:
             pass
         class Y:
@@ -1563,7 +1562,6 @@
         assert res == -7
 
     def test_segfault_while_compiling(self):
-        import py; py.test.skip("in-progress")
         class X:
             pass
         class Y:

Modified: pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/jit/timeshifter/test/test_vlist.py	Sat Mar 17 13:09:28 2007
@@ -158,7 +158,6 @@
         self.check_insns({})
 
     def test_bogus_index_while_compiling(self):
-        import py; py.test.skip("in-progress")
         class Y:
             pass
 

Modified: pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rdict.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rdict.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/rpython/lltypesystem/rdict.py	Sat Mar 17 13:09:28 2007
@@ -397,6 +397,7 @@
     else: 
         raise KeyError 
 ll_dict_getitem.oopspec = 'dict.getitem(d, key)'
+ll_dict_getitem.oopargcheck = lambda d, key: bool(d)
 
 def ll_dict_setitem(d, key, value):
     hash = d.keyhash(key)
@@ -736,3 +737,4 @@
     entry = ll_dict_lookup(d, key, d.keyhash(key))
     return entry.valid()
 ll_contains.oopspec = 'dict.contains(d, key)'
+ll_contains.oopargcheck = lambda d, key: bool(d)

Modified: pypy/branch/jit-virtual-world/pypy/rpython/rlist.py
==============================================================================
--- pypy/branch/jit-virtual-world/pypy/rpython/rlist.py	(original)
+++ pypy/branch/jit-virtual-world/pypy/rpython/rlist.py	Sat Mar 17 13:09:28 2007
@@ -464,11 +464,13 @@
 def ll_len(l):
     return l.ll_length()
 ll_len.oopspec = 'list.len(l)'
+ll_len.oopargcheck = lambda l: bool(l)
 
 def ll_list_is_true(l):
     # check if a list is True, allowing for None
     return bool(l) and l.ll_length() != 0
 ll_list_is_true.oopspec = 'list.nonzero(l)'
+ll_list_is_true.oopargcheck = lambda l: True
 
 def ll_append(l, newitem):
     length = l.ll_length()
@@ -601,6 +603,8 @@
         debug_assert(index < l.ll_length(), "list getitem index out of bound")
     return l.ll_getitem_fast(index)
 ll_getitem_nonneg.oopspec = 'list.getitem(l, index)'
+ll_getitem_nonneg.oopargcheck = lambda l, index: (bool(l) and
+                                                  0 <= index < l.ll_length())
 
 def ll_getitem(func, l, index):
     length = l.ll_length()
@@ -614,6 +618,8 @@
         debug_assert(index < length, "list getitem index out of bound")
     return l.ll_getitem_fast(index)
 ll_getitem.oopspec = 'list.getitem(l, index)'
+ll_getitem.oopargcheck = lambda l, index: (bool(l) and -l.ll_length() <=
+                                                       index < l.ll_length())
 
 def ll_setitem_nonneg(func, l, index, newitem):
     debug_assert(index >= 0, "unexpectedly negative list setitem index")



More information about the Pypy-commit mailing list