[pypy-commit] pypy arm-backed-float: (bivab, arigo) import regalloc tests from x86 backend
bivab
noreply at buildbot.pypy.org
Wed May 18 17:09:36 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backed-float
Changeset: r44284:a6dab81e983c
Date: 2011-05-18 16:48 +0200
http://bitbucket.org/pypy/pypy/changeset/a6dab81e983c/
Log: (bivab, arigo) import regalloc tests from x86 backend
diff --git a/pypy/jit/backend/arm/test/test_gc_integration.py b/pypy/jit/backend/arm/test/test_gc_integration.py
--- a/pypy/jit/backend/arm/test/test_gc_integration.py
+++ b/pypy/jit/backend/arm/test/test_gc_integration.py
@@ -20,13 +20,30 @@
from pypy.jit.backend.arm.test.test_regalloc import MockAssembler
from pypy.jit.backend.arm.test.test_regalloc import BaseTestRegalloc
+from pypy.jit.backend.arm.regalloc import ARMv7RegisterMananger, ARMFrameManager,\
+ VFPRegisterManager
CPU = getcpuclass()
class MockGcRootMap(object):
+ is_shadow_stack = False
def get_basic_shape(self, is_64_bit):
return ['shape']
- def add_ebp_offset(self, shape, offset):
+ def add_frame_offset(self, shape, offset):
+ shape.append(offset)
+ def add_callee_save_reg(self, shape, reg_index):
+ index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+ shape.append(index_to_name[reg_index])
+ def compress_callshape(self, shape, datablockwrapper):
+ assert datablockwrapper == 'fakedatablockwrapper'
+ assert shape[0] == 'shape'
+ return ['compressed'] + shape[1:]
+
+class MockGcRootMap2(object):
+ is_shadow_stack = False
+ def get_basic_shape(self, is_64_bit):
+ return ['shape']
+ def add_frame_offset(self, shape, offset):
shape.append(offset)
def add_callee_save_reg(self, shape, reg_index):
index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
@@ -42,7 +59,8 @@
get_funcptr_for_newarray = get_funcptr_for_new
get_funcptr_for_newstr = get_funcptr_for_new
get_funcptr_for_newunicode = get_funcptr_for_new
-
+ get_malloc_slowpath_addr = None
+
moving_gc = True
gcrootmap = MockGcRootMap()
@@ -53,6 +71,40 @@
rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
+class TestRegallocDirectGcIntegration(object):
+
+ def test_mark_gc_roots(self):
+ py.test.skip('roots')
+ cpu = CPU(None, None)
+ cpu.setup_once()
+ regalloc = RegAlloc(MockAssembler(cpu, MockGcDescr(False)))
+ regalloc.assembler.datablockwrapper = 'fakedatablockwrapper'
+ boxes = [BoxPtr() for i in range(len(ARMv7RegisterManager.all_regs))]
+ longevity = {}
+ for box in boxes:
+ longevity[box] = (0, 1)
+ regalloc.fm = ARMFrameManager()
+ regalloc.rm = ARMv7RegisterManager(longevity, regalloc.fm,
+ assembler=regalloc.assembler)
+ regalloc.xrm = VFPRegisterManager(longevity, regalloc.fm,
+ assembler=regalloc.assembler)
+ cpu = regalloc.assembler.cpu
+ for box in boxes:
+ regalloc.rm.try_allocate_reg(box)
+ TP = lltype.FuncType([], lltype.Signed)
+ calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
+ regalloc.rm._check_invariants()
+ box = boxes[0]
+ regalloc.position = 0
+ regalloc.consider_call(ResOperation(rop.CALL, [box], BoxInt(),
+ calldescr))
+ assert len(regalloc.assembler.movs) == 3
+ #
+ mark = regalloc.get_mark_gc_roots(cpu.gc_ll_descr.gcrootmap)
+ assert mark[0] == 'compressed'
+ base = -WORD * FRAME_FIXED_SIZE
+ expected = ['ebx', 'esi', 'edi', base, base-WORD, base-WORD*2]
+ assert dict.fromkeys(mark[1:]) == dict.fromkeys(expected)
class TestRegallocGcIntegration(BaseTestRegalloc):
@@ -131,26 +183,29 @@
class GCDescrFastpathMalloc(GcLLDescription):
gcrootmap = None
-
+ expected_malloc_slowpath_size = WORD*2
+
def __init__(self):
GcCache.__init__(self, False)
# create a nursery
NTP = rffi.CArray(lltype.Signed)
self.nursery = lltype.malloc(NTP, 16, flavor='raw')
- self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2,
+ self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 3,
flavor='raw')
self.addrs[0] = rffi.cast(lltype.Signed, self.nursery)
- self.addrs[1] = self.addrs[0] + 64
- # 64 bytes
+ self.addrs[1] = self.addrs[0] + 16*WORD
+ self.addrs[2] = 0
+ # 16 WORDs
def malloc_slowpath(size):
- assert size == WORD*2
+ assert size == self.expected_malloc_slowpath_size
nadr = rffi.cast(lltype.Signed, self.nursery)
self.addrs[0] = nadr + size
+ self.addrs[2] += 1
return nadr
self.malloc_slowpath = malloc_slowpath
self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed],
lltype.Signed)
- self._counter = 123
+ self._counter = 123000
def can_inline_malloc(self, descr):
return True
@@ -169,7 +224,7 @@
def get_nursery_top_addr(self):
return rffi.cast(lltype.Signed, self.addrs) + WORD
- def get_malloc_fixedsize_slowpath_addr(self):
+ def get_malloc_slowpath_addr(self):
fptr = llhelper(lltype.Ptr(self.MALLOC_SLOWPATH), self.malloc_slowpath)
return rffi.cast(lltype.Signed, fptr)
@@ -185,9 +240,11 @@
cpu.gc_ll_descr = GCDescrFastpathMalloc()
cpu.setup_once()
- NODE = lltype.Struct('node', ('tid', lltype.Signed),
- ('value', lltype.Signed))
- nodedescr = cpu.sizeof(NODE) # xxx hack: NODE is not a GcStruct
+ # hack: specify 'tid' explicitly, because this test is not running
+ # with the gc transformer
+ NODE = lltype.GcStruct('node', ('tid', lltype.Signed),
+ ('value', lltype.Signed))
+ nodedescr = cpu.sizeof(NODE)
valuedescr = cpu.fielddescrof(NODE, 'value')
self.cpu = cpu
@@ -206,7 +263,6 @@
self.namespace = locals().copy()
def test_malloc_fastpath(self):
- py.test.skip()
ops = '''
[i0]
p0 = new(descr=nodedescr)
@@ -220,9 +276,9 @@
assert gc_ll_descr.nursery[1] == 42
nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
assert gc_ll_descr.addrs[0] == nurs_adr + (WORD*2)
+ assert gc_ll_descr.addrs[2] == 0 # slowpath never called
def test_malloc_slowpath(self):
- py.test.skip()
ops = '''
[]
p0 = new(descr=nodedescr)
@@ -241,9 +297,9 @@
gc_ll_descr = self.cpu.gc_ll_descr
nadr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
assert gc_ll_descr.addrs[0] == nadr + (WORD*2)
+ assert gc_ll_descr.addrs[2] == 1 # slowpath called once
def test_new_with_vtable(self):
- py.test.skip()
ops = '''
[i0, i1]
p0 = new_with_vtable(ConstClass(vtable))
@@ -257,3 +313,116 @@
assert gc_ll_descr.nursery[1] == self.vtable_int
nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
assert gc_ll_descr.addrs[0] == nurs_adr + (WORD*3)
+ assert gc_ll_descr.addrs[2] == 0 # slowpath never called
+
+
+class Seen(Exception):
+ pass
+
+class GCDescrFastpathMallocVarsize(GCDescrFastpathMalloc):
+ def can_inline_malloc_varsize(self, arraydescr, num_elem):
+ return num_elem < 5
+ def get_funcptr_for_newarray(self):
+ return 52
+ def init_array_descr(self, A, descr):
+ descr.tid = self._counter
+ self._counter += 1
+ def args_for_new_array(self, descr):
+ raise Seen("args_for_new_array")
+
+class TestMallocVarsizeFastpath(BaseTestRegalloc):
+ def setup_method(self, method):
+ cpu = CPU(None, None)
+ cpu.vtable_offset = WORD
+ cpu.gc_ll_descr = GCDescrFastpathMallocVarsize()
+ cpu.setup_once()
+ self.cpu = cpu
+
+ ARRAY = lltype.GcArray(lltype.Signed)
+ arraydescr = cpu.arraydescrof(ARRAY)
+ self.arraydescr = arraydescr
+ ARRAYCHAR = lltype.GcArray(lltype.Char)
+ arraychardescr = cpu.arraydescrof(ARRAYCHAR)
+
+ self.namespace = locals().copy()
+
+ def test_malloc_varsize_fastpath(self):
+ # Hack. Running the GcLLDescr_framework without really having
+ # a complete GC means that we end up with both the tid and the
+ # length being at offset 0. In this case, so the length overwrites
+ # the tid. This is of course only the case in this test class.
+ ops = '''
+ []
+ p0 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p0, 0, 142, descr=arraydescr)
+ setarrayitem_gc(p0, 3, 143, descr=arraydescr)
+ finish(p0)
+ '''
+ self.interpret(ops, [])
+ # check the nursery
+ gc_ll_descr = self.cpu.gc_ll_descr
+ assert gc_ll_descr.nursery[0] == 4
+ assert gc_ll_descr.nursery[1] == 142
+ assert gc_ll_descr.nursery[4] == 143
+ nurs_adr = rffi.cast(lltype.Signed, gc_ll_descr.nursery)
+ assert gc_ll_descr.addrs[0] == nurs_adr + (WORD*5)
+ assert gc_ll_descr.addrs[2] == 0 # slowpath never called
+
+ def test_malloc_varsize_slowpath(self):
+ ops = '''
+ []
+ p0 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p0, 0, 420, descr=arraydescr)
+ setarrayitem_gc(p0, 3, 430, descr=arraydescr)
+ p1 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p1, 0, 421, descr=arraydescr)
+ setarrayitem_gc(p1, 3, 431, descr=arraydescr)
+ p2 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p2, 0, 422, descr=arraydescr)
+ setarrayitem_gc(p2, 3, 432, descr=arraydescr)
+ p3 = new_array(4, descr=arraydescr)
+ setarrayitem_gc(p3, 0, 423, descr=arraydescr)
+ setarrayitem_gc(p3, 3, 433, descr=arraydescr)
+ finish(p0, p1, p2, p3)
+ '''
+ gc_ll_descr = self.cpu.gc_ll_descr
+ gc_ll_descr.expected_malloc_slowpath_size = 5*WORD
+ self.interpret(ops, [])
+ assert gc_ll_descr.addrs[2] == 1 # slowpath called once
+
+ def test_malloc_varsize_too_big(self):
+ ops = '''
+ []
+ p0 = new_array(5, descr=arraydescr)
+ finish(p0)
+ '''
+ py.test.raises(Seen, self.interpret, ops, [])
+
+ def test_malloc_varsize_variable(self):
+ ops = '''
+ [i0]
+ p0 = new_array(i0, descr=arraydescr)
+ finish(p0)
+ '''
+ py.test.raises(Seen, self.interpret, ops, [])
+
+ def test_malloc_array_of_char(self):
+ # check that fastpath_malloc_varsize() respects the alignment
+ # of the pointer in the nursery
+ ops = '''
+ []
+ p1 = new_array(1, descr=arraychardescr)
+ p2 = new_array(2, descr=arraychardescr)
+ p3 = new_array(3, descr=arraychardescr)
+ p4 = new_array(4, descr=arraychardescr)
+ finish(p1, p2, p3, p4)
+ '''
+ self.interpret(ops, [])
+ p1 = self.getptr(0, llmemory.GCREF)
+ p2 = self.getptr(1, llmemory.GCREF)
+ p3 = self.getptr(2, llmemory.GCREF)
+ p4 = self.getptr(3, llmemory.GCREF)
+ assert p1._obj.intval & (WORD-1) == 0 # aligned
+ assert p2._obj.intval & (WORD-1) == 0 # aligned
+ assert p3._obj.intval & (WORD-1) == 0 # aligned
+ assert p4._obj.intval & (WORD-1) == 0 # aligned
More information about the pypy-commit
mailing list