[pypy-svn] r49715 - pypy/branch/pypy-gc-traceopt/rpython/memory/gc

arigo at codespeak.net arigo at codespeak.net
Thu Dec 13 14:20:49 CET 2007


Author: arigo
Date: Thu Dec 13 14:20:48 2007
New Revision: 49715

Modified:
   pypy/branch/pypy-gc-traceopt/rpython/memory/gc/base.py
   pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py
Log:
Support for GcArrays in the list of common shapes.


Modified: pypy/branch/pypy-gc-traceopt/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/pypy-gc-traceopt/rpython/memory/gc/base.py	(original)
+++ pypy/branch/pypy-gc-traceopt/rpython/memory/gc/base.py	Thu Dec 13 14:20:48 2007
@@ -120,14 +120,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
     _slow_trace._annspecialcase_ = 'specialize:arg(3)'
 
 

Modified: pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py
==============================================================================
--- pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py	(original)
+++ pypy/branch/pypy-gc-traceopt/rpython/memory/gc/traceopt.py	Thu Dec 13 14:20:48 2007
@@ -59,11 +59,16 @@
             else:
                 fields.append(('n%d' % i, llmemory.Address))
         yield lltype.GcStruct('dummy', *fields)
-    #yield lltype.GcArray(llmemory.GCREF)
+    yield lltype.GcArray(llmemory.GCREF)
 
 def build_common_shape_fn(TYPE):
+    if TYPE._is_varsize():
+        return build_common_shape_fn_varsize(TYPE)
+    else:
+        return build_common_shape_fn_nonvarsize(TYPE)
+
+def build_common_shape_fn_nonvarsize(TYPE):
     assert isinstance(TYPE, lltype.GcStruct)
-    assert not TYPE._is_varsize()
     offsets = offsets_to_gc_pointers(TYPE)
     unroll_offsets = unrolling_iterable(offsets)
 
@@ -88,6 +93,48 @@
 
     return compatible_shape, tracer
 
+def build_common_shape_fn_varsize(TYPE):
+    assert isinstance(TYPE, lltype.GcArray)    # for now, no varsized GcStruct
+    ARRAY = TYPE
+    assert ARRAY.OF != lltype.Void     # an empty GcStruct is compatible
+                                       # with an array of Voids, gc-wise
+    offsets = offsets_to_gc_pointers(ARRAY.OF)
+    assert len(offsets) > 0   # an array without pointers doesn't need an
+                              # optimized version - it's like an empty GcStruct
+    ofstolength = llmemory.ArrayLengthOffset(ARRAY)
+    ofstovar = llmemory.itemoffsetof(ARRAY, 0)
+    itemlength = llmemory.sizeof(ARRAY.OF)
+    unroll_offsets = unrolling_iterable(offsets)
+
+    def tracer(obj, callback, arg):
+        item = obj + ofstovar
+        length = (obj + ofstolength).signed[0]
+        while length > 0:
+            for offset in unroll_offsets:
+                callback(item + offset, arg)
+            item += itemlength
+            length -= 1
+    tracer._annspecialcase_ = 'specialize:arg(1)'
+
+    def compatible_shape(gc, typeid):
+        if not (gc.has_gcptr_in_varsize(typeid) and
+                len(gc.offsets_to_gc_pointers(typeid)) == 0 and
+                gc.varsize_offset_to_variable_part(typeid) == ofstovar and
+                gc.varsize_offset_to_length(typeid) == ofstolength and
+                gc.varsize_item_sizes(typeid) != itemlength):
+            return False
+        cur_offsets = gc.varsize_offsets_to_gcpointers_in_var_part(typeid)
+        if len(cur_offsets) != len(offsets):
+            return False
+        i = 0
+        while i < len(offsets):
+            if cur_offsets[i] != offsets[i]:
+                return False
+            i += 1
+        return True
+
+    return compatible_shape, tracer
+
 def get_common_shape_fns():
     # index 0: not decided yet
     # index 255: reserved for the unoptimized case



More information about the Pypy-commit mailing list