[pypy-commit] pypy gc_no_cleanup_nursery: introduce zero_contents and zero_gc_pointers as SpaceOperations in jtransform

fijal noreply at buildbot.pypy.org
Thu Sep 4 02:02:08 CEST 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: gc_no_cleanup_nursery
Changeset: r73294:80638b7a13c4
Date: 2014-09-03 18:01 -0600
http://bitbucket.org/pypy/pypy/changeset/80638b7a13c4/

Log:	introduce zero_contents and zero_gc_pointers as SpaceOperations in
	jtransform

diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -612,8 +612,14 @@
             # XXX only strings or simple arrays for now
             ARRAY = op.args[0].value
             arraydescr = self.cpu.arraydescrof(ARRAY)
-            return SpaceOperation('new_array', [op.args[2], arraydescr],
-                                  op.result)
+            op1 = SpaceOperation('new_array', [op.args[2], arraydescr],
+                                 op.result)
+            if self._has_gcptrs_in(ARRAY):
+                return [op1, SpaceOperation('zero_gc_pointers', [op.result],
+                                            None)]
+            if op.args[1].value.get('zero', False):
+                return [op1, SpaceOperation('zero_contents', [op.result], None)]
+            return op1
 
     def rewrite_op_free(self, op):
         d = op.args[1].value.copy()
@@ -860,7 +866,11 @@
         if op.args[1].value['flavor'] == 'raw':
             return self._rewrite_raw_malloc(op, 'raw_malloc_fixedsize', [])
         #
-        assert op.args[1].value == {'flavor': 'gc'}
+        if op.args[1].value.get('zero', False):
+            true_zero = True
+        else:
+            assert op.args[1].value == {'flavor': 'gc'}
+            true_zero = False
         STRUCT = op.args[0].value
         vtable = heaptracker.get_vtable_for_gcstruct(self.cpu, STRUCT)
         if vtable:
@@ -881,7 +891,24 @@
         else:
             opname = 'new'
         sizedescr = self.cpu.sizeof(STRUCT)
-        return SpaceOperation(opname, [sizedescr], op.result)
+        op1 = SpaceOperation(opname, [sizedescr], op.result)
+        if true_zero:
+            return [op1, SpaceOperation('zero_contents', [op.result], None)]
+        if self._has_gcptrs_in(STRUCT):
+            return [op1, SpaceOperation('zero_gc_pointers', [op.result], None)]
+        return op1
+
+    def _has_gcptrs_in(self, STRUCT):
+        if isinstance(STRUCT, lltype.Array):
+            ITEM = STRUCT.OF
+            if isinstance(ITEM, lltype.Struct):
+                STRUCT = ITEM
+            else:
+                return isinstance(ITEM, lltype.Ptr) and ITEM._needsgc()
+        for FIELD in STRUCT._flds.values():
+            if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc():
+                return True
+        return False
 
     def rewrite_op_getinteriorarraysize(self, op):
         # only supports strings and unicodes
diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -529,6 +529,31 @@
     assert op1.opname == 'new'
     assert op1.args == [('sizedescr', S)]
 
+def test_malloc_new_zero():
+    SS = lltype.GcStruct('SS')
+    S = lltype.GcStruct('S', ('x', lltype.Ptr(SS)))
+    v = varoftype(lltype.Ptr(S))
+    op = SpaceOperation('malloc', [Constant(S, lltype.Void),
+                                   Constant({'flavor': 'gc'}, lltype.Void)], v)
+    op1, op2 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new'
+    assert op1.args == [('sizedescr', S)]
+    assert op2.opname == 'zero_gc_pointers'
+    assert op2.args == [v]
+
+def test_malloc_new_zero_2():
+    SS = lltype.GcStruct('SS')
+    S = lltype.GcStruct('S', ('x', lltype.Ptr(SS)))
+    v = varoftype(lltype.Ptr(S))
+    op = SpaceOperation('malloc', [Constant(S, lltype.Void),
+                                   Constant({'flavor': 'gc',
+                                             'zero': True}, lltype.Void)], v)
+    op1, op2 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new'
+    assert op1.args == [('sizedescr', S)]
+    assert op2.opname == 'zero_contents'
+    assert op2.args == [v]
+
 def test_malloc_new_with_vtable():
     vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
     S = lltype.GcStruct('S', ('parent', rclass.OBJECT))
@@ -1026,6 +1051,20 @@
     assert op1.args == [v1]
     assert op1.result == v2
 
+def test_malloc_varsize_zero():
+    c_A = Constant(lltype.GcArray(lltype.Signed), lltype.Void)
+    c_flags = Constant({"flavor": "gc"}, lltype.Void)
+    v1 = varoftype(lltype.Signed)
+    v2 = varoftype(c_A.value)
+    op = SpaceOperation('malloc_varsize', [c_A, c_flags, v1], v2)
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new_array'
+    c_flags = Constant({"flavor": "gc", "zero": True}, lltype.Void)
+    op = SpaceOperation('malloc_varsize', [c_A, c_flags, v1], v2)
+    op1, op2 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new_array'
+    assert op2.opname == 'zero_contents'
+
 def test_str_concat():
     # test that the oopspec is present and correctly transformed
     PSTR = lltype.Ptr(rstr.STR)


More information about the pypy-commit mailing list