[pypy-svn] r77209 - in pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc: . test

arigo at codespeak.net arigo at codespeak.net
Mon Sep 20 17:40:04 CEST 2010


Author: arigo
Date: Mon Sep 20 17:40:01 2010
New Revision: 77209

Modified:
   pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py
   pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py
   pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
Log:
Reduce the arity and complexity of remember_young_pointer() methods.


Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py	(original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/generation.py	Mon Sep 20 17:40:01 2010
@@ -321,7 +321,7 @@
         addr = pointer.address[0]
         newaddr = self.copy(addr)
         pointer.address[0] = newaddr
-        self.write_into_last_generation_obj(obj, newaddr)
+        self.write_into_last_generation_obj(obj)
 
     # ____________________________________________________________
     # Implementation of nursery-only collections
@@ -452,11 +452,12 @@
     #  "if addr_struct.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, addr_struct):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
-            self.remember_young_pointer(addr_struct, newvalue)
+            self.remember_young_pointer(addr_struct)
 
     def _setup_wb(self):
+        DEBUG = self.DEBUG
         # The purpose of attaching remember_young_pointer to the instance
         # instead of keeping it as a regular method is to help the JIT call it.
         # Additionally, it makes the code in write_barrier() marginally smaller
@@ -464,33 +465,24 @@
         # 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):
             #llop.debug_print(lltype.Void, "\tremember_young_pointer",
             #                 addr_struct, "<-", addr)
-            ll_assert(not self.is_in_nursery(addr_struct),
-                         "nursery object with GCFLAG_NO_YOUNG_PTRS")
-            # if we have tagged pointers around, we first need to check whether
-            # we have valid pointer here, otherwise we can do it after the
-            # is_in_nursery check
-            if (self.config.taggedpointers and
-                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
-            elif (not self.config.taggedpointers and
-                  not self.is_valid_gc_object(addr)):
-                return
-            self.write_into_last_generation_obj(addr_struct, addr)
+            if DEBUG:
+                ll_assert(not self.is_in_nursery(addr_struct),
+                          "nursery object with GCFLAG_NO_YOUNG_PTRS")
+            self.old_objects_pointing_to_young.append(addr_struct)
+            self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+            self.write_into_last_generation_obj(addr_struct)
         remember_young_pointer._dont_inline_ = True
         self.remember_young_pointer = remember_young_pointer
 
-    def write_into_last_generation_obj(self, addr_struct, addr):
+    def write_into_last_generation_obj(self, addr_struct):
         objhdr = self.header(addr_struct)
         if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
-            if not self.is_last_generation(addr):
-                objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
-                self.last_generation_root_objects.append(addr_struct)
+            objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+            self.last_generation_root_objects.append(addr_struct)
+    write_into_last_generation_obj._always_inline_ = True
 
     def assume_young_pointers(self, addr_struct):
         objhdr = self.header(addr_struct)

Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py	(original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/minimark.py	Mon Sep 20 17:40:01 2010
@@ -675,19 +675,19 @@
     #  "if addr_struct.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, addr_struct):
         if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
-            self.remember_young_pointer(addr_struct, newvalue)
+            self.remember_young_pointer(addr_struct)
 
-    def write_barrier_from_array(self, newvalue, addr_array, index):
+    def write_barrier_from_array(self, addr_array, index):
         if self.header(addr_array).tid & GCFLAG_NO_YOUNG_PTRS:
             if self.card_page_indices > 0:     # <- constant-folded
-                self.remember_young_pointer_from_array(addr_array, index,
-                                                       newvalue)
+                self.remember_young_pointer_from_array(addr_array, index)
             else:
-                self.remember_young_pointer(addr_array, newvalue)
+                self.remember_young_pointer(addr_array)
 
     def _init_writebarrier_logic(self):
+        DEBUG = self.DEBUG
         # The purpose of attaching remember_young_pointer to the instance
         # instead of keeping it as a regular method is to help the JIT call it.
         # Additionally, it makes the code in write_barrier() marginally smaller
@@ -695,30 +695,22 @@
         # 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):
-            # 'addr_struct' is the address of the object in which we write;
-            # 'addr' is the address that we write in 'addr_struct'.
-            ll_assert(not self.is_in_nursery(addr_struct),
-                      "nursery object with GCFLAG_NO_YOUNG_PTRS")
-            # if we have tagged pointers around, we first need to check whether
-            # we have valid pointer here, otherwise we can do it after the
-            # is_in_nursery check
-            if (self.config.taggedpointers and
-                not self.is_valid_gc_object(addr)):
-                return
-            #
-            # Core logic: if the 'addr' is in the nursery, then we need
+        def remember_young_pointer(addr_struct):
+            # 'addr_struct' is the address of the object in which we write.
+            if DEBUG:
+                ll_assert(not self.is_in_nursery(addr_struct),
+                          "nursery object with GCFLAG_NO_YOUNG_PTRS")
+            #
+            # We assume that what we are writing is a pointer to the nursery
+            # (and don't care for the fact that this new pointer may not
+            # actually point to the nursery, which seems ok).  What we need is
             # to remove the flag GCFLAG_NO_YOUNG_PTRS and add the old object
             # to the list 'old_objects_pointing_to_young'.  We know that
             # 'addr_struct' cannot be in the nursery, because nursery objects
             # never have the flag GCFLAG_NO_YOUNG_PTRS to start with.
+            self.old_objects_pointing_to_young.append(addr_struct)
             objhdr = self.header(addr_struct)
-            if self.is_in_nursery(addr):
-                self.old_objects_pointing_to_young.append(addr_struct)
-                objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
-            elif (not self.config.taggedpointers and
-                  not self.is_valid_gc_object(addr)):
-                return
+            objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
             #
             # Second part: if 'addr_struct' is actually a prebuilt GC
             # object and it's the first time we see a write to it, we
@@ -737,17 +729,16 @@
 
 
     def _init_writebarrier_with_card_marker(self):
-        def remember_young_pointer_from_array(addr_array, index, addr):
+        def remember_young_pointer_from_array(addr_array, index):
             # 'addr_array' is the address of the object in which we write,
             # which must have an array part;  'index' is the index of the
-            # item that is (or contains) the pointer that we write;
-            # 'addr' is the address that we write in the array.
+            # item that is (or contains) the pointer that we write.
             objhdr = self.header(addr_array)
             if objhdr.tid & GCFLAG_HAS_CARDS == 0:
                 #
                 # no cards, use default logic.  The 'nocard_logic()' is just
                 # 'remember_young_pointer()', but forced to be inlined here.
-                nocard_logic(addr_array, addr)
+                nocard_logic(addr_array)
                 return
             #
             # 'addr_array' is a raw_malloc'ed array with card markers
@@ -764,22 +755,13 @@
             if byte & bitmask:
                 return
             #
-            # As in remember_young_pointer, check if 'addr' is a valid
-            # pointer, in case it can be a tagged integer
-            if (self.config.taggedpointers and
-                not self.is_valid_gc_object(addr)):
-                return
-            #
-            # If the 'addr' is in the nursery, then we need to set the flag.
-            # Note that the following check is done after the bit check
-            # above, because it is expected that the "bit already set"
-            # situation is the most common.
-            if self.is_in_nursery(addr):
-                addr_byte.char[0] = chr(byte | bitmask)
-                #
-                if objhdr.tid & GCFLAG_CARDS_SET == 0:
-                    self.old_objects_with_cards_set.append(addr_array)
-                    objhdr.tid |= GCFLAG_CARDS_SET
+            # We set the flag (even if the newly written address does not
+            # actually point to the nursery -- like remember_young_pointer()).
+            addr_byte.char[0] = chr(byte | bitmask)
+            #
+            if objhdr.tid & GCFLAG_CARDS_SET == 0:
+                self.old_objects_with_cards_set.append(addr_array)
+                objhdr.tid |= GCFLAG_CARDS_SET
 
         nocard_logic = func_with_new_name(self.remember_young_pointer,
                                           'remember_young_pointer_nocard')

Modified: pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py	(original)
+++ pypy/branch/smaller-writebarrier/pypy/rpython/memory/gc/test/test_direct.py	Mon Sep 20 17:40:01 2010
@@ -86,19 +86,17 @@
 
     def write(self, p, fieldname, 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)
+            self.gc.write_barrier(addr_struct)
         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)
             if hasattr(self.gc, 'write_barrier_from_array'):
-                self.gc.write_barrier_from_array(newaddr, addr_struct, index)
+                self.gc.write_barrier_from_array(addr_struct, index)
             else:
-                self.gc.write_barrier(newaddr, addr_struct)
+                self.gc.write_barrier(addr_struct)
         p[index] = newvalue
 
     def malloc(self, TYPE, n=None):



More information about the Pypy-commit mailing list