[pypy-svn] r70926 - in pypy/branch/gc-huge-list/pypy/rpython/memory/gc: . test

arigo at codespeak.net arigo at codespeak.net
Wed Jan 27 16:50:37 CET 2010


Author: arigo
Date: Wed Jan 27 16:50:37 2010
New Revision: 70926

Modified:
   pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py
   pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py
   pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py
Log:
(arigo, fijal)
Break everything. Start supporting card marking by marking cards instead of
listing objects in oldobjs_pointing_to_young


Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/generation.py	Wed Jan 27 16:50:37 2010
@@ -433,9 +433,9 @@
     #  "if newvalue.int0 & JIT_WB_IF_FLAG: remember_young_pointer()")
     JIT_WB_IF_FLAG = GCFLAG_NO_YOUNG_PTRS
 
-    def write_barrier(self, newvalue, addr_struct):
+    def write_barrier(self, newvalue, addr_struct, offset):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
-            self.remember_young_pointer(addr_struct, newvalue)
+            self.remember_young_pointer(addr_struct, newvalue, offset)
 
     def _setup_wb(self):
         # The purpose of attaching remember_young_pointer to the instance
@@ -445,7 +445,7 @@
         # For x86, there is also an extra requirement: when the JIT calls
         # remember_young_pointer(), it assumes that it will not touch the SSE
         # registers, so it does not save and restore them (that's a *hack*!).
-        def remember_young_pointer(addr_struct, addr):
+        def remember_young_pointer(addr_struct, addr, offset):
             #llop.debug_print(lltype.Void, "\tremember_young_pointer",
             #                 addr_struct, "<-", addr)
             ll_assert(not self.is_in_nursery(addr_struct),
@@ -457,8 +457,7 @@
                 not self.is_valid_gc_object(addr)):
                 return
             if self.is_in_nursery(addr):
-                self.old_objects_pointing_to_young.append(addr_struct)
-                self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+                self.remember_pointer_to_nursery(addr_struct, offset)
             elif (not self.config.taggedpointers and
                   not self.is_valid_gc_object(addr)):
                 return
@@ -466,6 +465,10 @@
         remember_young_pointer._dont_inline_ = True
         self.remember_young_pointer = remember_young_pointer
 
+    def remember_pointer_to_nursery(self, addr_struct, offset):
+        self.old_objects_pointing_to_young.append(addr_struct)
+        self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+
     def write_into_last_generation_obj(self, addr_struct, addr):
         objhdr = self.header(addr_struct)
         if objhdr.tid & GCFLAG_NO_HEAP_PTRS:

Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py	(original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/hybrid.py	Wed Jan 27 16:50:37 2010
@@ -285,6 +285,21 @@
         llarena.arena_reserve(result, objectsize)
         return result
 
+    def remember_pointer_to_nursery(self, addr_struct, offset):
+        if self.header(addr_struct).tid & GCFLAG_CARDMARKS:
+            # XXX we might want to store this object in the list of old
+            #     objects pointing to young. For now we simply walk all
+            #     huge lists possibly containing gc pointers for each
+            #     nursery collection
+            # Mark the correct card, don't clear GCFLAG_NO_YOUNG_PTRS flag.
+            # Note that 'offset' does not include the size_gc_header.
+            size_gc_header = self.gcheaderbuilder.size_gc_header
+            num = raw_malloc_usage(offset) / self.card_size
+            addr = (addr_struct - size_gc_header + llarena.negative_byte_index(num>>3))
+            addr.char[0] = chr(ord(addr.char[0]) | (1 << (num&7)))
+        else:
+            GenerationGC.remember_pointer_to_nursery(addr_struct, where_in_struct)
+
     def init_gc_object_immortal(self, addr, typeid,
                                 flags=(GCFLAG_NO_YOUNG_PTRS |
                                        GCFLAG_NO_HEAP_PTRS |

Modified: pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py	(original)
+++ pypy/branch/gc-huge-list/pypy/rpython/memory/gc/test/test_direct.py	Wed Jan 27 16:50:37 2010
@@ -82,14 +82,16 @@
         if self.gc.needs_write_barrier:
             newaddr = llmemory.cast_ptr_to_adr(newvalue)
             addr_struct = llmemory.cast_ptr_to_adr(p)
-            self.gc.write_barrier(newaddr, addr_struct)
+            offset = llmemory.offsetof(lltype.typeOf(p).TO, fieldname)
+            self.gc.write_barrier(newaddr, addr_struct, offset)
         setattr(p, fieldname, newvalue)
 
     def writearray(self, p, index, newvalue):
         if self.gc.needs_write_barrier:
             newaddr = llmemory.cast_ptr_to_adr(newvalue)
             addr_struct = llmemory.cast_ptr_to_adr(p)
-            self.gc.write_barrier(newaddr, addr_struct)
+            offset = llmemory.itemoffsetof(lltype.typeOf(p).TO, index)
+            self.gc.write_barrier(newaddr, addr_struct, offset)
         p[index] = newvalue
 
     def malloc(self, TYPE, n=None):
@@ -339,6 +341,7 @@
                  'large_object': 12,
                  'large_object_gcptrs': 12,
                  'generation3_collect_threshold': 5,
+                 'card_size': 12,
                  }
 
     def test_collect_gen(self):
@@ -376,6 +379,33 @@
         assert calls == [('semispace_collect', True)]
         calls = []
 
+    def test_card_marking(self):
+        from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS
+        from pypy.rpython.memory.gc.hybrid import GCFLAG_CARDMARKS
+        from pypy.rpython.lltypesystem import llarena
+        gc = self.gc 
+        
+        addr = llmemory.cast_ptr_to_adr(gc.malloc_varsize_slowpath(self.get_type_id(VAR), 12))
+        size_gc_header = gc.gcheaderbuilder.size_gc_header
+        obj = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(VAR))
+        assert gc.header(addr).tid & GCFLAG_CARDMARKS
+        assert gc.header(addr).tid & GCFLAG_NO_YOUNG_PTRS
+        for i in range(4):
+            assert (addr - size_gc_header + llarena.NegativeByteIndex(i)).char[0] == chr(0)
+
+        p = self.malloc(S)
+        self.writearray(obj, 7, p)
+        # the object looks like:
+        #    [size item0 item1][item2 item3 item4][item5 item6 item7][etc.]
+
+        assert gc.header(addr).tid & GCFLAG_CARDMARKS
+        assert gc.header(addr).tid & GCFLAG_NO_YOUNG_PTRS
+        for i in range(4):
+            res = (addr - size_gc_header + llarena.NegativeByteIndex(i)).char[0]
+            if i == 0:
+                assert res == chr(1<<2)
+            else:
+                assert res == chr(0)
 
 class TestMarkCompactGC(DirectGCTest):
     from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass



More information about the Pypy-commit mailing list