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

arigo at codespeak.net arigo at codespeak.net
Wed Jan 27 20:33:35 CET 2010


Author: arigo
Date: Wed Jan 27 20:33:34 2010
New Revision: 70931

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:
General progress.
I think I have reviewed all places that need to be fixed;
there are two places with an XXXX left.


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 20:33:34 2010
@@ -477,6 +477,7 @@
                 self.last_generation_root_objects.append(addr_struct)
 
     def assume_young_pointers(self, addr_struct):
+        XXXX
         objhdr = self.header(addr_struct)
         if objhdr.tid & GCFLAG_NO_YOUNG_PTRS:
             self.old_objects_pointing_to_young.append(addr_struct)
@@ -491,6 +492,7 @@
         one of the following flags a bit too eagerly, which means we'll have
         a bit more objects to track, but being on the safe side.
         """
+        XXXX
         source_hdr = self.header(source_addr)
         dest_hdr = self.header(dest_addr)
         if dest_hdr.tid & GCFLAG_NO_YOUNG_PTRS == 0:
@@ -556,7 +558,7 @@
         if tid & GCFLAG_NO_YOUNG_PTRS:
             ll_assert(not self.is_in_nursery(obj),
                       "nursery object with GCFLAG_NO_YOUNG_PTRS")
-            self.trace(obj, self._debug_no_nursery_pointer, None)
+            self.debug_check_object_no_nursery_pointer(obj)
         elif not self.is_in_nursery(obj):
             ll_assert(self._d_oopty.contains(obj),
                       "missing from old_objects_pointing_to_young")
@@ -568,6 +570,9 @@
             ll_assert(self._d_lgro.contains(obj),
                       "missing from last_generation_root_objects")
 
+    def debug_check_object_no_nursery_pointer(self, obj):
+        self.trace(obj, self._debug_no_nursery_pointer, None)
+
     def _debug_no_nursery_pointer(self, root, ignored):
         ll_assert(not self.is_in_nursery(root.address[0]),
                   "GCFLAG_NO_YOUNG_PTRS but found a young pointer")

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 20:33:34 2010
@@ -58,7 +58,8 @@
 
 GCFLAG_UNVISITED = GenerationGC.first_unused_gcflag << 0
 GCFLAG_CARDMARKS = GenerationGC.first_unused_gcflag << 1
-_gcflag_next_bit = GenerationGC.first_unused_gcflag << 2
+GCFLAG_CARDMARK_SET = GenerationGC.first_unused_gcflag << 2
+_gcflag_next_bit = GenerationGC.first_unused_gcflag << 3
 GCFLAG_AGE_ONE   = _gcflag_next_bit
 GCFLAG_AGE_MAX   = _gcflag_next_bit * MAX_SEMISPACE_AGE
 GCFLAG_AGE_MASK  = 0
@@ -491,6 +492,8 @@
                     dead_size+=raw_malloc_usage(self.get_size_incl_hash(obj))
                 addr = obj - size_gc_header
                 if tid & GCFLAG_CARDMARKS:
+                    ll_assert(tid & GCFLAG_CARDMARK_SET == 0,
+                              "unexpected flag CARDMARK_SET when freeing")
                     objectsize = self.get_size_incl_hash(obj)
                     addr += llarena.negative_byte_index(
                         self.get_extra_bitarray_size(objectsize) - 1)
@@ -566,7 +569,8 @@
         return raw_malloc_usage(bitarraysize)
 
     def remember_pointer_to_nursery(self, addr_struct, offset):
-        if self.header(addr_struct).tid & GCFLAG_CARDMARKS:
+        hdr = self.header(addr_struct)
+        if hdr.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
@@ -576,9 +580,44 @@
             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)
+            flag = 1 << (num&7)
+            value = ord(addr.char[0])
+            if value & flag == 0:
+                addr.char[0] = chr(value | flag)
+                if hdr.tid & GCFLAG_CARDMARK_SET == 0:
+                    hdr.tid |= GCFLAG_CARDMARK_SET
+                    self.old_objects_pointing_to_young.append(addr_struct)
+        else:
+            GenerationGC.remember_pointer_to_nursery(self, addr_struct, offset)
+
+    def reset_young_gcflags(self):
+        oldlist = self.old_objects_pointing_to_young
+        while oldlist.non_empty():
+            obj = oldlist.pop()
+            hdr = self.header(obj)
+            if hdr.tid & GCFLAG_CARDMARK_SET:
+                ll_assert(hdr.tid & GCFLAG_NO_YOUNG_PTRS,
+                          "invalid combination: CARDMARK_SET&!NO_YOUNG_PTRS")
+                self.clean_marked_cards(obj)
+            else:
+                hdr.tid |= GCFLAG_NO_YOUNG_PTRS
+
+    def collect_oldrefs_to_nursery(self):
+        count = 0
+        oldlist = self.old_objects_pointing_to_young
+        while oldlist.non_empty():
+            count += 1
+            obj = oldlist.pop()
+            hdr = self.header(obj)
+            if hdr.tid & GCFLAG_CARDMARK_SET:
+                ll_assert(hdr.tid & GCFLAG_NO_YOUNG_PTRS,
+                          "invalid combination: CARDMARK_SET&!NO_YOUNG_PTRS")
+                self.foreach_marked_card(obj, self._trace_drag_out, None)
+                self.clean_marked_cards(obj)
+            else:
+                hdr.tid |= GCFLAG_NO_YOUNG_PTRS
+                self.trace_and_drag_out_of_nursery(obj)
+        debug_print("collect_oldrefs_to_nursery", count)
 
     def startoffset_from_cardno(self, typeid, cardno):
         start = cardno * self.card_size
@@ -608,7 +647,7 @@
             item += itemlength
     trace_marked_card._annspecialcase_ = 'specialize:arg(3)'
 
-    def foreach_marked_card_and_clean(self, obj, callback, arg):
+    def foreach_marked_card(self, obj, callback, arg):
         bytearraysize = self.get_extra_bitarray_size(self.get_size_incl_hash(obj))
         size_gc_header = self.gcheaderbuilder.size_gc_header
         bytearrayaddr = obj - size_gc_header
@@ -617,7 +656,6 @@
             nextaddr = bytearrayaddr + llarena.negative_byte_index(i)
             next = ord(nextaddr.char[0])
             if next != 0:
-                nextaddr.char[0] = chr(0)
                 base = i << 3
                 if next & 0x01: self.trace_marked_card(obj, base | 0, callback, arg)
                 if next & 0x02: self.trace_marked_card(obj, base | 1, callback, arg)
@@ -628,7 +666,33 @@
                 if next & 0x40: self.trace_marked_card(obj, base | 6, callback, arg)
                 if next & 0x80: self.trace_marked_card(obj, base | 7, callback, arg)
             i += 1
-    foreach_marked_card_and_clean._annspecialcase_ = 'specialize:arg(2)'
+    foreach_marked_card._annspecialcase_ = 'specialize:arg(2)'
+
+    def clean_marked_cards(self, obj):
+        self.header(obj).tid &= ~GCFLAG_CARDMARK_SET
+        bytearraysize = self.get_extra_bitarray_size(self.get_size_incl_hash(obj))
+        size_gc_header = self.gcheaderbuilder.size_gc_header
+        bytearrayaddr = obj - size_gc_header
+        i = 0
+        while i < bytearraysize:
+            nextaddr = bytearrayaddr + llarena.negative_byte_index(i)
+            nextaddr.char[0] = chr(0)
+            i += 1
+
+    def debug_check_object_no_nursery_pointer(self, obj):
+        tid = self.header(obj).tid
+        if tid & GCFLAG_CARDMARKS:
+            pass
+        else:
+            GenerationGC.debug_check_object_no_nursery_pointer(self, obj)
+
+    def _debug_check_flag_1(self, obj, ignored):
+        tid = self.header(obj).tid
+        if tid & GCFLAG_CARDMARKS:
+            ll_assert(tid & GCFLAG_NO_YOUNG_PTRS,
+                      "invalid combination: CARDMARK_SET&!NO_YOUNG_PTRS")
+        else:
+            GenerationGC._debug_check_flag_1(self, obj, ignored)
 
     # _________________________________________________________
 

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 20:33:34 2010
@@ -415,9 +415,11 @@
         old_trace = gc.trace_marked_card
         gc.trace_marked_card = callback
 
-        gc.foreach_marked_card_and_clean(addr, 123, 456)
+        gc.foreach_marked_card(addr, 123, 456)
         assert marked_cards == [2]
         gc.trace_marked_card = old_trace
+        assert (addr - size_gc_header + llarena.NegativeByteIndex(0)).char[0] == chr(1<<2)
+        gc.clean_marked_cards(addr)
         assert (addr - size_gc_header + llarena.NegativeByteIndex(0)).char[0] == chr(0)
 
         objs = []
@@ -426,7 +428,8 @@
             # so we need to read that array item
             objs.append(obj.address[0])
         self.writearray(obj, 7, p)
-        gc.foreach_marked_card_and_clean(addr, callback, None)
+        gc.foreach_marked_card(addr, callback, None)
+        gc.clean_marked_cards(addr)
 
         addrp = llmemory.cast_ptr_to_adr(p)
         assert objs == [addrp]
@@ -435,7 +438,8 @@
         assert (addr - size_gc_header + llarena.NegativeByteIndex(0)).char[0] == chr(1<<2 | 1<<3)
 
         del objs[:]
-        gc.foreach_marked_card_and_clean(addr, callback, None)
+        gc.foreach_marked_card(addr, callback, None)
+        gc.clean_marked_cards(addr)
         assert objs == [addrp, addrp]
 
         self.writearray(obj, 0, p)
@@ -443,7 +447,8 @@
         assert (addr - size_gc_header + llarena.NegativeByteIndex(0)).char[0] == chr(1<<0 | 1<<4)
 
         del objs[:]
-        gc.foreach_marked_card_and_clean(addr, callback, None)
+        gc.foreach_marked_card(addr, callback, None)
+        gc.clean_marked_cards(addr)
         assert objs == [addrp, addrp]
 
 class TestMarkCompactGC(DirectGCTest):



More information about the Pypy-commit mailing list