[pypy-svn] r79305 - in pypy/branch/jit-free/pypy: rpython/memory/gc translator/c/test

arigo at codespeak.net arigo at codespeak.net
Sat Nov 20 16:34:07 CET 2010


Author: arigo
Date: Sat Nov 20 16:34:06 2010
New Revision: 79305

Modified:
   pypy/branch/jit-free/pypy/rpython/memory/gc/inspector.py
   pypy/branch/jit-free/pypy/translator/c/test/test_newgc.py
Log:
Improve the test, and fix.


Modified: pypy/branch/jit-free/pypy/rpython/memory/gc/inspector.py
==============================================================================
--- pypy/branch/jit-free/pypy/rpython/memory/gc/inspector.py	(original)
+++ pypy/branch/jit-free/pypy/rpython/memory/gc/inspector.py	Sat Nov 20 16:34:06 2010
@@ -119,8 +119,6 @@
     def delete(self):
         if self.gcflag == 0:
             self.seen.delete()
-        else:
-            self.clear_gcflag_again()
         self.pending.delete()
         lltype.free(self.writebuffer, flavor='raw')
         free_non_gc_object(self)
@@ -145,6 +143,8 @@
             self.flush()
     write._always_inline_ = True
 
+    # ----------
+
     def write_marker(self):
         self.write(0)
         self.write(0)
@@ -188,30 +188,50 @@
         while pending.non_empty():
             self.writeobj(pending.pop())
 
-    def clear_gcflag_again(self):
-        self.gc.enumerate_all_roots(_hd_clear_root, self)
-        pending = self.pending
-        while pending.non_empty():
-            self.clear(pending.pop())
+    # ----------
+    # A simplified copy of the above, to make sure we walk again all the
+    # objects to clear the 'gcflag'.
+
+    def unwriteobj(self, obj):
+        gc = self.gc
+        gc.trace(obj, self._unwriteref, None)
+
+    def _unwriteref(self, pointer, _):
+        obj = pointer.address[0]
+        self.unadd(obj)
 
-    def clear(self, obj):
+    def unadd(self, obj):
         assert self.gcflag != 0
         hdr = self.gc.header(obj)
         if (hdr.tid & self.gcflag) != 0:
             hdr.tid &= ~self.gcflag
             self.pending.append(obj)
 
+    def clear_gcflag_again(self):
+        self.gc.enumerate_all_roots(_hd_unadd_root, self)
+        pendingroots = self.pending
+        self.pending = AddressStack()
+        self.unwalk(pendingroots)
+        pendingroots.delete()
+
+    def unwalk(self, pending):
+        while pending.non_empty():
+            self.unwriteobj(pending.pop())
+
 def _hd_add_root(obj, heap_dumper):
     heap_dumper.add(obj)
 
-def _hd_clear_root(obj, heap_dumper):
-    heap_dumper.clear(obj)
+def _hd_unadd_root(obj, heap_dumper):
+    heap_dumper.unadd(obj)
 
 def dump_rpy_heap(gc, fd):
     heapdumper = HeapDumper(gc, fd)
     heapdumper.add_roots()
     heapdumper.walk(heapdumper.pending)
     heapdumper.flush()
+    if heapdumper.gcflag != 0:
+        heapdumper.clear_gcflag_again()
+        heapdumper.unwalk(heapdumper.pending)
     heapdumper.delete()
     return True
 

Modified: pypy/branch/jit-free/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/jit-free/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/branch/jit-free/pypy/translator/c/test/test_newgc.py	Sat Nov 20 16:34:06 2010
@@ -1064,14 +1064,16 @@
     def test_get_rpy_type_index(self):
         self.run("get_rpy_type_index")
 
-    filename_dump = str(udir.join('test_dump_rpy_heap'))
+    filename1_dump = str(udir.join('test_dump_rpy_heap.1'))
+    filename2_dump = str(udir.join('test_dump_rpy_heap.2'))
     def define_dump_rpy_heap(self):
         U = lltype.GcForwardReference()
         U.become(lltype.GcStruct('U', ('next', lltype.Ptr(U)),
                                  ('x', lltype.Signed)))
         S = lltype.GcStruct('S', ('u', lltype.Ptr(U)))
         A = lltype.GcArray(lltype.Ptr(S))
-        filename = self.filename_dump
+        filename1 = self.filename1_dump
+        filename2 = self.filename2_dump
 
         def fn():
             s = lltype.malloc(S)
@@ -1081,20 +1083,31 @@
             a = lltype.malloc(A, 1000)
             s2 = lltype.malloc(S)
             #
-            fd = os.open(filename, os.O_WRONLY | os.O_CREAT, 0666)
-            rgc.dump_rpy_heap(fd)
+            fd1 = os.open(filename1, os.O_WRONLY | os.O_CREAT, 0666)
+            fd2 = os.open(filename2, os.O_WRONLY | os.O_CREAT, 0666)
+            rgc.dump_rpy_heap(fd1)
+            rgc.dump_rpy_heap(fd2)      # try twice in a row
             keepalive_until_here(s2)
             keepalive_until_here(s)
             keepalive_until_here(a)
-            os.close(fd)
+            os.close(fd1)
+            os.close(fd2)
             return 0
 
         return fn
 
     def test_dump_rpy_heap(self):
         self.run("dump_rpy_heap")
-        assert os.path.exists(self.filename_dump)
-        assert os.path.getsize(self.filename_dump) > 64
+        for fn in [self.filename1_dump, self.filename2_dump]:
+            assert os.path.exists(fn)
+            assert os.path.getsize(fn) > 64
+        f = open(self.filename1_dump)
+        data1 = f.read()
+        f.close()
+        f = open(self.filename2_dump)
+        data2 = f.read()
+        f.close()
+        assert data1 == data2
 
     filename_dump_typeids_z = str(udir.join('test_typeids_z'))
     def define_write_typeids_z(self):



More information about the Pypy-commit mailing list