[pypy-svn] r32089 - in pypy/dist/pypy/jit: codegen/i386 codegen/i386/test codegen/llgraph timeshifter timeshifter/test

pedronis at codespeak.net pedronis at codespeak.net
Fri Sep 8 20:53:52 CEST 2006


Author: pedronis
Date: Fri Sep  8 20:53:40 2006
New Revision: 32089

Modified:
   pypy/dist/pypy/jit/codegen/i386/ri386genop.py
   pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
   pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/rtyper.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
Log:
(arigo, pedronis)

Timeshifter and backends support for malloc_varsize. Some refactorings.



Modified: pypy/dist/pypy/jit/codegen/i386/ri386genop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386genop.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386genop.py	Fri Sep  8 20:53:40 2006
@@ -162,19 +162,24 @@
         self.mc.LEA(eax, mem(edx, offset))
         return self.returnvar(eax)
 
-    def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
-        # XXX! only works for GcArray(Signed) for now!!
+    def itemaddr(self, base, arraytoken, gv_index):
+        # uses ecx
         lengthoffset, startoffset, itemoffset = arraytoken
-        self.mc.MOV(edx, gv_ptr.operand(self))
         if isinstance(gv_index, IntConst):
             startoffset += itemoffset * gv_index.value
-            op = mem(edx, startoffset)
+            op = mem(base, startoffset)
         elif itemoffset in SIZE2SHIFT:
             self.mc.MOV(ecx, gv_index.operand(self))
-            op = memSIB(edx, ecx, SIZE2SHIFT[itemoffset], startoffset)
+            op = memSIB(base, ecx, SIZE2SHIFT[itemoffset], startoffset)
         else:
             self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
-            op = memSIB(edx, ecx, 0, startoffset)
+            op = memSIB(base, ecx, 0, startoffset)
+        return op
+
+    def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
+        # XXX! only works for GcArray(Signed) for now!!
+        self.mc.MOV(edx, gv_ptr.operand(self))
+        op = self.itemaddr(edx, arraytoken, gv_index)
         return self.returnvar(op)
 
     def genop_getarraysize(self, arraytoken, gv_ptr):
@@ -184,19 +189,10 @@
 
     def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
         # XXX! only works for GcArray(Signed) for now!!
-        lengthoffset, startoffset, itemoffset = arraytoken
         self.mc.MOV(eax, gv_value.operand(self))
         self.mc.MOV(edx, gv_ptr.operand(self))
-        if isinstance(gv_index, IntConst):
-            startoffset += itemoffset * gv_index.value
-            op = mem(edx, startoffset)
-        elif itemoffset in SIZE2SHIFT:
-            self.mc.MOV(ecx, gv_index.operand(self))
-            op = memSIB(edx, ecx, SIZE2SHIFT[itemoffset], startoffset)
-        else:
-            self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
-            op = memSIB(edx, ecx, 0, startoffset)
-        self.mc.MOV(op, eax)
+        destop = self.itemaddr(edx, arraytoken, gv_index)
+        self.mc.MOV(destop, eax)
 
     def genop_malloc_fixedsize(self, size):
         # XXX boehm only, no atomic/non atomic distinction for now
@@ -205,6 +201,19 @@
         self.mc.CALL(rel32(lltype.cast_ptr_to_int(gc_malloc_ptr)))
         return self.returnvar(eax)
 
+    def genop_malloc_varsize(self, varsizealloctoken, gv_size):
+        # XXX boehm only, no atomic/non atomic distinction for now
+        # XXX no overflow checking for now
+        op_size = self.itemaddr(None, varsizealloctoken, gv_size)
+        self.mc.LEA(edx, op_size)
+        self.push(edx)
+        gc_malloc_ptr = llhelper(GC_MALLOC, gc_malloc)
+        self.mc.CALL(rel32(lltype.cast_ptr_to_int(gc_malloc_ptr)))
+        lengthoffset, _, _ = varsizealloctoken
+        self.mc.MOV(ecx, gv_size.operand(self))
+        self.mc.MOV(mem(eax, lengthoffset), ecx)
+        return self.returnvar(eax)
+        
     def genop_call(self, sigtoken, gv_fnptr, args_gv):
         for i in range(len(args_gv)-1, -1, -1):
             gv_arg = args_gv[i]
@@ -523,6 +532,20 @@
         return llmemory.sizeof(T)
 
     @staticmethod
