[pypy-svn] r32091 - in pypy/dist/pypy: jit/codegen jit/codegen/i386 jit/codegen/i386/test jit/timeshifter jit/timeshifter/test jit/tl/test rpython/memory
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 9 01:36:55 CEST 2006
Author: arigo
Date: Sat Sep 9 01:36:48 2006
New Revision: 32091
Added:
pypy/dist/pypy/jit/codegen/graph2rgenop.py (contents, props changed)
pypy/dist/pypy/jit/codegen/i386/test/test_genc_tl.py
- copied, changed from r32080, pypy/dist/pypy/jit/codegen/i386/test/test_genc_tlr.py
pypy/dist/pypy/jit/codegen/i386/test/test_operation.py (contents, props changed)
Modified:
pypy/dist/pypy/jit/codegen/i386/ri386genop.py
pypy/dist/pypy/jit/codegen/i386/ri386setup.py
pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtyper.py
pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_tl.py
pypy/dist/pypy/jit/timeshifter/test/test_tlr.py
pypy/dist/pypy/jit/tl/test/test_tl.py
pypy/dist/pypy/jit/tl/test/test_tlr.py
pypy/dist/pypy/rpython/memory/lltypelayout.py
Log:
(pedronis, arigo)
The TL tests pass!
- a bit more about malloc_varsize
- benchmarking at various levels
- graph2rgenop: for testing back-ends, turns a simple ll graph into a
sequence of rgenop calls that builds the same code
- more tests and more operations for ri386genop
Added: pypy/dist/pypy/jit/codegen/graph2rgenop.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/graph2rgenop.py Sat Sep 9 01:36:48 2006
@@ -0,0 +1,77 @@
+"""
+For testing purposes. Turns *simple enough* low-level graphs
+into machine code by calling the rgenop interface.
+"""
+from pypy.rpython.lltypesystem import lltype
+from pypy.objspace.flow import model as flowmodel
+
+
+def compile_graph(rgenop, graph):
+ FUNC = lltype.FuncType([v.concretetype for v in graph.getargs()],
+ graph.getreturnvar().concretetype)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, entrypoint, args_gv = rgenop.newgraph(sigtoken)
+
+ pending_blocks = {graph.startblock: (builder, args_gv)}
+ seen_blocks = {}
+
+ def varkind(v):
+ return rgenop.kindToken(v.concretetype)
+
+ def var2gv(v):
+ if isinstance(v, flowmodel.Variable):
+ return varmap[v]
+ else:
+ return rgenop.genconst(v.value)
+
+ for block in graph.iterblocks():
+ builder, args_gv = pending_blocks.pop(block)
+ assert len(args_gv) == len(block.inputargs)
+ label = builder.enter_next_block(map(varkind, block.inputargs),
+ args_gv)
+ seen_blocks[block] = label
+ varmap = dict(zip(block.inputargs, args_gv))
+
+ if not block.exits:
+ [retvar] = block.inputargs
+ builder.finish_and_return(sigtoken, varmap[retvar])
+ continue
+
+ for op in block.operations:
+ # XXX only supports some operations for now
+ if op.opname == 'malloc':
+ token = rgenop.allocToken(op.args[0].value)
+ gv_result = builder.genop_malloc_fixedsize(token)
+ elif op.opname == 'malloc_varsize':
+ token = rgenop.varsizeAllocToken(op.args[0].value)
+ gv_result = builder.genop_malloc_varsize(token,
+ var2gv(op.args[1]))
+ elif op.opname == 'getarrayitem':
+ token = rgenop.arrayToken(op.args[0].concretetype.TO)
+ gv_result = builder.genop_getarrayitem(token,
+ var2gv(op.args[0]),
+ var2gv(op.args[1]))
+ elif op.opname == 'setarrayitem':
+ token = rgenop.arrayToken(op.args[0].concretetype.TO)
+ gv_result = builder.genop_setarrayitem(token,
+ var2gv(op.args[0]),
+ var2gv(op.args[1]),
+ var2gv(op.args[2]))
+ elif len(op.args) == 1:
+ gv_result = builder.genop1(op.opname, var2gv(op.args[0]))
+ elif len(op.args) == 2:
+ gv_result = builder.genop2(op.opname, var2gv(op.args[0]),
+ var2gv(op.args[1]))
+ else:
+ raise NotImplementedError(op.opname)
+ varmap[op.result] = gv_result
+
+ if block.exitswitch is not None:
+ raise NotImplementedError("XXX exitswitch")
+ else:
+ [link] = block.exits
+ args_gv = [var2gv(v) for v in link.args]
+ pending_blocks[link.target] = builder, args_gv
+
+ return rgenop.gencallableconst(sigtoken, "compiled_%s" % (graph.name,),
+ entrypoint)
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 Sat Sep 9 01:36:48 2006
@@ -76,8 +76,10 @@
return lltype.cast_primitive(T, self.value)
def __repr__(self):
- return "const=%s" % (imm(self.value).assembler(),)
-
+ try:
+ return "const=%s" % (imm(self.value).assembler(),)
+ except TypeError: # from Symbolics
+ return "const=%r" % (self.value,)
##class FnPtrConst(IntConst):
@@ -165,21 +167,29 @@
def itemaddr(self, base, arraytoken, gv_index):
# uses ecx
lengthoffset, startoffset, itemoffset = arraytoken
+ if itemoffset == 1:
+ memSIBx = memSIB8
+ else:
+ memSIBx = memSIB
if isinstance(gv_index, IntConst):
startoffset += itemoffset * gv_index.value
- op = mem(base, startoffset)
+ op = memSIBx(base, None, 0, startoffset)
elif itemoffset in SIZE2SHIFT:
self.mc.MOV(ecx, gv_index.operand(self))
- op = memSIB(base, ecx, SIZE2SHIFT[itemoffset], startoffset)
+ op = memSIBx(base, ecx, SIZE2SHIFT[itemoffset], startoffset)
else:
self.mc.IMUL(ecx, gv_index.operand(self), imm(itemoffset))
- op = memSIB(base, ecx, 0, startoffset)
+ op = memSIBx(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)
+ _, _, itemsize = arraytoken
+ if itemsize != WORD:
+ assert itemsize == 1 or itemsize == 2
+ self.mc.MOVZX(eax, op)
+ op = eax
return self.returnvar(op)
def genop_getarraysize(self, arraytoken, gv_ptr):
@@ -188,17 +198,24 @@
return self.returnvar(mem(edx, lengthoffset))
def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
- # XXX! only works for GcArray(Signed) for now!!
self.mc.MOV(eax, gv_value.operand(self))
self.mc.MOV(edx, gv_ptr.operand(self))
destop = self.itemaddr(edx, arraytoken, gv_index)
+ _, _, itemsize = arraytoken
+ if itemsize != WORD:
+ if itemsize == 1:
+ self.mc.MOV(destop, al)
+ return
+ elif itemsize == 2:
+ self.mc.o16() # followed by the MOV below
+ else:
+ raise AssertionError
self.mc.MOV(destop, eax)
def genop_malloc_fixedsize(self, size):
# XXX boehm only, no atomic/non atomic distinction for now
self.push(imm(size))
- gc_malloc_ptr = llhelper(GC_MALLOC, gc_malloc)
- self.mc.CALL(rel32(lltype.cast_ptr_to_int(gc_malloc_ptr)))
+ self.mc.CALL(rel32(gc_malloc_fnaddr()))
return self.returnvar(eax)
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
@@ -207,8 +224,7 @@
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)))
+ self.mc.CALL(rel32(gc_malloc_fnaddr()))
lengthoffset, _, _ = varsizealloctoken
self.mc.MOV(ecx, gv_size.operand(self))
self.mc.MOV(mem(eax, lengthoffset), ecx)
@@ -283,9 +299,12 @@
self.push(op)
return res
- def op_int_is_true(self, gv_x):
+ @staticmethod
+ def identity(gv_x):
return gv_x
+ op_int_is_true = identity
+
def op_int_add(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.ADD(eax, gv_y.operand(self))
@@ -370,6 +389,11 @@
self.mc.NEG(eax)
return self.returnvar(eax)
+ def op_int_invert(self, gv_x):
+ self.mc.MOV(eax, gv_x.operand(self))
+ self.mc.NOT(eax)
+ return self.returnvar(eax)
+
def op_int_lshift(self, gv_x, gv_y):
self.mc.MOV(eax, gv_x.operand(self))
self.mc.MOV(ecx, gv_y.operand(self))
@@ -394,6 +418,9 @@
self.mc.MOVZX(eax, al)
return self.returnvar(eax)
+ op_cast_char_to_int = identity
+ op_cast_unichar_to_int = identity
+
op_ptr_nonzero = op_int_is_true
op_ptr_iszero = op_bool_not # for now
@@ -409,6 +436,27 @@
from pypy.rpython.lltypesystem.lloperation import llop
return llop.call_boehm_gc_alloc(llmemory.Address, size)
+def gc_malloc_fnaddr():
+ """Returns the address of the Boehm 'malloc' function."""
+ if objectmodel.we_are_translated():
+ gc_malloc_ptr = llhelper(GC_MALLOC, gc_malloc)
+ return lltype.cast_ptr_to_int(gc_malloc_ptr)
+ else:
+ # <pedronis> don't do this at home
+ try:
+ from ctypes import cast, c_void_p
+ from pypy.rpython.rctypes.tool import util
+ path = util.find_library('gc')
+ if path is None:
+ raise ImportError("Boehm (libgc) not found")
+ boehmlib = util.load_library(path)
+ except ImportError, e:
+ import py
+ py.test.skip(str(e))
+ else:
+ GC_malloc = boehmlib.GC_malloc
+ return cast(GC_malloc, c_void_p).value
+
# ____________________________________________________________
def remap_stack_layout(builder, outputargs_gv, targetblock):
@@ -536,14 +584,16 @@
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)
+ else:
+ # var-sized structs
+ arrayfield = T._arrayfld
+ ARRAYFIELD = getattr(T, arrayfield)
+ arraytoken = RI386GenOp.arrayToken(ARRAYFIELD)
+ length_offset, items_offset, item_size = arraytoken
+ arrayfield_offset = llmemory.offsetof(T, arrayfield)
+ return (arrayfield_offset+length_offset,
+ arrayfield_offset+items_offset,
+ item_size)
@staticmethod
@specialize.memo()
Modified: pypy/dist/pypy/jit/codegen/i386/ri386setup.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386setup.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386setup.py Sat Sep 9 01:36:48 2006
@@ -350,6 +350,8 @@
MOVZX = Instruction()
MOVZX.mode2(REG, MODRM8, ['\x0F\xB6', register(1,8), modrm(2,'b')])
+MOVZX.mode2(REG, MODRM, ['\x0F\xB7', register(1,8), modrm(2)])
+# ^^^ but this only reads the 16 lower bits of the source
MOVZX.as_all_suffixes = 1
MOVZX.as_alias = "MOVZ"
@@ -404,6 +406,9 @@
BREAKPOINT.mode0(['\xCC'])
BREAKPOINT.as_alias = "INT3"
+o16 = Instruction() # 16-bits instruction prefix (name from 'nasm')
+o16.mode0(['\x66'])
+
Conditions = {
'O': 0,
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 Sat Sep 9 01:36:48 2006
@@ -1,8 +1,8 @@
import os
-from pypy.rpython.objectmodel import specialize
from pypy.annotation import model as annmodel
from pypy.jit.timeshifter.test import test_timeshift
from pypy.jit.codegen.i386.ri386genop import RI386GenOp, IntConst
+from pypy.jit.codegen.i386.test.test_operation import RGenOpPacked
class Whatever(object):
@@ -10,30 +10,9 @@
return True
class I386LLInterpTimeshiftingTestMixin(object):
- class RGenOp(RI386GenOp):
- from pypy.jit.codegen.i386.codebuf import LLTypeMachineCodeBlock as MachineCodeBlock
-
- @staticmethod
- @specialize.memo()
- def fieldToken(T, name):
- return list(T._names).index(name)
-
- @staticmethod
- @specialize.memo()
- def arrayToken(A):
- return 0, 1, 1
-
- @staticmethod
- @specialize.memo()
- def allocToken(T):
- return len(T._names)
-
- varsizeAllocToken = arrayToken
-
- @staticmethod
- @specialize.memo()
- def constFieldName(T, name):
- return IntConst(list(T._names).index(name))
+ class RGenOp(RGenOpPacked):
+ from pypy.jit.codegen.i386.codebuf import LLTypeMachineCodeBlock \
+ as MachineCodeBlock
def timeshift(self, ll_function, values, opt_consts=[], *args, **kwds):
values = self.timeshift_cached(ll_function, values, *args, **kwds)
Added: pypy/dist/pypy/jit/codegen/i386/test/test_operation.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_operation.py Sat Sep 9 01:36:48 2006
@@ -0,0 +1,118 @@
+import py
+from pypy.rpython.objectmodel import specialize
+from pypy.annotation import model as annmodel
+from pypy.rpython.lltypesystem import lltype
+from pypy.translator.translator import TranslationContext, graphof
+from pypy.jit.codegen import graph2rgenop
+from pypy.jit.codegen.i386.ri386genop import RI386GenOp
+from pypy.rpython.memory.lltypelayout import convert_offset_to_int
+from ctypes import cast, c_void_p, CFUNCTYPE, c_int
+
+
+class RGenOpPacked(RI386GenOp):
+ """Like RI386GenOp, but produces concrete offsets in the tokens
+ instead of llmemory.offsets. These numbers may not agree with
+ your C compiler's.
+ """
+
+ @staticmethod
+ @specialize.memo()
+ def fieldToken(T, name):
+ return convert_offset_to_int(RI386GenOp.fieldToken(T, name))
+
+ @staticmethod
+ @specialize.memo()
+ def arrayToken(A):
+ return tuple(map(convert_offset_to_int, RI386GenOp.arrayToken(A)))
+
+ @staticmethod
+ @specialize.memo()
+ def allocToken(T):
+ return convert_offset_to_int(RI386GenOp.allocToken(T))
+
+ @staticmethod
+ @specialize.memo()
+ def varsizeAllocToken(A):
+ return tuple(map(convert_offset_to_int,
+ RI386GenOp.varsizeAllocToken(A)))
+
+
+class TestBasic:
+
+ def rgen(self, ll_function, argtypes):
+ t = TranslationContext()
+ t.buildannotator().build_types(ll_function, argtypes)
+ t.buildrtyper().specialize()
+ graph = graphof(t, ll_function)
+ rgenop = RGenOpPacked()
+ self.rgenop = rgenop # keep this alive!
+ gv_generated = graph2rgenop.compile_graph(rgenop, graph)
+ ctypestypes = [c_int] * len(argtypes) # for now
+ fp = cast(c_void_p(gv_generated.value), CFUNCTYPE(c_int, *ctypestypes))
+ return fp
+
+ def test_arithmetic(self):
+ for fn in [lambda x, y: x + y,
+ lambda x, y: x - y,
+ lambda x, y: x * y,
+ lambda x, y: x // y,
+ lambda x, y: x << y,
+ lambda x, y: x >> y,
+ lambda x, y: x ^ y,
+ lambda x, y: x & y,
+ lambda x, y: x | y,
+ lambda x, y: -y,
+ lambda x, y: ~y,
+ ]:
+ fp = self.rgen(fn, [int, int])
+ assert fp(40, 2) == fn(40, 2)
+
+ def test_comparison(self):
+ for fn in [lambda x, y: int(x < y),
+ lambda x, y: int(x <= y),
+ lambda x, y: int(x == y),
+ lambda x, y: int(x != y),
+ lambda x, y: int(x > y),
+ lambda x, y: int(x >= y)
+ ]:
+ fp = self.rgen(fn, [int, int])
+ assert fp(12, 11) == fn(12, 11)
+ assert fp(12, 12) == fn(12, 12)
+ assert fp(12, 13) == fn(12, 13)
+ assert fp(-12, 11) == fn(-12, 11)
+ assert fp(-12, 12) == fn(-12, 12)
+ assert fp(-12, 13) == fn(-12, 13)
+ assert fp(12, -11) == fn(12, -11)
+ assert fp(12, -12) == fn(12, -12)
+ assert fp(12, -13) == fn(12, -13)
+ assert fp(-12, -11) == fn(-12, -11)
+ assert fp(-12, -12) == fn(-12, -12)
+ assert fp(-12, -13) == fn(-12, -13)
+
+ def test_char_array(self):
+ A = lltype.GcArray(lltype.Char)
+ def fn(n):
+ a = lltype.malloc(A, 5)
+ a[4] = 'H'
+ a[3] = 'e'
+ a[2] = 'l'
+ a[1] = 'l'
+ a[0] = 'o'
+ return ord(a[n])
+ fp = self.rgen(fn, [int])
+ for i in range(5):
+ assert fp(i) == fn(i)
+
+ def test_unichar_array(self):
+ A = lltype.GcArray(lltype.UniChar)
+ def fn(n):
+ a = lltype.malloc(A, 5)
+ a[4] = u'H'
+ a[3] = u'e'
+ a[2] = u'l'
+ a[1] = u'l'
+ a[0] = u'o'
+ return ord(a[n])
+ fp = self.rgen(fn, [int])
+ for i in range(5):
+ assert fp(i) == fn(i)
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Sat Sep 9 01:36:48 2006
@@ -38,15 +38,16 @@
__metaclass__ = cachedtype
firstsubstructdesc = None
arrayfielddesc = None
+ alloctoken = None
varsizealloctoken = None
def __init__(self, RGenOp, TYPE):
self.TYPE = TYPE
self.PTRTYPE = lltype.Ptr(TYPE)
- self.alloctoken = RGenOp.allocToken(self.TYPE)
self.ptrkind = RGenOp.kindToken(self.PTRTYPE)
innermostdesc = self
-
+ if not TYPE._is_varsize():
+ self.alloctoken = RGenOp.allocToken(TYPE)
fielddescs = []
fielddesc_by_name = {}
for name in self.TYPE._names:
Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py Sat Sep 9 01:36:48 2006
@@ -288,7 +288,6 @@
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)
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 Sat Sep 9 01:36:48 2006
@@ -732,6 +732,26 @@
'setarrayitem': 2, 'getarrayitem': 1,
'getarraysize': 1, 'int_mul': 1})
+ def test_red_varsized_struct(self):
+ A = lltype.Array(lltype.Signed)
+ S = lltype.GcStruct('S', ('foo', lltype.Signed), ('a', A))
+ def ll_function(x, y, n):
+ s = lltype.malloc(S, 3)
+ s.foo = len(s.a)-1
+ s.a[0] = x
+ s.a[1] = y
+ return s.a[n]*s.foo
+
+ res = self.timeshift(ll_function, [21, -21, 0], [],
+ policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(malloc_varsize=1)
+
+ res = self.timeshift(ll_function, [21, -21, 1], [],
+ policy=P_NOVIRTUAL)
+ assert res == -42
+ self.check_insns(malloc_varsize=1)
+
def test_red_propagate(self):
S = lltype.GcStruct('S', ('n', lltype.Signed))
def ll_function(n, k):
Modified: pypy/dist/pypy/jit/timeshifter/test/test_tl.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_tl.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_tl.py Sat Sep 9 01:36:48 2006
@@ -1,6 +1,8 @@
-from pypy.rpython.lltypesystem.rstr import string_repr
+from pypy.rpython.module.support import LLSupport
from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC
+from pypy.tool.sourcetools import func_with_new_name
+from pypy.jit.conftest import Benchmark
from pypy.jit.tl import tl
from pypy.jit.tl.test.test_tl import FACTORIAL_SOURCE
@@ -9,9 +11,22 @@
class TestTL(TimeshiftingTests):
def test_tl(self):
- import py; py.test.skip("in-progress")
code = tl.compile(FACTORIAL_SOURCE)
- ll_code = string_repr.convert_const(code)
- res = self.timeshift(tl.interp_without_call, [ll_code, 0, 5], [0, 1],
- policy=P_OOPSPEC)
- assert res == 120
+ bytecode = ','.join([str(ord(c)) for c in code])
+ tl_interp_without_call = func_with_new_name(
+ tl.interp_without_call, "tl_interp_without_call")
+ # to stick attributes on the new function object, not on tl.interp_wit*
+ def build_bytecode(s):
+ result = ''.join([chr(int(t)) for t in s.split(',')])
+ return LLSupport.to_rstr(result)
+ tl_interp_without_call.convert_arguments = [build_bytecode, int, int]
+
+ if Benchmark.ENABLED:
+ n = 2500
+ expected = 0 # far too many powers of 2 to be anything else
+ else:
+ n = 5
+ expected = 120
+ res = self.timeshift(tl_interp_without_call, [bytecode, 0, n],
+ [0, 1], policy=P_OOPSPEC)
+ assert res == expected
Modified: pypy/dist/pypy/jit/timeshifter/test/test_tlr.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_tlr.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_tlr.py Sat Sep 9 01:36:48 2006
@@ -1,4 +1,3 @@
-from pypy.rpython.lltypesystem.rstr import string_repr
from pypy.rpython.module.support import LLSupport
from pypy.jit.timeshifter.test.test_timeshift import TimeshiftingTests
from pypy.jit.timeshifter.test.test_vlist import P_OOPSPEC
Modified: pypy/dist/pypy/jit/tl/test/test_tl.py
==============================================================================
--- pypy/dist/pypy/jit/tl/test/test_tl.py (original)
+++ pypy/dist/pypy/jit/tl/test/test_tl.py Sat Sep 9 01:36:48 2006
@@ -2,6 +2,7 @@
import operator
from pypy.jit.tl.tl import interp, compile
from pypy.jit.tl.opcode import *
+from pypy.jit.conftest import Benchmark
from pypy.translator.translator import TranslationContext
from pypy.annotation import policy
@@ -255,3 +256,18 @@
code = compile(FACTORIAL_SOURCE)
res = interp(code, 0, 6)
assert res == 720
+
+def test_translate_factorial():
+ # use py.test --benchmark to do the benchmarking
+ code = compile(FACTORIAL_SOURCE)
+ def driver():
+ bench = Benchmark()
+ while 1:
+ res = interp(code, 0, 2500)
+ if bench.stop():
+ break
+ return res
+
+ fn = translate(driver, [])
+ res = fn()
+ assert res == 0 # too many powers of 2 to be anything else
Modified: pypy/dist/pypy/jit/tl/test/test_tlr.py
==============================================================================
--- pypy/dist/pypy/jit/tl/test/test_tlr.py (original)
+++ pypy/dist/pypy/jit/tl/test/test_tlr.py Sat Sep 9 01:36:48 2006
@@ -1,7 +1,22 @@
from pypy.jit.tl import tlr
+from pypy.jit.tl.test.test_tl import translate
+from pypy.jit.conftest import Benchmark
def test_square():
assert tlr.interpret(tlr.SQUARE, 1) == 1
assert tlr.interpret(tlr.SQUARE, 7) == 49
assert tlr.interpret(tlr.SQUARE, 9) == 81
+
+def test_translate():
+ def driver():
+ bench = Benchmark()
+ while 1:
+ res = tlr.interpret(tlr.SQUARE, 1764)
+ if bench.stop():
+ break
+ return res
+
+ fn = translate(driver, [])
+ res = fn()
+ assert res == 1764 * 1764
Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py (original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py Sat Sep 9 01:36:48 2006
@@ -5,6 +5,7 @@
primitive_to_fmt = {lltype.Signed: "l",
lltype.Unsigned: "L",
lltype.Char: "c",
+ lltype.UniChar: "H", # maybe
lltype.Bool: "B",
lltype.Float: "d",
llmemory.Address: "P",
@@ -103,6 +104,8 @@
return get_fixed_size(lltype.Signed)
elif isinstance(offset, llmemory.GCHeaderOffset):
return sizeof(offset.gcheaderbuilder.HDR)
+ elif isinstance(offset, llmemory.ArrayLengthOffset):
+ return 0
else:
raise Exception("unknown offset type %r"%offset)
More information about the Pypy-commit
mailing list