[pypy-commit] pypy gc_no_cleanup_nursery: fight fight fight until the tests start oassinbg
fijal
noreply at buildbot.pypy.org
Wed Sep 24 17:53:27 CEST 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: gc_no_cleanup_nursery
Changeset: r73675:c6ba1b273ac0
Date: 2014-09-24 17:52 +0200
http://bitbucket.org/pypy/pypy/changeset/c6ba1b273ac0/
Log: fight fight fight until the tests start oassinbg
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -165,6 +165,9 @@
def is_array_of_structs(self):
return isinstance(self.A.OF, lltype.Struct)
+ def get_fielddescrs(self):
+ return self.fielddescrs
+
def is_item_integer_bounded(self):
return getkind(self.A.OF) == 'int' \
and rffi.sizeof(self.A.OF) < symbolic.WORD
@@ -225,6 +228,19 @@
'i': 0,
'f': 0.0}
+def fielddescrs_for(cpu, STRUCT, res=None):
+ if res is None:
+ res = []
+ # order is not relevant, except for tests
+ for name in STRUCT._names:
+ FIELD = getattr(STRUCT, name)
+ if isinstance(FIELD, lltype.Struct):
+ fielddescrs_for(cpu, FIELD, res)
+ else:
+ res.append(cpu.fielddescrof(STRUCT, name))
+ return res
+
+
class LLGraphCPU(model.AbstractCPU):
from rpython.jit.metainterp.typesystem import llhelper as ts
supports_floats = True
@@ -392,6 +408,8 @@
except KeyError:
descr = ArrayDescr(A)
self.descrs[key] = descr
+ if descr.is_array_of_structs():
+ descr.fielddescrs = fielddescrs_for(self, A.OF)
return descr
def interiorfielddescrof(self, A, fieldname):
diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -36,10 +36,10 @@
tid = llop.combine_ushort(lltype.Signed, 0, 0)
def __init__(self, size, count_fields_if_immut=-1,
- offsets_of_gcfields=None):
+ fielddescrs=None):
self.size = size
self.count_fields_if_immut = count_fields_if_immut
- self.offsets_of_gcfields = offsets_of_gcfields
+ self.fielddescrs = fielddescrs
def count_fields_if_immutable(self):
return self.count_fields_if_immut
@@ -60,13 +60,13 @@
except KeyError:
size = symbolic.get_size(STRUCT, gccache.translate_support_code)
count_fields_if_immut = heaptracker.count_fields_if_immutable(STRUCT)
- offsets_of_gcfields = heaptracker.offsets_of_gcfields(gccache, STRUCT)
+ fielddescrs = heaptracker.fielddescrs(gccache, STRUCT)
if heaptracker.has_gcstruct_a_vtable(STRUCT):
sizedescr = SizeDescrWithVTable(size, count_fields_if_immut,
- offsets_of_gcfields)
+ fielddescrs)
else:
sizedescr = SizeDescr(size, count_fields_if_immut,
- offsets_of_gcfields)
+ fielddescrs)
gccache.init_size_descr(STRUCT, sizedescr)
cache[STRUCT] = sizedescr
return sizedescr
@@ -192,6 +192,7 @@
lendescr = None
flag = '\x00'
vinfo = None
+ fielddescrs = None
def __init__(self, basesize, itemsize, lendescr, flag):
self.basesize = basesize
@@ -215,6 +216,9 @@
return self.flag in (FLAG_SIGNED, FLAG_UNSIGNED) \
and self.itemsize < symbolic.WORD
+ def get_fielddescrs(self):
+ return self.fielddescrs
+
def get_item_integer_min(self):
if self.flag == FLAG_UNSIGNED:
return intbounds.get_integer_min(True, self.itemsize)
@@ -254,6 +258,9 @@
lendescr = get_field_arraylen_descr(gccache, ARRAY_OR_STRUCT)
flag = get_type_flag(ARRAY_INSIDE.OF)
arraydescr = ArrayDescr(basesize, itemsize, lendescr, flag)
+ if arraydescr.is_array_of_structs():
+ arraydescr.fielddescrs = heaptracker.fielddescrs(gccache,
+ ARRAY_OR_STRUCT.OF)
if ARRAY_OR_STRUCT._gckind == 'gc':
gccache.init_array_descr(ARRAY_OR_STRUCT, arraydescr)
cache[ARRAY_OR_STRUCT] = arraydescr
diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -1,6 +1,6 @@
from rpython.rlib import rgc
from rpython.rlib.rarithmetic import ovfcheck
-from rpython.rtyper.lltypesystem import llmemory
+from rpython.rtyper.lltypesystem import llmemory, lltype
from rpython.jit.metainterp import history
from rpython.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr, BoxInt
from rpython.jit.metainterp.resoperation import ResOperation, rop
@@ -39,6 +39,7 @@
_op_malloc_nursery = None
_v_last_malloced_nursery = None
c_zero = ConstInt(0)
+ c_null = ConstPtr(lltype.nullptr(llmemory.GCREF.TO))
def __init__(self, gc_ll_descr, cpu):
self.gc_ll_descr = gc_ll_descr
@@ -137,8 +138,10 @@
except KeyError:
d = {}
self.delayed_zero_setfields[result] = d
- for ofs in descr.offsets_of_gcfields:
- d[ofs] = None
+ for fielddescr in descr.fielddescrs:
+ if fielddescr.is_pointer_field():
+ ofs = self.cpu.unpack_fielddescr(fielddescr)
+ d[ofs] = None
def consider_setfield_gc(self, op):
offset = self.cpu.unpack_fielddescr(op.getdescr())
@@ -256,15 +259,15 @@
length_box, descr=descrs.jfi_frame_depth),
ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
None, descr=descrs.jf_extra_stack_depth),
- ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
+ ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
None, descr=descrs.jf_savedata),
- ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
+ ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
None, descr=descrs.jf_force_descr),
- ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
+ ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
None, descr=descrs.jf_descr),
- ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
+ ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
None, descr=descrs.jf_guard_exc),
- ResOperation(rop.SETFIELD_GC, [frame, self.c_zero],
+ ResOperation(rop.SETFIELD_GC, [frame, self.c_null],
None, descr=descrs.jf_forward),
]
self.newops += extra_ops
diff --git a/rpython/jit/backend/llsupport/test/test_descr.py b/rpython/jit/backend/llsupport/test/test_descr.py
--- a/rpython/jit/backend/llsupport/test/test_descr.py
+++ b/rpython/jit/backend/llsupport/test/test_descr.py
@@ -19,9 +19,8 @@
assert descr_t.size == symbolic.get_size(T, False)
assert descr_s.count_fields_if_immutable() == -1
assert descr_t.count_fields_if_immutable() == -1
- assert descr_t.offsets_of_gcfields == []
- assert descr_s.offsets_of_gcfields == [
- symbolic.get_field_token(S, 'y', False)[0]]
+ assert descr_t.fielddescrs == []
+ assert len(descr_s.fielddescrs) == 2
assert descr_s == get_size_descr(c0, S)
assert descr_s != get_size_descr(c1, S)
#
@@ -32,10 +31,7 @@
PARENT = lltype.Struct('P', ('x', lltype.Ptr(T)))
STRUCT = lltype.GcStruct('S', ('parent', PARENT), ('y', lltype.Ptr(T)))
descr_struct = get_size_descr(c0, STRUCT)
- assert descr_struct.offsets_of_gcfields == [
- symbolic.get_field_token(PARENT, 'x', False)[0],
- symbolic.get_field_token(STRUCT, 'y', False)[0],
- ]
+ assert len(descr_struct.fielddescrs) == 2
def test_get_size_descr_immut():
S = lltype.GcStruct('S', hints={'immutable': True})
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -84,6 +84,11 @@
jfi_frame_depth = framedescrs.jfi_frame_depth
jfi_frame_size = framedescrs.jfi_frame_size
jf_frame_info = framedescrs.jf_frame_info
+ jf_savedata = framedescrs.jf_savedata
+ jf_force_descr = framedescrs.jf_force_descr
+ jf_descr = framedescrs.jf_descr
+ jf_guard_exc = framedescrs.jf_guard_exc
+ jf_forward = framedescrs.jf_forward
jf_extra_stack_depth = framedescrs.jf_extra_stack_depth
signedframedescr = self.cpu.signedframedescr
floatframedescr = self.cpu.floatframedescr
@@ -149,7 +154,7 @@
def setup_method(self, meth):
class FakeCPU(BaseFakeCPU):
def sizeof(self, STRUCT):
- return SizeDescrWithVTable(102, offsets_of_gcfields=[])
+ return SizeDescrWithVTable(102, fielddescrs=[])
self.cpu = FakeCPU()
self.gc_ll_descr = GcLLDescr_boehm(None, None, None)
@@ -286,7 +291,7 @@
#
class FakeCPU(BaseFakeCPU):
def sizeof(self, STRUCT):
- descr = SizeDescrWithVTable(104, offsets_of_gcfields=[])
+ descr = SizeDescrWithVTable(104, fielddescrs=[])
descr.tid = 9315
return descr
self.cpu = FakeCPU()
@@ -319,7 +324,7 @@
setfield_gc(p1, 5678, descr=tiddescr)
p2 = int_add(p1, %(tdescr.size)d)
setfield_gc(p2, 1234, descr=tiddescr)
- zero_ptr_field(p1, %(tdescr.offsets_of_gcfields[0])s)
+ zero_ptr_field(p1, %(tdescr.fielddescrs[1].offset)s)
jump()
""")
@@ -767,7 +772,7 @@
[i0]
p0 = call_malloc_nursery(%(tdescr.size)d)
setfield_gc(p0, 5678, descr=tiddescr)
- zero_ptr_field(p0, %(tdescr.offsets_of_gcfields[0])s)
+ zero_ptr_field(p0, %(tdescr.fielddescrs[1].offset)s)
p1 = call_malloc_nursery_varsize(1, 1, i0, \
descr=strdescr)
setfield_gc(p1, i0, descr=strlendescr)
@@ -788,7 +793,7 @@
[p1]
p0 = call_malloc_nursery(%(tdescr.size)d)
setfield_gc(p0, 5678, descr=tiddescr)
- zero_ptr_field(p0, %(tdescr.offsets_of_gcfields[0])s)
+ zero_ptr_field(p0, %(tdescr.fielddescrs[1].offset)s)
label(p0, p1)
cond_call_gc_wb(p0, descr=wbdescr)
setfield_gc(p0, p1, descr=tzdescr)
@@ -820,6 +825,11 @@
setfield_gc(p1, 0, descr=tiddescr)
i2 = getfield_gc(ConstClass(frame_info), descr=jfi_frame_depth)
setfield_gc(p1, 0, descr=jf_extra_stack_depth)
+ setfield_gc(p1, NULL, descr=jf_savedata)
+ setfield_gc(p1, NULL, descr=jf_force_descr)
+ setfield_gc(p1, NULL, descr=jf_descr)
+ setfield_gc(p1, NULL, descr=jf_guard_exc)
+ setfield_gc(p1, NULL, descr=jf_forward)
setfield_gc(p1, i2, descr=framelendescr)
setfield_gc(p1, ConstClass(frame_info), descr=jf_frame_info)
setarrayitem_gc(p1, 0, i0, descr=signedframedescr)
diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py
--- a/rpython/jit/codewriter/heaptracker.py
+++ b/rpython/jit/codewriter/heaptracker.py
@@ -126,18 +126,16 @@
vtable = llmemory.cast_ptr_to_adr(vtable)
return adr2int(vtable)
-def offsets_of_gcfields(gccache, STRUCT, res=None):
- from rpython.jit.backend.llsupport import symbolic
+def fielddescrs(gccache, STRUCT, res=None):
+ from rpython.jit.backend.llsupport import descr
if res is None:
res = []
# order is not relevant, except for tests
for name in STRUCT._names:
FIELD = getattr(STRUCT, name)
- if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc():
- offset, _ = symbolic.get_field_token(STRUCT, name,
- gccache.translate_support_code)
- res.append(offset)
- elif isinstance(FIELD, lltype.Struct):
- offsets_of_gcfields(gccache, FIELD, res)
+ if isinstance(FIELD, lltype.Struct):
+ fielddescrs(gccache, FIELD, res)
+ else:
+ res.append(descr.get_field_descr(gccache, STRUCT, name))
return res
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -502,6 +502,8 @@
descr=arraydescr)
self.optimizer.send_extra_operation(newop)
val = self.getvalue(resbox)
+ if val is None:
+ continue
if dest_value.is_virtual():
dest_value.setitem(index + dest_start, val)
else:
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -1135,12 +1135,12 @@
[i1]
p1 = new_array(2, descr=arraydescr)
setarrayitem_gc(p1, 0, 25, descr=arraydescr)
- i2 = getarrayitem_gc(p1, 1, descr=arraydescr)
+ i2 = getarrayitem_gc(p1, 0, descr=arraydescr)
jump(i2)
"""
expected = """
[i1]
- jump(0)
+ jump(25)
"""
self.optimize_loop(ops, expected)
@@ -2977,6 +2977,7 @@
[p1]
p0 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p0, descr=virtualtokendescr)
escape(p2)
setfield_gc(p2, p1, descr=virtualforceddescr)
@@ -3009,6 +3010,7 @@
p3 = force_token()
#
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
setfield_gc(p0, p2, descr=nextdescr)
#
@@ -3048,6 +3050,7 @@
p3 = force_token()
#
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
setfield_gc(p0, p2, descr=nextdescr)
#
@@ -3124,6 +3127,7 @@
[i1]
p3 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
escape(p2)
p1 = new_with_vtable(ConstClass(node_vtable))
@@ -3149,6 +3153,7 @@
[i1, p1]
p3 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
escape(p2)
setfield_gc(p2, p1, descr=virtualforceddescr)
@@ -5472,6 +5477,22 @@
"""
self.optimize_loop(ops, expected)
+ def test_virtual_clear_array_contents_escape(self):
+ ops = """
+ []
+ p0 = new_array(2, descr=arraydescr)
+ clear_array_contents(p0, descr=arraydescr)
+ escape(p0)
+ """
+ expected = """
+ []
+ p0 = new_array(2, descr=arraydescr)
+ setarrayitem_gc(p0, 0, 0, descr=arraydescr)
+ setarrayitem_gc(p0, 1, 0, descr=arraydescr)
+ escape(p0)
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(BaseTestOptimizeBasic, LLtypeMixin):
pass
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1563,7 +1563,7 @@
[i1]
p1 = new_array(2, descr=arraydescr)
setarrayitem_gc(p1, 0, 25, descr=arraydescr)
- i2 = getarrayitem_gc(p1, 1, descr=arraydescr)
+ i2 = getarrayitem_gc(p1, 0, descr=arraydescr)
jump(i2)
"""
preamble = """
@@ -3751,6 +3751,7 @@
[p1]
p0 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p0, descr=virtualtokendescr)
escape(p2)
setfield_gc(p2, p1, descr=virtualforceddescr)
@@ -3783,6 +3784,7 @@
p3 = force_token()
#
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
setfield_gc(p0, p2, descr=nextdescr)
#
@@ -3822,6 +3824,7 @@
p3 = force_token()
#
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
setfield_gc(p0, p2, descr=nextdescr)
#
@@ -3909,6 +3912,7 @@
[i1]
p3 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
escape(p2)
p1 = new_with_vtable(ConstClass(node_vtable))
@@ -3934,6 +3938,7 @@
[i1, p1]
p3 = force_token()
p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, NULL, descr=virtualforceddescr)
setfield_gc(p2, p3, descr=virtualtokendescr)
escape(p2)
setfield_gc(p2, p1, descr=virtualforceddescr)
@@ -4019,6 +4024,7 @@
ops = '''
[]
p1 = new_array(3, descr=arraydescr)
+ clear_array_contents(p1, descr=arraydescr)
p2 = new_array(3, descr=arraydescr)
setarrayitem_gc(p1, 2, 10, descr=arraydescr)
setarrayitem_gc(p2, 2, 13, descr=arraydescr)
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -253,11 +253,13 @@
itemboxes = []
for i in range(self.getlength()):
itemvalue = self.get_item_value(i)
- itemboxes.append(itemvalue.get_key_box())
+ if itemvalue is not None:
+ itemboxes.append(itemvalue.get_key_box())
visitor.register_virtual_fields(self.keybox, itemboxes)
for i in range(self.getlength()):
itemvalue = self.get_item_value(i)
- itemvalue.visitor_walk_recursive(visitor)
+ if itemvalue is not None:
+ itemvalue.visitor_walk_recursive(visitor)
class VArrayValue(AbstractVArrayValue):
@@ -266,7 +268,7 @@
AbstractVirtualValue.__init__(self, keybox, source_op)
self.arraydescr = arraydescr
self.constvalue = constvalue
- self._items = [self.constvalue] * size
+ self._items = [None] * size
def getlength(self):
return len(self._items)
@@ -277,6 +279,10 @@
def set_item_value(self, i, newval):
self._items[i] = newval
+ def initialize_with_zeros(self, optimizer):
+ for i in range(len(self._items)):
+ self._items[i] = optimizer.new_const_item(self.arraydescr)
+
def getitem(self, index):
res = self._items[index]
return res
@@ -294,6 +300,10 @@
already_forced[self] = self
for index in range(self.getlength()):
itemval = self.get_item_value(index)
+ # XXX should be skip alltogether, but I don't wanna know or
+ # fight unrolling just yet
+ if itemval is None:
+ itemval = self.constvalue
itemval = itemval.force_at_end_of_preamble(already_forced, optforce)
self.set_item_value(index, itemval)
return self
@@ -306,11 +316,11 @@
self.box = box = self.source_op.result
for index in range(len(self._items)):
subvalue = self._items[index]
- if subvalue is not self.constvalue:
+ if subvalue is not None:
subbox = subvalue.force_box(optforce)
op = ResOperation(rop.SETARRAYITEM_GC,
[box, ConstInt(index), subbox], None,
- descr=self.arraydescr)
+ descr=self.arraydescr)
optforce.emit_operation(op)
@specialize.argtype(1)
@@ -334,6 +344,12 @@
assert isinstance(itemvalue, optimizer.OptValue)
self._items[index][ofs] = itemvalue
+ def initialize_with_zeros(self, optimizer):
+ fielddescrs = self.arraydescr.get_fielddescrs()
+ for item_d in self._items:
+ for descr in fielddescrs:
+ item_d[descr] = optimizer.new_const(descr)
+
def _really_force(self, optforce):
assert self.source_op is not None
if not we_are_translated():
@@ -664,6 +680,8 @@
def optimize_CLEAR_ARRAY_CONTENTS(self, op):
v = self.getvalue(op.getarg(0))
if v.is_virtual():
+ # initialize the items, since we need to store zeros
+ v.initialize_with_zeros(self.optimizer)
return
self.emit_operation(op)
More information about the pypy-commit
mailing list