[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