[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