[pypy-svn] r49731 - in pypy/dist/pypy/rpython/memory: . gc

arigo at codespeak.net arigo at codespeak.net
Thu Dec 13 17:48:57 CET 2007


Author: arigo
Date: Thu Dec 13 17:48:57 2007
New Revision: 49731

Modified:
   pypy/dist/pypy/rpython/memory/gc/base.py
   pypy/dist/pypy/rpython/memory/gctypelayout.py
Log:
Experimental: special-case GcArray(gcptr) in trace().  So far,
optimizing this case was the most important measured win in the
pypy-gc-traceopt branch.


Modified: pypy/dist/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/base.py	(original)
+++ pypy/dist/pypy/rpython/memory/gc/base.py	Thu Dec 13 17:48:57 2007
@@ -7,6 +7,8 @@
     needs_write_barrier = False
     needs_zero_gc_pointers = True
 
+    TYPEID_OF_GCARRAY_OF_GCPTR = 1
+
     def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
                             getfinalizer,
                             offsets_to_gc_pointers,
@@ -115,6 +117,15 @@
         Typically, 'callback' is a bound method and 'arg' can be None.
         """
         typeid = self.get_type_id(obj)
+        if typeid == GCBase.TYPEID_OF_GCARRAY_OF_GCPTR:
+            # a performance shortcut for GcArray(gcptr)
+            length = (obj + llmemory.gcarrayofptr_lengthoffset).signed[0]
+            item = obj + llmemory.gcarrayofptr_itemsoffset
+            while length > 0:
+                callback(item, arg)
+                item += llmemory.gcarrayofptr_singleitemoffset
+                length -= 1
+            return
         offsets = self.offsets_to_gc_pointers(typeid)
         i = 0
         while i < len(offsets):
@@ -125,14 +136,13 @@
             length = (obj + self.varsize_offset_to_length(typeid)).signed[0]
             offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid)
             itemlength = self.varsize_item_sizes(typeid)
-            i = 0
-            while i < length:
+            while length > 0:
                 j = 0
                 while j < len(offsets):
                     callback(item + offsets[j], arg)
                     j += 1
-                i += 1
                 item += itemlength
+                length -= 1
     trace._annspecialcase_ = 'specialize:arg(2)'
 
 

Modified: pypy/dist/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctypelayout.py	Thu Dec 13 17:48:57 2007
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena
+from pypy.rpython.memory.gc.base import GCBase
 
 
 class TypeLayoutBuilder(object):
@@ -25,6 +26,22 @@
         except KeyError:
             assert self.can_add_new_types
             assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray))
+
+            if TYPE != llmemory.GCARRAY_OF_PTR:
+                # first, force GcArray(gcptr) to have typeid 1, for the
+                # performance-related special-casing done by GCBase.trace().
+                if llmemory.GCARRAY_OF_PTR not in self.id_of_type:
+                    typeid = self.get_type_id(llmemory.GCARRAY_OF_PTR)
+                    assert typeid == GCBase.TYPEID_OF_GCARRAY_OF_GCPTR
+                # all types that are of the shape GcArray(gcptr) get a
+                # typeid of 1.
+                if (isinstance(TYPE, lltype.GcArray)
+                    and isinstance(TYPE.OF, lltype.Ptr)
+                    and TYPE.OF.TO._gckind == 'gc'):
+                    type_id = GCBase.TYPEID_OF_GCARRAY_OF_GCPTR
+                    self.id_of_type[TYPE] = type_id
+                    return type_id
+
             # Record the new type_id description as a small dict for now.
             # The framework gc transformer will turn it into a
             # Struct("type_info") in flatten_table().



More information about the Pypy-commit mailing list