[pypy-svn] r74153 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 28 11:39:47 CEST 2010


Author: arigo
Date: Wed Apr 28 11:39:46 2010
New Revision: 74153

Added:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/heaptracker.py
      - copied unchanged from r74151, pypy/branch/blackhole-improvement/pypy/jit/metainterp/heaptracker.py
Modified:
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
   pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
Log:
Mallocs.


Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py	Wed Apr 28 11:39:46 2010
@@ -4,6 +4,7 @@
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
 from pypy.objspace.flow.model import Block, Link, c_last_exception
 from pypy.jit.codewriter.flatten import ListOfKind
+from pypy.jit.codewriter import support, heaptracker
 
 
 def transform_graph(graph, cpu=None):
@@ -170,20 +171,23 @@
         else: raise AssertionError(kind)
         lst.append(v)
 
-    def _rewrite_with_helper(self, op):
-        from pypy.jit.codewriter.support import builtin_func_for_spec
-        c_func, _ = builtin_func_for_spec(self.cpu.rtyper, op.opname,
-                                          [lltype.Signed, lltype.Signed],
-                                          lltype.Signed)
-        op = SpaceOperation('direct_call', [c_func] + op.args, op.result)
-        return self.rewrite_op_direct_call(op)
-
-    rewrite_op_int_floordiv_ovf_zer = _rewrite_with_helper
-    rewrite_op_int_floordiv_ovf     = _rewrite_with_helper
-    rewrite_op_int_floordiv_zer     = _rewrite_with_helper
-    rewrite_op_int_mod_ovf_zer = _rewrite_with_helper
-    rewrite_op_int_mod_ovf     = _rewrite_with_helper
-    rewrite_op_int_mod_zer     = _rewrite_with_helper
+    def _do_builtin_call(self, op, oopspec_name=None, args=None, extra=None):
+        if oopspec_name is None: oopspec_name = op.opname
+        if args is None: args = op.args
+        argtypes = [v.concretetype for v in args]
+        resulttype = op.result.concretetype
+        c_func, TP = support.builtin_func_for_spec(self.cpu.rtyper,
+                                                   oopspec_name, argtypes,
+                                                   resulttype, extra)
+        op1 = SpaceOperation('direct_call', [c_func] + args, op.result)
+        return self.rewrite_op_direct_call(op1)
+
+    rewrite_op_int_floordiv_ovf_zer = _do_builtin_call
+    rewrite_op_int_floordiv_ovf     = _do_builtin_call
+    rewrite_op_int_floordiv_zer     = _do_builtin_call
+    rewrite_op_int_mod_ovf_zer = _do_builtin_call
+    rewrite_op_int_mod_ovf     = _do_builtin_call
+    rewrite_op_int_mod_zer     = _do_builtin_call
 
     def rewrite_op_hint(self, op):
         hints = op.args[1].value
@@ -280,6 +284,32 @@
         return SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
                               [v_inst, descr], op.result)
 
+    def rewrite_op_malloc(self, op):
+        assert op.args[1].value == {'flavor': 'gc'}
+        STRUCT = op.args[0].value
+        vtable = heaptracker.get_vtable_for_gcstruct(self.cpu, STRUCT)
+        if vtable:
+            # do we have a __del__?
+            try:
+                rtti = lltype.getRuntimeTypeInfo(STRUCT)
+            except ValueError:
+                pass
+            else:
+                if hasattr(rtti._obj, 'destructor_funcptr'):
+                    RESULT = lltype.Ptr(STRUCT)
+                    assert RESULT == op.result.concretetype
+                    return self._do_builtin_call(op, 'alloc_with_del',
+                                                 [], extra = (RESULT, vtable))
+            # store the vtable as an address -- that's fine, because the
+            # GC doesn't need to follow them
+            #self.codewriter.register_known_gctype(vtable, STRUCT)
+            sizevtabledescr = self.cpu.sizevtableof(STRUCT, vtable)
+            return SpaceOperation('new_with_vtable', [sizevtabledescr],
+                                  op.result)
+        else:
+            sizedescr = self.cpu.sizeof(STRUCT)
+            return SpaceOperation('new', [sizedescr], op.result)
+
 # ____________________________________________________________
 
 def _with_prefix(prefix):

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py	Wed Apr 28 11:39:46 2010
@@ -210,11 +210,12 @@
 
     # ---------- malloc with del ----------
 
-    def _ll_1_alloc_with_del(RESULT, vtable):
-        p = lltype.malloc(RESULT)
-        lltype.cast_pointer(rclass.OBJECTPTR, p).typeptr = vtable
-        return p
-    _ll_1_alloc_with_del.need_result_type = True
+    def build_ll_0_alloc_with_del(RESULT, vtable):
+        def _ll_0_alloc_with_del():
+            p = lltype.malloc(RESULT)
+            lltype.cast_pointer(rclass.OBJECTPTR, p).typeptr = vtable
+            return p
+        return _ll_0_alloc_with_del
 
 
 class OOtypeHelpers:
@@ -294,8 +295,10 @@
 
 # -------------------------------------------------------
 