+    @specialize.memo()
+    def varsizeAllocToken(T):
+        if isinstance(T, lltype.Array):
+            return RI386GenOp.arrayToken(T)
+        subfield = T._arrayfld
+        SUBFIELD = getattr(T, subfield)
+        subtoken = RI386GenOp.varsizeAllocToken(SUBFIELD)
+        length_offset, items_offset, item_size = subtoken
+        subfield_offset = llmemory.offsetof(T, subfield)
+        return (subfield_offset+length_offset,
+                subfield_offset+items_offset,
+                item_size)
+
+    @staticmethod
     @specialize.memo()    
     def arrayToken(A):
         return (llmemory.ArrayLengthOffset(A),

Modified: pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py	(original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py	Fri Sep  8 20:53:40 2006
@@ -28,6 +28,8 @@
         def allocToken(T):
             return len(T._names)
 
+        varsizeAllocToken = arrayToken
+
         @staticmethod
         @specialize.memo()
         def constFieldName(T, name):

Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	Fri Sep  8 20:53:40 2006
@@ -185,6 +185,8 @@
         return (LLConst(llimpl.constTYPE(TYPE)),
                 LLConst(llimpl.constTYPE(lltype.Ptr(TYPE))))
 
+    varsizeAllocToken = allocToken
+
     @staticmethod
     @specialize.memo()
     def arrayToken(A):

Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Fri Sep  8 20:53:40 2006
@@ -37,7 +37,9 @@
 class StructTypeDesc(object):
     __metaclass__ = cachedtype
     firstsubstructdesc = None
-
+    arrayfielddesc = None
+    varsizealloctoken = None
+    
     def __init__(self, RGenOp, TYPE):
         self.TYPE = TYPE
         self.PTRTYPE = lltype.Ptr(TYPE)
@@ -50,6 +52,10 @@
         for name in self.TYPE._names:
             FIELDTYPE = getattr(self.TYPE, name)
             if isinstance(FIELDTYPE, lltype.ContainerType):
+                if isinstance(FIELDTYPE, lltype.Array):
+                    self.arrayfielddesc = ArrayFieldDesc(RGenOp, FIELDTYPE)
+                    self.varsizealloctoken = RGenOp.varsizeAllocToken(TYPE)
+                    continue
                 substructdesc = StructTypeDesc(RGenOp, FIELDTYPE)
                 assert name == self.TYPE._names[0], (
                     "unsupported: inlined substructures not as first field")
@@ -129,10 +135,11 @@
         self.defaultbox = self.redboxcls(self.kind, self.gv_default)
 
 class ArrayFieldDesc(FieldDesc):
-    def __init__(self, RGenOp, PTRTYPE):
-        assert isinstance(PTRTYPE.TO, lltype.Array)
-        FieldDesc.__init__(self, RGenOp, PTRTYPE, PTRTYPE.TO.OF)
-        self.arraytoken = RGenOp.arrayToken(PTRTYPE.TO)
+    def __init__(self, RGenOp, TYPE):
+        assert isinstance(TYPE, lltype.Array)
+        FieldDesc.__init__(self, RGenOp, lltype.Ptr(TYPE), TYPE.OF)
+        self.arraytoken = RGenOp.arrayToken(TYPE)
+        self.varsizealloctoken = RGenOp.varsizeAllocToken(TYPE)
         self.indexkind = RGenOp.kindToken(lltype.Signed)
 
 # ____________________________________________________________

Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Fri Sep  8 20:53:40 2006
@@ -81,6 +81,12 @@
     genvar = jitstate.curbuilder.genop2(opdesc.opname, gv_arg0, gv_arg1)
     return opdesc.redboxcls(opdesc.result_kind, genvar)
 
+def ll_genmalloc_varsize(jitstate, contdesc, sizebox):
+    gv_size = sizebox.getgenvar(jitstate.curbuilder)
+    alloctoken = contdesc.varsizealloctoken
+    genvar = jitstate.curbuilder.genop_malloc_varsize(alloctoken, gv_size)
+    return rvalue.PtrRedBox(contdesc.ptrkind, genvar)
+
 def ll_gengetfield(jitstate, fielddesc, argbox):
     if fielddesc.immutable and argbox.is_constant():
         res = getattr(rvalue.ll_getvalue(argbox, fielddesc.PTRTYPE),

Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py	Fri Sep  8 20:53:40 2006
@@ -178,7 +178,7 @@
         ts = self.timeshifter
         v_argbox, v_index = hop.inputargs(self.getredrepr(PTRTYPE),
                                           self.getredrepr(lltype.Signed))
-        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE)
+        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
         c_fielddesc = inputconst(lltype.Void, fielddesc)
         s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
         v_jitstate = hop.llops.getjitstate()
@@ -197,7 +197,7 @@
         ts = self.timeshifter
         [v_argbox] = hop.inputargs(self.getredrepr(PTRTYPE))
         
-        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE)
+        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
         c_fielddesc = inputconst(lltype.Void, fielddesc)
         s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
         v_jitstate = hop.llops.getjitstate()
@@ -252,7 +252,7 @@
         v_argbox, v_index, v_valuebox= hop.inputargs(self.getredrepr(PTRTYPE),
                                                      self.getredrepr(lltype.Signed),
                                                      self.getredrepr(VALUETYPE))
-        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE)
+        fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
         c_fielddesc = inputconst(lltype.Void, fielddesc)
         s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
         v_jitstate = hop.llops.getjitstate()
