[pypy-svn] r77463 - in pypy/trunk/pypy/rpython/memory: gc gctransform test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 29 13:04:24 CEST 2010


Author: arigo
Date: Wed Sep 29 13:04:22 2010
New Revision: 77463

Modified:
   pypy/trunk/pypy/rpython/memory/gc/base.py
   pypy/trunk/pypy/rpython/memory/gc/minimark.py
   pypy/trunk/pypy/rpython/memory/gctransform/framework.py
   pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py
Log:
find_clean_setarrayitems() is not a valid optimization in
the presence of card marking!  Disable it in this case.


Modified: pypy/trunk/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/trunk/pypy/rpython/memory/gc/base.py	Wed Sep 29 13:04:22 2010
@@ -39,6 +39,9 @@
     def can_malloc_nonmovable(self):
         return not self.moving_gc
 
+    def can_optimize_clean_setarrayitems(self):
+        return True     # False in case of card marking
+
     # The following flag enables costly consistency checks after each
     # collection.  It is automatically set to True by test_gc.py.  The
     # checking logic is translatable, so the flag can be set to True

Modified: pypy/trunk/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gc/minimark.py	(original)
+++ pypy/trunk/pypy/rpython/memory/gc/minimark.py	Wed Sep 29 13:04:22 2010
@@ -564,6 +564,11 @@
     def can_malloc_nonmovable(self):
         return True
 
+    def can_optimize_clean_setarrayitems(self):
+        if self.card_page_indices > 0:
+            return False
+        return MovingGCBase.can_optimize_clean_setarrayitems(self)
+
     def can_move(self, obj):
         """Overrides the parent can_move()."""
         return self.is_in_nursery(obj)
@@ -688,8 +693,9 @@
                   "unexpected GCFLAG_CARDS_SET")
         # if the GCFLAG_HAS_CARDS is set, check that all bits are zero now
         if self.header(obj).tid & GCFLAG_HAS_CARDS:
-            ll_assert(self.card_page_indices > 0,
-                      "GCFLAG_HAS_CARDS but not using card marking")
+            if self.card_page_indices <= 0:
+                ll_assert(False, "GCFLAG_HAS_CARDS but not using card marking")
+                return
             typeid = self.get_type_id(obj)
             ll_assert(self.has_gcptr_in_varsize(typeid),
                       "GCFLAG_HAS_CARDS but not has_gcptr_in_varsize")
@@ -961,6 +967,8 @@
                         if cardbyte & 1:
                             if interval_stop > length:
                                 interval_stop = length
+                                ll_assert(cardbyte <= 1 and bytes == 0,
+                                          "premature end of object")
                             self.trace_and_drag_out_of_nursery_partial(
                                 obj, interval_start, interval_stop)
                         #

Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py	Wed Sep 29 13:04:22 2010
@@ -606,8 +606,10 @@
             
         if self.write_barrier_ptr:
             self.clean_sets = (
-                find_clean_setarrayitems(self.collect_analyzer, graph).union(
-                find_initializing_stores(self.collect_analyzer, graph)))
+                find_initializing_stores(self.collect_analyzer, graph))
+            if self.gcdata.gc.can_optimize_clean_setarrayitems():
+                self.clean_sets = self.clean_sets.union(
+                    find_clean_setarrayitems(self.collect_analyzer, graph))
         super(FrameworkGCTransformer, self).transform_graph(graph)
         if self.write_barrier_ptr:
             self.clean_sets = None

Modified: pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py	Wed Sep 29 13:04:22 2010
@@ -1474,10 +1474,37 @@
                          'page_size': 16*WORD,
                          'arena_size': 64*WORD,
                          'small_request_threshold': 5*WORD,
+                         'large_object': 8*WORD,
+                         'large_object_gcptrs': 10*WORD,
                          'card_page_indices': 4,
                          }
             root_stack_depth = 200
 
+    def define_no_clean_setarrayitems(cls):
+        # The optimization find_clean_setarrayitems() in
+        # gctransformer/framework.py does not work with card marking.
+        # Check that it is turned off.
+        S = lltype.GcStruct('S', ('x', lltype.Signed))
+        A = lltype.GcArray(lltype.Ptr(S))
+        def sub(lst):
+            lst[15] = lltype.malloc(S)   # 'lst' is set the single mark "12-15"
+            lst[15].x = 123
+            lst[0] = lst[15]   # that would be a "clean_setarrayitem"
+        def f():
+            lst = lltype.malloc(A, 16)   # 16 > 10
+            rgc.collect()
+            sub(lst)
+            null = lltype.nullptr(S)
+            lst[15] = null     # clear, so that A() is only visible via lst[0]
+            rgc.collect()      # -> crash
+            return lst[0].x
+        return f
+
+    def test_no_clean_setarrayitems(self):
+        run = self.runner("no_clean_setarrayitems")
+        res = run([])
+        assert res == 123
+
 # ________________________________________________________________
 # tagged pointers
 



More information about the Pypy-commit mailing list