Author: mattip <matti.pi...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit