[pypy-commit] pypy concurrent-marksweep: Fixes: custom_trace support again. The issue is that it was called

arigo noreply at buildbot.pypy.org
Mon Oct 10 18:35:11 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: concurrent-marksweep
Changeset: r47922:295b1a9fe890
Date: 2011-10-10 18:34 +0200
http://bitbucket.org/pypy/pypy/changeset/295b1a9fe890/

Log:	Fixes: custom_trace support again. The issue is that it was called
	by an indirect_call() with no known target set --- and so it was
	assumed to be able to raise.

diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -675,6 +675,12 @@
             #log.warn("op_indirect_call with graphs=None:", f)
         return self.op_direct_call(f, *args)
 
+    def op_llcall_cannot_raise(self, llf, *args):
+        try:
+            return self.op_direct_call(llf, *args)
+        except LLException, e:
+            raise AssertionError("llcall_cannot_raise: raised %s" % e)
+
     def op_malloc(self, obj, flags):
         flavor = flags['flavor']
         zero = flags.get('zero', False)
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -186,6 +186,7 @@
 
     'direct_call':          LLOp(canraise=(Exception,)),
     'indirect_call':        LLOp(canraise=(Exception,)),
+    'llcall_cannot_raise':  LLOp(canrun=True),    # dangerous, use carefully!
 
     # __________ numeric operations __________
 
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
@@ -624,6 +624,13 @@
     from pypy.rlib.rtimer import read_timestamp
     return read_timestamp()
 
+def op_llcall_cannot_raise(llf, *args):
+    try:
+        return llf(*args)
+    except Exception, e:
+        raise AssertionError("llcall_cannot_raise: raised %s: %s" % (
+            e.__class__.__name__, e))
+
 # ____________________________________________________________
 
 def get_op_impl(opname):
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.debug import ll_assert
 from pypy.rpython.memory.gcheader import GCHeaderBuilder
 from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE
@@ -231,11 +232,12 @@
                     j += 1
                 item += itemlength
                 length -= 1
-        if self.has_custom_trace(typeid) and 0: # XXX XXX temporarily disabled
+        if self.has_custom_trace(typeid):
             generator = self.get_custom_trace(typeid)
             item = llmemory.NULL
             while True:
-                item = generator(obj, item)
+                item = llop.llcall_cannot_raise(llmemory.Address,
+                                                generator, obj, item)
                 if not item:
                     break
                 if self.points_to_valid_gc_object(item):
diff --git a/pypy/rpython/memory/gc/concurrentms.py b/pypy/rpython/memory/gc/concurrentms.py
--- a/pypy/rpython/memory/gc/concurrentms.py
+++ b/pypy/rpython/memory/gc/concurrentms.py
@@ -439,7 +439,7 @@
         return True
 
     def assume_young_pointers(self, addr_struct):
-        XXX
+        pass # XXX
 
     def _init_writebarrier_logic(self):
         #
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -1286,6 +1286,7 @@
         fptr = rtti._obj.custom_trace_funcptr
         if not hasattr(fptr._obj, 'graph'):
             ll_func = fptr._obj._callable
+            ll_func._should_never_raise_ = True
             fptr = self.transformer.annotate_finalizer(ll_func,
                     [llmemory.Address, llmemory.Address], llmemory.Address)
         return fptr
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -276,6 +276,7 @@
             else:
                 py.test.raises((RuntimeError, ArenaError),
                                self.interpret, f, [])
+                print "NOTE: The previous ArenaError, if any, is expected"
 
     def test_weakref(self):
         import weakref, gc
diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py
--- a/pypy/translator/c/funcgen.py
+++ b/pypy/translator/c/funcgen.py
@@ -462,14 +462,11 @@
         return self.generic_call(fn.concretetype, self.expr(fn),
                                  op.args[1:-1], op.result, op.args[-1].value)
 
-    def OP_ADR_CALL(self, op):
-        ARGTYPES = [v.concretetype for v in op.args[1:]]
-        RESTYPE = op.result.concretetype
-        FUNC = Ptr(FuncType(ARGTYPES, RESTYPE))
-        typename = self.db.gettype(FUNC)
-        fnaddr = op.args[0]
-        fnexpr = '((%s)%s)' % (cdecl(typename, ''), self.expr(fnaddr))
-        return self.generic_call(FUNC, fnexpr, op.args[1:], op.result)
+    def OP_LLCALL_CANNOT_RAISE(self, op):
+        fn = op.args[0]
+        res = self.generic_call(fn.concretetype, self.expr(fn),
+                                op.args[1:], op.result)
+        return res + ' /* llcall_cannot_raise */'
 
     # low-level operations
     def generic_get(self, op, sourceexpr):
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -378,18 +378,23 @@
         [v_obj, c_grpptr, c_skipoffset, c_vtableinfo] = op.args
         typename = funcgen.db.gettype(op.result.concretetype)
         tid_field = c_vtableinfo.value[2]
+        tid_offset = 0
+        if isinstance(tid_field, tuple):
+            tid_field, tid_offset = tid_field
         # Fish out the C name of the tid field.
         HDR = self.db.gctransformer.HDR
         hdr_node = self.db.gettypedefnode(HDR)
         fieldname = hdr_node.c_struct_field_name(tid_field)
+        #
+        tid = '%s->_gcheader.%s' % (funcgen.expr(v_obj), fieldname)
+        if tid_offset:
+            tid = '(%s >> %d)' % (tid, tid_offset)
         return (
-        '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->'
-            '_gcheader.%s, %s);'
+        '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s, %s);'
             % (funcgen.expr(op.result),
                cdecl(typename, ''),
                funcgen.expr(c_grpptr),
-               funcgen.expr(v_obj),
-               fieldname,
+               tid,
                funcgen.expr(c_skipoffset)))
 
     def OP_GC_ASSUME_YOUNG_POINTERS(self, funcgen, op):


More information about the pypy-commit mailing list