Author: Armin Rigo <[email protected]>
Branch: concurrent-marksweep
Changeset: r48359:429e30ddfdfc
Date: 2011-10-23 16:02 +0200
http://bitbucket.org/pypy/pypy/changeset/429e30ddfdfc/

Log:    With this, targetgcbench works (but is terribly bad for now).

diff --git a/pypy/rpython/memory/gc/concurrentgen.py 
b/pypy/rpython/memory/gc/concurrentgen.py
--- a/pypy/rpython/memory/gc/concurrentgen.py
+++ b/pypy/rpython/memory/gc/concurrentgen.py
@@ -259,7 +259,11 @@
             self.force_scan(addr_struct)
 
     def assume_young_pointers(self, addr_struct):
-        pass # XXX
+        raise NotImplementedError
+
+    def writebarrier_before_copy(self, source_addr, dest_addr,
+                                 source_start, dest_start, length):
+        return False  # XXX implement
 
     def _init_writebarrier_logic(self):
         #
@@ -319,6 +323,7 @@
             self.flagged_objects.append(obj)
         #
         force_scan._dont_inline_ = True
+        force_scan._should_never_raise_ = True
         self.force_scan = force_scan
 
     def _barrier_add_extra(self, root, ignored):
@@ -443,7 +448,7 @@
         #
         # Add all old objects that have been written to since the last
         # time trigger_next_collection was called
-        self.flagged_objects.foreach(self._add_prebuilt_root, None)
+        self.flagged_objects.foreach(self._add_flagged_root, None)
         #
         # Clear this list
         self.flagged_objects.clear()
@@ -470,16 +475,26 @@
         self.execute_finalizers_ll()
 
     def _add_stack_root(self, root):
+        # NB. it's ok to edit 'gray_objects' from the mutator thread here,
+        # because the collector thread is not running yet
         obj = root.address[0]
         #debug_print("_add_stack_root", obj)
         self.get_mark(obj)
         self.collector.gray_objects.append(obj)
 
-    def _add_prebuilt_root(self, obj, ignored):
-        # NB. it's ok to edit 'gray_objects' from the mutator thread here,
-        # because the collector thread is not running yet
-        #debug_print("_add_prebuilt_root", obj)
-        self.get_mark(obj)
+    def _add_flagged_root(self, obj, ignored):
+        #debug_print("_add_flagged_root", obj)
+        #
+        # Important: the mark on 'obj' must be 'cym', otherwise it will not
+        # be scanned at all.  It should generally be, except in rare cases
+        # where it was reset to '#' by the collector thread.
+        mark = self.get_mark(obj)
+        if mark == MARK_BYTE_OLD:
+            self.set_mark(obj, self.current_young_marker)
+        else:
+            ll_assert(mark == self.current_young_marker,
+                      "add_flagged: bad mark")
+        #
         self.collector.gray_objects.append(obj)
 
     def debug_check_lists(self):
diff --git a/pypy/rpython/memory/gc/test/test_direct.py 
b/pypy/rpython/memory/gc/test/test_direct.py
--- a/pypy/rpython/memory/gc/test/test_direct.py
+++ b/pypy/rpython/memory/gc/test/test_direct.py
@@ -613,3 +613,37 @@
 class TestConcurrentGenGC(DirectGCTest):
     from pypy.rpython.memory.gc.concurrentgen \
             import ConcurrentGenGC as GCClass
+
+    def test_prebuilt_object_must_not_be_freed(self):
+        k = lltype.malloc(S, immortal=True)
+        k.x = 42
+        k.next = k2 = lltype.malloc(S, immortal=True)
+        k.next.x = 43
+        self.consider_constant(k)
+        self.consider_constant(k2)
+        all_s = []
+        all_s2 = []
+        #
+        for i in range(10):
+            s = self.malloc(S); s.x = 31
+            self.stackroots.append(s)
+            s2 = self.malloc(S); s2.x = 32
+            self.stackroots.append(s2)
+            #
+            all_s.append(s)
+            all_s2.append(s)
+            self.gc.collect(2)
+            #
+            self.write(k2, 'next', s)
+            self.write(k, 'next', s2)
+            self.gc.collect()
+            self.gc.collect()
+            assert k.x == 42
+            assert k.next.x == 32
+            assert k2.x == 43
+            assert k2.next.x == 31
+            #
+            for s in all_s:       # still all alive
+                assert s.x == 31
+            for s2 in all_s2:
+                assert s2.x == 31
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
@@ -323,7 +323,7 @@
                     getfn(GCClass.writebarrier_before_copy.im_func,
                     [s_gc] + [annmodel.SomeAddress()] * 2 +
                     [annmodel.SomeInteger()] * 3, annmodel.SomeBool())
-        elif GCClass.needs_write_barrier:
+        elif GCClass.needs_write_barrier or GCClass.needs_deletion_barrier:
             raise NotImplementedError("GC needs write barrier, but does not 
provide writebarrier_before_copy functionality")
 
         # in some GCs we can inline the common case of
diff --git a/pypy/translator/c/src/debug_lltrace.h 
b/pypy/translator/c/src/debug_lltrace.h
--- a/pypy/translator/c/src/debug_lltrace.h
+++ b/pypy/translator/c/src/debug_lltrace.h
@@ -12,6 +12,13 @@
 #  endif
 
 
+/* enable this for sending it out to stderr
+#undef RPyTraceSet
+#define RPyTraceSet(field, n)  {fprintf(stderr,"s %p->%p\n",\
+                                &(field),(void*)(long)field);}
+*/
+
+
 #else /*******************************************************/
 
 #  include "src/atomic_ops.h"
diff --git a/pypy/translator/c/test/test_newgc.py 
b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -1541,3 +1541,7 @@
 class TestMostlyConcurrentMarkSweepGC(TestUsingFramework):
     gcpolicy = "concurrentms"
     repetitions = 100
+
+class TestConcurrentGenGC(TestUsingFramework):
+    gcpolicy = "concurrentgen"
+    repetitions = 100
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to