@@ -287,6 +287,25 @@
         r_result = hop.r_result
         return r_result.create(hop)
 
+    def translate_op_malloc_varsize(self, hop):
+        # XXX no array support for now
+        ts = self.timeshifter
+        assert isinstance(hop.r_result, RedRepr)
+        PTRTYPE = originalconcretetype(hop.s_result)
+        TYPE = PTRTYPE.TO
+        if isinstance(TYPE, lltype.Struct):
+            contdesc = rcontainer.StructTypeDesc(self.RGenOp, TYPE)
+        else:
+            contdesc = rcontainer.ArrayFieldDesc(self.RGenOp, TYPE)
+        c_contdesc = inputconst(lltype.Void, contdesc)
+        s_contdesc = ts.rtyper.annotator.bookkeeper.immutablevalue(contdesc)
+        v_jitstate = hop.llops.getjitstate()
+        v_size = hop.inputarg(self.getredrepr(lltype.Signed), arg=1)
+        return hop.llops.genmixlevelhelpercall(rtimeshift.ll_genmalloc_varsize,
+                   [ts.s_JITState, s_contdesc, ts.s_RedBox],
+                   [v_jitstate,    c_contdesc, v_size     ], ts.s_RedBox)
+        
+        
     def translate_op_ptr_nonzero(self, hop, reverse=False):
         ts = self.timeshifter
         PTRTYPE = originalconcretetype(hop.args_s[0])

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Fri Sep  8 20:53:40 2006
@@ -710,20 +710,27 @@
         res = self.timeshift(ll_function, [], [], policy=P_NOVIRTUAL)
         assert res == 3
 
-##     def test_red_array(self):
-##          A = lltype.GcArray(lltype.Signed)
-##          def ll_function(x, y, n):
-##              a = lltype.malloc(A, 2)
-##              a[0] = x
-##              a[1] = y
-##              return a[n]
-
-##          res = self.timeshift(ll_function, [42, -42, 0], [], policy=P_NOVIRTUAL)
-##          assert res == 42
-
-##          res = self.timeshift(ll_function, [42, -42, 1], [], policy=P_NOVIRTUAL)
-##          assert res == -42
-
+    def test_red_array(self):
+         A = lltype.GcArray(lltype.Signed)
+         def ll_function(x, y, n):
+             a = lltype.malloc(A, 2)
+             a[0] = x
+             a[1] = y
+             return a[n]*len(a)
+
+         res = self.timeshift(ll_function, [21, -21, 0], [],
+                              policy=P_NOVIRTUAL)
+         assert res == 42
+         self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1,
+                           'setarrayitem': 2, 'getarrayitem': 1,
+                           'getarraysize': 1, 'int_mul': 1})
+
+         res = self.timeshift(ll_function, [21, -21, 1], [],
+                              policy=P_NOVIRTUAL)
+         assert res == -42
+         self.check_insns({'malloc_varsize': 1, 'ptr_iszero': 1,
+                           'setarrayitem': 2, 'getarrayitem': 1,
+                           'getarraysize': 1, 'int_mul': 1})
 
     def test_red_propagate(self):
         S = lltype.GcStruct('S', ('n', lltype.Signed))



More information about the Pypy-commit mailing list