Read about our upcoming Code of Conduct on this issue

Commit 75c74069 authored by Armin Rigo's avatar Armin Rigo
Browse files

Test and fix. It's relatively hard to hit the case on PyPy, but

if we managed to, it would be a potential obscure GC-related crash.
parent ac52eb7bbbb0
......@@ -316,7 +316,9 @@ class GcRewriterAssembler(object):
[ConstInt(kind), ConstInt(itemsize), v_length],
v_result, descr=arraydescr)
self.newops.append(op)
self.write_barrier_applied[v_result] = None
# don't record v_result into self.write_barrier_applied:
# it can be a large, young array with card marking, and then
# the GC relies on the write barrier being called
return True
def gen_malloc_nursery_varsize_frame(self, sizebox, v_result):
......
......@@ -719,6 +719,24 @@ class TestFramework(RewriteTests):
jump()
""")
def test_initialization_store_potentially_large_array(self):
# the write barrier cannot be omitted, because we might get
# an array with cards and the GC assumes that the write
# barrier is always called, even on young (but large) arrays
self.check_rewrite("""
[i0, p1, i2]
p0 = new_array(i0, descr=bdescr)
setarrayitem_gc(p0, i2, p1, descr=bdescr)
jump()
""", """
[i0, p1, i2]
p0 = call_malloc_nursery_varsize(0, 1, i0, descr=bdescr)
setfield_gc(p0, i0, descr=blendescr)
cond_call_gc_wb_array(p0, i2, descr=wbdescr)
setarrayitem_gc(p0, i2, p1, descr=bdescr)
jump()
""")
def test_non_initialization_store(self):
self.check_rewrite("""
[i0]
......
......@@ -60,6 +60,8 @@ def find_initializing_stores(collect_analyzer, graph):
if op.args[0] in mallocvars:
mallocvars[op.result] = True
elif op.opname in ("setfield", "setarrayitem", "setinteriorfield"):
# note that 'mallocvars' only tracks fixed-size mallocs,
# so no risk that they use card marking
TYPE = op.args[-1].concretetype
if (op.args[0] in mallocvars and
isinstance(TYPE, lltype.Ptr) and
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment