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

arigo at codespeak.net arigo at codespeak.net
Sun May 7 13:35:59 CEST 2006


Author: arigo
Date: Sun May  7 13:35:53 2006
New Revision: 26929

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/support.py
   pypy/dist/pypy/translator/backendopt/inline.py
   pypy/dist/pypy/translator/c/test/test_newgc.py
Log:
(pedronis, arigo)
* review test_newgc for the real intention being the gc__collect()
  places.
* fix two minor but segfaulting bugs in the gc.
* functions with an attribute 'dont_inline=True' are never inlined.


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Sun May  7 13:35:53 2006
@@ -1068,8 +1068,11 @@
         s_gc = self.translator.annotator.bookkeeper.valueoftype(self.gcdata.GCClass)
         r_gc = self.translator.rtyper.getrepr(s_gc)
         const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
-        return [SpaceOperation(
-                    "direct_call", [self.collect_ptr, const_gc], op.result)]
+        newop = SpaceOperation(
+                    "direct_call", [self.collect_ptr, const_gc], op.result)
+        ops, index = self.protect_roots(newop, livevars, block,
+                                        block.operations.index(op))
+        return ops
 
     def push_alive_nopyobj(self, var):
         return []

Modified: pypy/dist/pypy/rpython/memory/support.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/support.py	(original)
+++ pypy/dist/pypy/rpython/memory/support.py	Sun May  7 13:35:53 2006
@@ -31,12 +31,12 @@
         _alloc_flavor_ = "raw"
         
         def __init__(self):
-            self.chunk = NULL
+            self.chunk = unused_chunks.get()
 
         def append(self, addr):
             if addr == NULL:
                 return
-            if self.chunk == NULL or self.chunk.signed[1] == chunk_size:
+            if self.chunk.signed[1] == chunk_size:
                 new = unused_chunks.get()
                 new.address[0] = self.chunk
                 new.signed[1] = 0

Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/inline.py	Sun May  7 13:35:53 2006
@@ -496,7 +496,7 @@
             static_instruction_count(graph))
 
 
-def static_callers(translator, ignore_primitives=False):
+def inlinable_static_callers(translator):
     result = []
     def build_call_graph(node):
         if isinstance(node, Block):
@@ -505,10 +505,12 @@
                     funcobj = op.args[0].value._obj
                     graph = getattr(funcobj, 'graph', None)
                     if graph is not None:
-                        if ignore_primitives:
-                            if getattr(getattr(funcobj, '_callable', None),
-                                       'suggested_primitive', False):
-                                continue
+                        if getattr(getattr(funcobj, '_callable', None),
+                                   'suggested_primitive', False):
+                            continue
+                        if getattr(getattr(funcobj, '_callable', None),
+                                   'dont_inline', False):
+                            continue
                         result.append((parentgraph, graph))
     for parentgraph in translator.graphs:
         traverse(build_call_graph, parentgraph)
@@ -522,7 +524,7 @@
     callers = {}     # {graph: {graphs-that-call-it}}
     callees = {}     # {graph: {graphs-that-it-calls}}
     if callgraph is None:
-        callgraph = static_callers(translator, ignore_primitives=True)
+        callgraph = inlinable_static_callers(translator)
     for graph1, graph2 in callgraph:
         callers.setdefault(graph2, {})[graph1] = True
         callees.setdefault(graph1, {})[graph2] = True

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	Sun May  7 13:35:53 2006
@@ -315,17 +315,24 @@
 class TestUsingFramework(AbstractTestClass):
     from pypy.translator.c.gc import FrameworkGcPolicy as gcpolicy
 
+    def test_empty_collect(self):
+        def f():
+            llop.gc__collect(lltype.Void)
+        fn = self.getcompiled(f)
+        fn()
+
     def test_framework_simple(self):
         def g(x): # cannot cause a collect
             return x + 1
         class A(object):
             pass
-        def f():
+        def make():
             a = A()
             a.b = g(1)
-            # this should trigger a couple of collections
-            for i in range(1000):
-                [A() for j in range(1000)]
+            return a
+        make.dont_inline = True
+        def f():
+            a = make()
             llop.gc__collect(lltype.Void)
             return a.b
         fn = self.getcompiled(f)
@@ -339,14 +346,15 @@
             pass
         class B(object):
             pass
-        def g(x): # can cause a collect
-            return B()
+        def g(x): # cause a collect
+            llop.gc__collect(lltype.Void)
+        g.dont_inline = True
         global_a = A()
         global_a.b = B()
         global_a.b.a = A()
         global_a.b.a.b = B()
         global_a.b.a.b.c = 1
-        def f():
+        def make():
             global_a.b.a.b.c = 40
             a = global_a.b.a
             b = a.b
@@ -354,8 +362,9 @@
             g(1)
             b0 = a.b
             b0.c = b.c = 42
-            for i in range(1000):
-                [A() for j in range(1000)]
+        make.dont_inline = True
+        def f():
+            make()
             llop.gc__collect(lltype.Void)
             return global_a.b.a.b.c
         fn = self.getcompiled(f)
@@ -375,16 +384,11 @@
             b.a = a
             b.othervalue = 5
         def g(a):
-            # this should trigger 3 collections
-            for i in range(1000000):
-                prepare(B(), -1)
-            llop.gc__collect(lltype.Void)
             llop.gc__collect(lltype.Void)
-            llop.gc__collect(lltype.Void)
-            # we need to prevent it getting inlined
-            if not a:
-                g(A())
+            for i in range(1000):
+                prepare(B(), -1)    # probably overwrites collected memory
             return a.value
+        g.dont_inline = True
         def f():
             b = B()
             prepare(b, 123)
@@ -446,8 +450,11 @@
                 self.y = y
         a = A(0)
         a.x = None
-        def f():
+        def make():
             a.x = A(42)
+        make.dont_inline = True
+        def f():
+            make()
             llop.gc__collect(lltype.Void)
             return a.x.y
         fn = self.getcompiled(f)
@@ -500,26 +507,23 @@
         
     def test_framework_opaque(self):
         A = lltype.GcStruct('A', ('value', lltype.Signed))
-        B = lltype.GcStruct('B', ('a', lltype.Ptr(A)))
         O = lltype.GcOpaqueType('test.framework')
-        b = lltype.malloc(B)
-        b.a = lltype.malloc(A)
 
         def gethidden(n):
             a = lltype.malloc(A)
             a.value = -n * 7
-            # we need to prevent it getting inlined
-            if n > 0:
-                gethidden(n-1)
             return lltype.cast_opaque_ptr(lltype.Ptr(O), a)
+        gethidden.dont_inline = True
         def reveal(o):
             return lltype.cast_opaque_ptr(lltype.Ptr(A), o)
+        def overwrite(a, i):
+            a.value = i
+        overwrite.dont_inline = True
         def f():
             o = gethidden(10)
-            # this should trigger a collection
-            for i in range(2500000):
-                b.a.value = i
-                b.a = lltype.malloc(A)
+            llop.gc__collect(lltype.Void)
+            for i in range(1000):    # overwrite freed memory
+                overwrite(lltype.malloc(A), i)
             a = reveal(o)
             return a.value
         fn = self.getcompiled(f)



More information about the Pypy-commit mailing list