Commit 680bf841 authored by Armin Rigo's avatar Armin Rigo

Test and fix for issue #1909: the logic would incorrectly insert

some zero_ptr_field() operation between an int_add_ovf() and
the following guard_no_overflow().
parent 0d83e4b2
......@@ -58,14 +58,16 @@ class GcRewriterAssembler(object):
# barriers. We do this on each "basic block" of operations, which in
# this case means between CALLs or unknown-size mallocs.
#
for op in operations:
for i in range(len(operations)):
op = operations[i]
if op.getopnum() == rop.DEBUG_MERGE_POINT:
continue
# ---------- turn NEWxxx into CALL_MALLOC_xxx ----------
if op.is_malloc():
self.handle_malloc_operation(op)
continue
if op.is_guard():
if (op.is_guard() or
self.could_merge_with_next_guard(op, i, operations)):
self.emit_pending_zeros()
elif op.can_malloc():
self.emitting_an_operation_that_can_collect()
......@@ -103,6 +105,21 @@ class GcRewriterAssembler(object):
self.newops.append(op)
return self.newops
def could_merge_with_next_guard(self, op, i, operations):
# return True in cases where the operation and the following guard
# should likely remain together. Simplified version of
# can_merge_with_next_guard() in llsupport/regalloc.py.
if not op.is_comparison():
return op.is_ovf() # int_xxx_ovf() / guard_no_overflow()
if i + 1 >= len(operations):
return False
if (operations[i + 1].getopnum() != rop.GUARD_TRUE and
operations[i + 1].getopnum() != rop.GUARD_FALSE):
return False
if operations[i + 1].getarg(0) is not op.result:
return False
return True
# ----------
def handle_malloc_operation(self, op):
......
......@@ -9,6 +9,7 @@ from rpython.jit.tool.oparser import parse
from rpython.jit.metainterp.optimizeopt.util import equaloplists
from rpython.jit.codewriter.heaptracker import register_known_gctype
from rpython.jit.metainterp.history import JitCellToken, FLOAT
from rpython.jit.metainterp.history import AbstractFailDescr
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper import rclass
from rpython.jit.backend.x86.arch import WORD
......@@ -95,6 +96,8 @@ class RewriteTests(object):
floatframedescr = self.cpu.floatframedescr
casmdescr.compiled_loop_token = clt
#
guarddescr = AbstractFailDescr()
#
namespace.update(locals())
#
for funcname in self.gc_ll_descr._generated_functions:
......@@ -994,3 +997,37 @@ class TestFramework(RewriteTests):
setarrayitem_gc(p1, 1, f0, descr=floatframedescr)
i3 = call_assembler(p1, descr=casmdescr)
""")
def test_int_add_ovf(self):
self.check_rewrite("""
[i0]
p0 = new(descr=tdescr)
i1 = int_add_ovf(i0, 123)
guard_overflow(descr=guarddescr) []
jump()
""", """
[i0]
p0 = call_malloc_nursery(%(tdescr.size)d)
setfield_gc(p0, 5678, descr=tiddescr)
zero_ptr_field(p0, %(tdescr.gc_fielddescrs[0].offset)s)
i1 = int_add_ovf(i0, 123)
guard_overflow(descr=guarddescr) []
jump()
""")
def test_int_gt(self):
self.check_rewrite("""
[i0]
p0 = new(descr=tdescr)
i1 = int_gt(i0, 123)
guard_false(i1, descr=guarddescr) []
jump()
""", """
[i0]
p0 = call_malloc_nursery(%(tdescr.size)d)
setfield_gc(p0, 5678, descr=tiddescr)
zero_ptr_field(p0, %(tdescr.gc_fielddescrs[0].offset)s)
i1 = int_gt(i0, 123)
guard_false(i1, descr=guarddescr) []
jump()
""")
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