-def setup_extra_builtin(rtyper, oopspec_name, nb_args):
+def setup_extra_builtin(rtyper, oopspec_name, nb_args, extra=None):
     name = '_ll_%d_%s' % (nb_args, oopspec_name.replace('.', '_'))
+    if extra is not None:
+        name = 'build' + name
     try:
         wrapper = globals()[name]
     except KeyError:
@@ -304,6 +307,8 @@
         else:
             Helpers = OOtypeHelpers
         wrapper = getattr(Helpers, name).im_func
+    if extra is not None:
+        wrapper = wrapper(*extra)
     return wrapper
 
 # # ____________________________________________________________
@@ -388,8 +393,8 @@
     else:
         raise ValueError(op.opname)
 
-def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res):
-    key = (oopspec_name, tuple(ll_args), ll_res)
+def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res, extra=None):
+    key = (oopspec_name, tuple(ll_args), ll_res, extra)
     try:
         return rtyper._builtin_func_for_spec_cache[key]
     except (KeyError, AttributeError):
@@ -400,14 +405,19 @@
     else:
         LIST_OR_DICT = ll_args[0]
     s_result = annmodel.lltype_to_annotation(ll_res)
-    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s))
+    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra)
     if getattr(impl, 'need_result_type', False):
         bk = rtyper.annotator.bookkeeper
         args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))]))
     #
-    mixlevelann = MixLevelHelperAnnotator(rtyper)
-    c_func = mixlevelann.constfunc(impl, args_s, s_result)
-    mixlevelann.finish()
+    if hasattr(rtyper, 'annotator'):  # regular case
+        mixlevelann = MixLevelHelperAnnotator(rtyper)
+        c_func = mixlevelann.constfunc(impl, args_s, s_result)
+        mixlevelann.finish()
+    else:
+        # for testing only
+        c_func = Constant(oopspec_name,
+                          lltype.Ptr(lltype.FuncType(ll_args, ll_res)))
     #
     if not hasattr(rtyper, '_builtin_func_for_spec_cache'):
         rtyper._builtin_func_for_spec_cache = {}

Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	(original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py	Wed Apr 28 11:39:46 2010
@@ -5,12 +5,22 @@
 from pypy.jit.metainterp.history import getkind
 from pypy.rpython.lltypesystem import lltype, rclass, rstr
 from pypy.translator.unsimplify import varoftype
+from pypy.jit.codewriter import heaptracker
+
+class FakeRTyper:
+    class type_system: name = 'lltypesystem'
+    instance_reprs = {}
 
 class FakeCPU:
+    rtyper = FakeRTyper()
     def calldescrof(self, FUNC, ARGS, RESULT):
         return ('calldescr', FUNC, ARGS, RESULT)
     def fielddescrof(self, STRUCT, name):
         return ('fielddescr', STRUCT, name)
+    def sizeof(self, STRUCT):
+        return ('sizedescr', STRUCT)
+    def sizevtableof(self, STRUCT, vtable):
+        return ('sizevtabledescr', STRUCT, vtable)
 
 class FakeLink:
     args = []
@@ -161,6 +171,41 @@
         assert op1.args == [v_parent, fielddescr]
         assert op1.result == v_result
 
+def test_malloc_new():
+    S = lltype.GcStruct('S')
+    v = varoftype(lltype.Ptr(S))
+    op = SpaceOperation('malloc', [Constant(S, lltype.Void),
+                                   Constant({'flavor': 'gc'}, lltype.Void)], v)
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new'
+    assert op1.args == [('sizedescr', S)]
+
+def test_malloc_new_with_vtable():
+    class vtable: pass
+    S = lltype.GcStruct('S', ('parent', rclass.OBJECT))
+    heaptracker.set_testing_vtable_for_gcstruct(S, vtable, 'S')
+    v = varoftype(lltype.Ptr(S))
+    op = SpaceOperation('malloc', [Constant(S, lltype.Void),
+                                   Constant({'flavor': 'gc'}, lltype.Void)], v)
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'new_with_vtable'
+    assert op1.args == [('sizevtabledescr', S, vtable)]
+
+def test_malloc_new_with_destructor():
+    class vtable: pass
+    S = lltype.GcStruct('S', ('parent', rclass.OBJECT))
+    DESTRUCTOR = lltype.FuncType([lltype.Ptr(S)], lltype.Void)
+    destructor = lltype.functionptr(DESTRUCTOR, 'destructor')
+    lltype.attachRuntimeTypeInfo(S, destrptr=destructor)
+    heaptracker.set_testing_vtable_for_gcstruct(S, vtable, 'S')
+    v = varoftype(lltype.Ptr(S))
+    op = SpaceOperation('malloc', [Constant(S, lltype.Void),
+                                   Constant({'flavor': 'gc'}, lltype.Void)], v)
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'residual_call_r_r'
+    assert op1.args[0].value == 'alloc_with_del'    # pseudo-function as a str
+    assert list(op1.args[2]) == []
+
 def test_rename_on_links():
     v1 = Variable()
     v2 = Variable()



More information about the Pypy-commit mailing list