[pypy-commit] pypy default: merge heads

mattip noreply at buildbot.pypy.org
Fri Jan 16 10:53:28 CET 2015


Author: mattip <matti.picus at gmail.com>
Branch: 
Changeset: r75371:96a1b468e3c5
Date: 2015-01-16 11:53 +0200
http://bitbucket.org/pypy/pypy/changeset/96a1b468e3c5/

Log:	merge heads

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -219,19 +219,42 @@
     def _trace_slow_path(self, obj, callback, arg):
         typeid = self.get_type_id(obj)
         if self.has_gcptr_in_varsize(typeid):
-            item = obj + self.varsize_offset_to_variable_part(typeid)
             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)
-            while length > 0:
-                j = 0
-                while j < len(offsets):
-                    itemobj = item + offsets[j]
-                    if self.points_to_valid_gc_object(itemobj):
-                        callback(itemobj, arg)
-                    j += 1
-                item += itemlength
-                length -= 1
+            if length > 0:
+                item = obj + self.varsize_offset_to_variable_part(typeid)
+                offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid)
+                itemlength = self.varsize_item_sizes(typeid)
+                len_offsets = len(offsets)
+                if len_offsets == 1:     # common path #1
+                    offsets0 = offsets[0]
+                    while length > 0:
+                        itemobj0 = item + offsets0
+                        if self.points_to_valid_gc_object(itemobj0):
+                            callback(itemobj0, arg)
+                        item += itemlength
+                        length -= 1
+                elif len_offsets == 2:   # common path #2
+                    offsets0 = offsets[0]
+                    offsets1 = offsets[1]
+                    while length > 0:
+                        itemobj0 = item + offsets0
+                        if self.points_to_valid_gc_object(itemobj0):
+                            callback(itemobj0, arg)
+                        itemobj1 = item + offsets1
+                        if self.points_to_valid_gc_object(itemobj1):
+                            callback(itemobj1, arg)
+                        item += itemlength
+                        length -= 1
+                else:                    # general path
+                    while length > 0:
+                        j = 0
+                        while j < len_offsets:
+                            itemobj = item + offsets[j]
+                            if self.points_to_valid_gc_object(itemobj):
+                                callback(itemobj, arg)
+                            j += 1
+                        item += itemlength
+                        length -= 1
         if self.has_custom_trace(typeid):
             self.custom_trace_dispatcher(obj, typeid, callback, arg)
     _trace_slow_path._annspecialcase_ = 'specialize:arg(2)'
diff --git a/rpython/memory/test/gc_test_base.py b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -607,6 +607,58 @@
             return rgc.can_move(lltype.malloc(TP, 1))
         assert self.interpret(func, []) == self.GC_CAN_MOVE
 
+    def test_trace_array_of_structs(self):
+        R = lltype.GcStruct('R', ('i', lltype.Signed))
+        S1 = lltype.GcArray(('p1', lltype.Ptr(R)))
+        S2 = lltype.GcArray(('p1', lltype.Ptr(R)),
+                            ('p2', lltype.Ptr(R)))
+        S3 = lltype.GcArray(('p1', lltype.Ptr(R)),
+                            ('p2', lltype.Ptr(R)),
+                            ('p3', lltype.Ptr(R)))
+        def func():
+            s1 = lltype.malloc(S1, 2)
+            s1[0].p1 = lltype.malloc(R)
+            s1[1].p1 = lltype.malloc(R)
+            s2 = lltype.malloc(S2, 2)
+            s2[0].p1 = lltype.malloc(R)
+            s2[0].p2 = lltype.malloc(R)
+            s2[1].p1 = lltype.malloc(R)
+            s2[1].p2 = lltype.malloc(R)
+            s3 = lltype.malloc(S3, 2)
+            s3[0].p1 = lltype.malloc(R)
+            s3[0].p2 = lltype.malloc(R)
+            s3[0].p3 = lltype.malloc(R)
+            s3[1].p1 = lltype.malloc(R)
+            s3[1].p2 = lltype.malloc(R)
+            s3[1].p3 = lltype.malloc(R)
+            s1[0].p1.i = 100
+            s1[1].p1.i = 101
+            s2[0].p1.i = 102
+            s2[0].p2.i = 103
+            s2[1].p1.i = 104
+            s2[1].p2.i = 105
+            s3[0].p1.i = 106
+            s3[0].p2.i = 107
+            s3[0].p3.i = 108
+            s3[1].p1.i = 109
+            s3[1].p2.i = 110
+            s3[1].p3.i = 111
+            rgc.collect()
+            return ((s1[0].p1.i == 100) +
+                    (s1[1].p1.i == 101) +
+                    (s2[0].p1.i == 102) +
+                    (s2[0].p2.i == 103) +
+                    (s2[1].p1.i == 104) +
+                    (s2[1].p2.i == 105) +
+                    (s3[0].p1.i == 106) +
+                    (s3[0].p2.i == 107) +
+                    (s3[0].p3.i == 108) +
+                    (s3[1].p1.i == 109) +
+                    (s3[1].p2.i == 110) +
+                    (s3[1].p3.i == 111))
+        res = self.interpret(func, [])
+        assert res == 12
+
     def test_shrink_array(self):
         from rpython.rtyper.lltypesystem.rstr import STR
 


More information about the pypy-commit mailing list