[pypy-svn] r26719 - in pypy/dist/pypy: rpython/memory translator translator/c/test

arigo at codespeak.net arigo at codespeak.net
Wed May 3 12:53:37 CEST 2006


Author: arigo
Date: Wed May  3 12:53:36 2006
New Revision: 26719

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/translator/c/test/test_genc.py
   pypy/dist/pypy/translator/c/test/test_newgc.py
   pypy/dist/pypy/translator/unsimplify.py
Log:
(pedronis, arigo)

Fixed another rare leak in gctransform.
Enabled malloc_counters() testing for most GenC tests.


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Wed May  3 12:53:36 2006
@@ -4,6 +4,7 @@
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, \
      c_last_exception, FunctionGraph, Block, Link, checkgraph
 from pypy.translator.unsimplify import insert_empty_block
+from pypy.translator.unsimplify import insert_empty_startblock
 from pypy.translator.translator import graphof
 from pypy.translator.backendopt.support import var_needsgc, needs_conservative_livevar_calculation
 from pypy.translator.backendopt import graphanalyze
@@ -67,7 +68,18 @@
             return
         self.seen_graphs[graph] = True
         self.links_to_split = {} # link -> vars to pop_alive across the link
-        
+
+        # add push_alives at the beginning of the graph
+        newops = []
+        for var in graph.startblock.inputargs:
+            if var_needsgc(var):
+                newops.extend(self.push_alive(var))
+        if newops:  # only to check if we are going to add any operation at all
+            insert_empty_startblock(None, graph)
+            for var in graph.startblock.inputargs:
+                if var_needsgc(var):
+                    graph.startblock.operations.extend(self.push_alive(var))
+
         for block in graph.iterblocks():
             self.transform_block(block)
         for link, livecounts in self.links_to_split.iteritems():
@@ -104,10 +116,6 @@
         newops = []
         livevars = [var for var in block.inputargs if var_needsgc(var)]
         newops = []
-        if block.isstartblock:
-            for var in block.inputargs:
-                if var_needsgc(var):
-                    newops.extend(self.push_alive(var))
         # XXX this is getting obscure.  Maybe we should use the basic
         # graph-transforming capabilities of the RTyper instead, as we
         # seem to run into all the same problems as the ones we already

Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py	Wed May  3 12:53:36 2006
@@ -46,10 +46,11 @@
         t.view()
     compiled_fn = getattr(module, entrypoint)
     def checking_fn(*args, **kwds):
-        res = compiled_fn(*args, **kwds)
-        mallocs, frees = module.malloc_counters()
-        assert mallocs == frees
-        return res
+        try:
+            return compiled_fn(*args, **kwds)
+        finally:
+            mallocs, frees = module.malloc_counters()
+            assert mallocs == frees
     return checking_fn
 
 def test_func_as_pyobject():

Modified: pypy/dist/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_newgc.py	Wed May  3 12:53:36 2006
@@ -12,8 +12,9 @@
 
 from pypy import conftest
 
-def compile_func(fn, inputtypes):
-    t = TranslationContext()
+def compile_func(fn, inputtypes, t=None):
+    if t is None:
+        t = TranslationContext()
     t.buildannotator().build_types(fn, inputtypes)
     t.buildrtyper().specialize()
     builder = genc.CExtModuleBuilder(t, fn, gcpolicy=gc.RefcountingGcPolicy)
@@ -193,6 +194,33 @@
     res = fn(1)
     assert res == 1
 
+def test_wrong_startblock_incref():
+    class B(object):
+        pass
+    def g(b):
+        while True:
+            b.x -= 10
+            if b.x < 0:
+                return b.x
+    def f(n):
+        b = B()
+        b.x = n
+        return g(b)
+
+    # XXX obscure: remove the first empty block in the graph of 'g'
+    t = TranslationContext()
+    graph = t.buildflowgraph(g)
+    assert graph.startblock.operations == []
+    graph.startblock = graph.startblock.exits[0].target
+    graph.startblock.isstartblock = True
+    from pypy.objspace.flow.model import checkgraph
+    checkgraph(graph)
+    t._prebuilt_graphs[g] = graph
+
+    fn = compile_func(f, [int], t)
+    res = fn(112)
+    assert res == -8
+
 class Weakrefable(object):
     __lifeline__ = None
 

Modified: pypy/dist/pypy/translator/unsimplify.py
==============================================================================
--- pypy/dist/pypy/translator/unsimplify.py	(original)
+++ pypy/dist/pypy/translator/unsimplify.py	Wed May  3 12:53:36 2006
@@ -35,6 +35,14 @@
     link.target = newblock
     return newblock
 
+def insert_empty_startblock(translator, graph):
+    vars = [copyvar(translator, v) for v in graph.startblock.inputargs]
+    newblock = Block(vars)
+    newblock.closeblock(Link(vars, graph.startblock))
+    graph.startblock.isstartblock = False
+    graph.startblock = newblock
+    graph.startblock.isstartblock = True
+
 def split_block(translator, block, index):
     """return a link where prevblock is the block leading up but excluding the
     index'th operation and target is a new block with the neccessary variables 



More information about the Pypy-commit mailing list