[pypy-svn] pypy arm-backend-2: Update arm backend to use asmmemmgr to manage code blocks and writes to memory

bivab commits-noreply at bitbucket.org
Fri Dec 17 18:22:06 CET 2010


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r40089:8b2e56b628f2
Date: 2010-12-17 14:23 +0100
http://bitbucket.org/pypy/pypy/changeset/8b2e56b628f2/

Log:	Update arm backend to use asmmemmgr to manage code blocks and writes to memory

diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -15,13 +15,29 @@
                  gcdescr=None):
         AbstractLLCPU.__init__(self, rtyper, stats, opts,
                                translate_support_code, gcdescr)
+    def setup(self):
+        if self.opts is not None:
+            failargs_limit = self.opts.failargs_limit
+        else:
+            failargs_limit = 1000
         self.assembler = AssemblerARM(self)
 
+    def setup_once(self):
+        self.assembler.setup_once()
+
+    def finish_once(self):
+        self.assembler.finish_once()
+
     def compile_loop(self, inputargs, operations, looptoken, log=True):
-        self.assembler.assemble_loop(inputargs, operations, looptoken)
+        self.assembler.assemble_loop(inputargs, operations,
+                                                    looptoken, log=log)
 
-    def compile_bridge(self, faildescr, inputargs, operations, log=True):
-        self.assembler.assemble_bridge(faildescr, inputargs, operations)
+    def compile_bridge(self, faildescr, inputargs, operations,
+                                       original_loop_token, log=True):
+        clt = original_loop_token.compiled_loop_token
+        clt.compiling_a_bridge()
+        self.assembler.assemble_bridge(faildescr, inputargs, operations,
+                                       original_loop_token, log=log)
 
     def set_future_value_int(self, index, intvalue):
         self.assembler.fail_boxes_int.setitem(index, intvalue)

diff --git a/pypy/jit/backend/arm/test/support.py b/pypy/jit/backend/arm/test/support.py
--- a/pypy/jit/backend/arm/test/support.py
+++ b/pypy/jit/backend/arm/test/support.py
@@ -10,10 +10,10 @@
 
 def run_asm(asm):
     BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
-    addr = asm.mc._start_addr
+    addr = asm.mc.materialize(asm.cpu.asmmemmgr, [], None)
     assert addr % 8 == 0
     func = rffi.cast(lltype.Ptr(BOOTSTRAP_TP), addr)
-    asm.mc._dump_trace('test.asm')
+    asm.mc._dump_trace(addr, 'test.asm')
     return func()
 
 def skip_unless_arm():

diff --git a/pypy/jit/backend/arm/test/test_ztranslate_backend.py b/pypy/jit/backend/arm/test/test_ztranslate_backend.py
--- a/pypy/jit/backend/arm/test/test_ztranslate_backend.py
+++ b/pypy/jit/backend/arm/test/test_ztranslate_backend.py
@@ -1,4 +1,5 @@
 import py
+import os
 from pypy.jit.metainterp.history import (AbstractFailDescr,
                                          AbstractDescr,
                                          BasicFailDescr,
@@ -11,6 +12,7 @@
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.jit.backend.detect_cpu import getcpuclass
 from pypy.jit.backend.arm.runner import ArmCPU
+from pypy.tool.udir import udir
 
 class FakeStats(object):
     pass
@@ -32,6 +34,7 @@
                 ]
             inputargs = [i0]
             operations[2].setfailargs([i1])
+            cpu.setup_once()
             cpu.compile_loop(inputargs, operations, looptoken)
 
             i1b = BoxInt()
@@ -42,14 +45,17 @@
                 ResOperation(rop.JUMP, [i1b], None, descr=looptoken),
             ]
             bridge[1].setfailargs([i1b])
-
-            cpu.compile_bridge(faildescr1, [i1b], bridge)
+            assert looptoken._arm_bootstrap_code != 0
+            assert looptoken._arm_loop_code != 0
+            cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken, True)
 
             cpu.set_future_value_int(0, 2)
             fail = cpu.execute_token(looptoken)
             res = cpu.get_latest_value_int(0)
             return fail.identifier * 1000 + res
 
+        logfile = udir.join('test_ztranslation.log')
+        os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,)
         res = interpret(loop, [], insist=True)
         assert res == 2020
 

diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -9,6 +9,7 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.jit.metainterp.history import ConstInt, BoxInt, AbstractFailDescr
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from pypy.tool.udir import udir
 
 def binary_helper_call(name):
@@ -22,29 +23,18 @@
             self.BL(addr)
         else:
             self.PUSH(range(2, 4), cond=c)
-            self.BL(addr, c, some_reg=reg.r2)
+            self.BL(addr, c)
             self.POP(range(2,4), cond=c)
     return f
 
 class AbstractARMv7Builder(object):
-    def _init(self, data, map_size):
-        self._data = data
-        self._size = map_size
-        self._pos = 0
 
-    def _dump_trace(self, name, formatter=-1):
-        if not we_are_translated():
-            if formatter != -1:
-                name = name % formatter
-            dir = udir.ensure('asm', dir=True)
-            f = dir.join(name).open('wb')
-            for i in range(self._pos):
-                f.write(self._data[i])
-            f.close()
+    def __init__(self):
+        pass
 
-    def ensure_can_fit(self, n):
-        raise NotImplementedError
-
+    def align(self):
+        while(self.currpos() % FUNC_ALIGN != 0):
+            self.writechar(chr(0))
     def NOP(self):
         self.MOV_rr(0, 0)
 
@@ -61,29 +51,43 @@
     def BKPT(self, cond=cond.AL):
         self.write32(cond << 28 | 0x1200070)
 
-    def B(self, target, c=cond.AL, some_reg=None):
+    def B(self, target, c=cond.AL):
         if c == cond.AL:
-            self.ensure_can_fit(2*WORD)
             self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET/2)
             self.write32(target)
         else:
-            assert some_reg is not None
-            self.ensure_can_fit(self.size_of_gen_load_int+WORD)
-            self.gen_load_int(some_reg.value, target, cond=c)
-            self.MOV_rr(reg.pc.value, some_reg.value, cond=c)
+            self.gen_load_int(reg.ip.value, target, cond=c)
+            self.MOV_rr(reg.pc.value, reg.ip.value, cond=c)
 
-    def BL(self, target, c=cond.AL, some_reg=None):
+    def B_offs(self, target_ofs, c=cond.AL):
+        target = target_ofs-arch.PC_OFFSET/2
+        pos = self.currpos()
+        if target_ofs > pos:
+            raise NotImplementedError
+        else:
+            if target >= 0 and target <= 0xFF:
+                pos = self.currpos()
+                target_ofs = pos - target_ofs
+                target = WORD + target_ofs + arch.PC_OFFSET/2
+                self.SUB_ri(reg.pc.value, reg.pc.value, target, cond=c)
+            else:
+                assert c == cond.AL
+                self.LDR_ri(reg.ip.value, reg.pc.value, cond=c)
+                self.SUB_rr(reg.pc.value, reg.pc.value, reg.ip.value, cond=c)
+                pos = self.currpos()
+                target_ofs = pos - target_ofs
+                target = WORD + target_ofs + arch.PC_OFFSET/2
+                self.write32(target)
+
+    def BL(self, target, c=cond.AL):
         if c == cond.AL:
-            self.ensure_can_fit(3*WORD)
             self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET/2)
             self.LDR_ri(reg.pc.value, reg.pc.value, imm=-arch.PC_OFFSET/2)
             self.write32(target)
         else:
-            assert some_reg is not None
-            self.ensure_can_fit(self.size_of_gen_load_int*2+WORD)
-            self.gen_load_int(some_reg.value, target, cond=c)
-            self.gen_load_int(reg.lr.value, self.curraddr()+self.size_of_gen_load_int+WORD, cond=c)
-            self.MOV_rr(reg.pc.value, some_reg.value, cond=c)
+            self.gen_load_int(reg.ip.value, target, cond=c)
+            self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET/2)
+            self.MOV_rr(reg.pc.value, reg.ip.value, cond=c)
 
     DIV = binary_helper_call('int_div')
     MOD = binary_helper_call('int_mod')
@@ -108,17 +112,10 @@
         self.writechar(chr((word >> 24) & 0xFF))
 
     def writechar(self, char):
-        self._data[self._pos] = char
-        self._pos += 1
-
-    def baseaddr(self):
-        return rffi.cast(lltype.Signed, self._data)
-
-    def curraddr(self):
-        return self.baseaddr() + self._pos
+        raise NotImplementedError
 
     def currpos(self):
-        return self._pos
+        raise NotImplementedError
 
     size_of_gen_load_int = 4 * WORD
     ofs_shift = zip(range(8, 25, 8), range(12, 0, -4))
@@ -134,51 +131,54 @@
             self.ORR_ri(r, r, imm=t, cond=cond)
 
 
-class ARMv7InMemoryBuilder(AbstractARMv7Builder):
-    def __init__(self, start, end):
-        map_size = end - start
-        data = rffi.cast(PTR, start)
-        self._init(data, map_size)
+class OverwritingBuilder(AbstractARMv7Builder):
+    def __init__(self, cb, start, size):
+        AbstractARMv7Builder.__init__(self)
+        self.cb = cb
+        self.index = start
+        self.end = start + size
 
-    def ensure_can_fit(self, n):
-        """ensure after this call there is enough space for n instructions
-        in a contiguous memory chunk or raise an exception"""
-        if not self._pos + n < self._size:
-            raise ValueError
+    def writechar(self, char):
+        assert self.index <= self.end
+        self.cb.overwrite(self.index, char)
+        self.index += 1
 
-class ARMv7Builder(AbstractARMv7Builder):
+class ARMv7Builder(BlockBuilderMixin, AbstractARMv7Builder):
+    def __init__(self):
+        AbstractARMv7Builder.__init__(self)
+        self.init_block_builder()
 
-    def __init__(self):
-        map_size = 4096
-        data = alloc(map_size)
-        self._pos = 0
-        self._init(data, map_size)
-        self.checks = True
-        self.n_data=0
+    def _dump_trace(self, addr, name, formatter=-1):
+        if not we_are_translated():
+            if formatter != -1:
+                name = name % formatter
+            dir = udir.ensure('asm', dir=True)
+            f = dir.join(name).open('wb')
+            data = rffi.cast(rffi.CCHARP, addr)
+            for i in range(self.currpos()):
+                f.write(data[i])
+            f.close()
 
-    _space_for_jump = 2 * WORD
-    def writechar(self, char):
-        if self.checks and not self._pos < self._size - self._space_for_jump - WORD:
-            self._add_more_mem()
-        assert self._pos < self._size - 1
-        AbstractARMv7Builder.writechar(self, char)
+    # XXX remove and setup aligning in llsupport
+    def materialize(self, asmmemmgr, allblocks, gcrootmap=None):
+        size = self.get_relative_pos()
+        malloced = asmmemmgr.malloc(size, size+7)
+        allblocks.append(malloced)
+        rawstart = malloced[0]
+        while(rawstart % FUNC_ALIGN != 0):
+            rawstart += 1
+        self.copy_to_raw_memory(rawstart)
+        if self.gcroot_markers is not None:
+            assert gcrootmap is not None
+            for pos, mark in self.gcroot_markers:
+                gcrootmap.put(rawstart + pos, mark)
+        return rawstart
 
-    def _add_more_mem(self):
-        self.checks = False
-        new_mem = alloc(self._size)
-        new_mem_addr = rffi.cast(lltype.Signed, new_mem)
-        self.LDR_ri(reg.pc.value, reg.pc.value, -4)
-        self.write32(new_mem_addr)
-        self._dump_trace('data%04d.asm', self.n_data)
-        self.n_data += 1
-        self._data = new_mem
-        self._pos = 0
-        self.checks = True
+    def copy_to_raw_memory(self, addr):
+        self._copy_to_raw_memory(addr)
 
-    def ensure_can_fit(self, n):
-        """ensure after this call there is enough space for n instructions
-        in a contiguous memory chunk"""
-        if not self._pos + n + self._space_for_jump < self._size - WORD:
-            self._add_more_mem()
+    def currpos(self):
+        return self.get_relative_pos()
+
 
 define_instructions(AbstractARMv7Builder)

diff --git a/pypy/jit/backend/arm/test/test_assembler.py b/pypy/jit/backend/arm/test/test_assembler.py
--- a/pypy/jit/backend/arm/test/test_assembler.py
+++ b/pypy/jit/backend/arm/test/test_assembler.py
@@ -1,10 +1,11 @@
-from pypy.jit.backend.arm.arch import arm_int_div, arm_int_div_sign
+from pypy.jit.backend.arm import arch
 from pypy.jit.backend.arm import conditions as c
 from pypy.jit.backend.arm import registers as r
 from pypy.jit.backend.arm.arch import WORD
+from pypy.jit.backend.arm.arch import arm_int_div, arm_int_div_sign
 from pypy.jit.backend.arm.assembler import AssemblerARM
-from pypy.jit.backend.arm.codebuilder import ARMv7InMemoryBuilder
 from pypy.jit.backend.arm.test.support import skip_unless_arm, run_asm
+from pypy.jit.backend.detect_cpu import getcpuclass
 from pypy.jit.metainterp.resoperation import rop
 
 from pypy.rpython.annlowlevel import llhelper
@@ -12,10 +13,13 @@
 
 skip_unless_arm()
 
+CPU = getcpuclass()
 class TestRunningAssembler():
     def setup_method(self, method):
-        self.a = AssemblerARM(None)
-        self.a.setup_mc()
+        cpu = CPU(None, None)
+        self.a = AssemblerARM(cpu)
+        self.a.setup_once()
+        self.a.setup()
 
     def test_make_operation_list(self):
         i = rop.INT_ADD
@@ -88,11 +92,11 @@
     def test_simple_jump(self):
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r1.value, 1)
-        loop_head = self.a.mc.curraddr()
+        loop_head = self.a.mc.currpos()
         self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
         self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
         self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
-        self.a.mc.B(loop_head, c.NE, some_reg = r.r4)
+        self.a.mc.B_offs(loop_head, c.NE)
         self.a.mc.MOV_rr(r.r0.value, r.r1.value)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 7
@@ -100,28 +104,14 @@
     def test_jump(self):
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r1.value, 1)
-        loop_head = self.a.mc.curraddr()
+        loop_head = self.a.mc.currpos()
         self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
         self.a.mc.CMP_ri(r.r1.value, 9)
-        self.a.mc.B(loop_head, c.NE, some_reg = r.r4)
+        self.a.mc.B_offs(loop_head, c.NE)
         self.a.mc.MOV_rr(r.r0.value, r.r1.value)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 9
 
-    def test_jump_with_inline_address(self):
-        self.a.gen_func_prolog()
-        self.a.mc.MOV_ri(r.r1.value, 1)
-        loop_head = self.a.mc.curraddr()
-        self.a.mc.ADD_ri(r.r1.value, r.r1.value, 1)
-        self.a.mc.CMP_ri(r.r1.value, 9)
-        self.a.mc.LDR_ri(r.pc.value, r.pc.value,
-        imm=self.a.epilog_size, cond=c.NE) # we want to read after the last instr. of gen_func_prolog
-        self.a.mc.MOV_rr(r.r0.value, r.r1.value)
-        self.a.gen_func_epilog()
-        self.a.mc.write32(loop_head)
-        assert run_asm(self.a) == 9
-
-
     def test_call_python_func(self):
         functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
         call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
@@ -139,7 +129,7 @@
         # call to div
         self.a.mc.PUSH(range(2, 12))
         div_addr = rffi.cast(lltype.Signed, llhelper(arm_int_div_sign, arm_int_div))
-        self.a.mc.BL(div_addr, some_reg=r.r2)
+        self.a.mc.BL(div_addr)
         self.a.mc.POP(range(2, 12))
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 61
@@ -177,7 +167,7 @@
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r0.value, 123)
         self.a.mc.CMP_ri(r.r0.value, 1)
-        self.a.mc.BL(call_addr, c.NE, some_reg=r.r1)
+        self.a.mc.BL(call_addr, c.NE)
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 133
 

diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -2,10 +2,11 @@
 from pypy.jit.backend.arm import locations
 from pypy.jit.backend.arm import registers as r
 from pypy.jit.backend.arm.arch import WORD, FUNC_ALIGN, PC_OFFSET
-from pypy.jit.backend.arm.codebuilder import ARMv7Builder, ARMv7InMemoryBuilder
+from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
 from pypy.jit.backend.arm.regalloc import (ARMRegisterManager, ARMFrameManager,
                                                             TempInt, TempPtr)
 from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity, TempBox
+from pypy.jit.backend.model import CompiledLoopToken
 from pypy.jit.metainterp.history import (Const, ConstInt, ConstPtr,
                                         BoxInt, BoxPtr, AbstractFailDescr,
                                         INT, REF, FLOAT)
@@ -52,43 +53,39 @@
         self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
         self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
         self.setup_failure_recovery()
-        self._debug_asm = True
         self.mc = None
         self.malloc_func_addr = 0
         self.malloc_array_func_addr = 0
         self.malloc_str_func_addr = 0
         self.malloc_unicode_func_addr = 0
         self.memcpy_addr = 0
-
-    def setup_mc(self):
-        self.mc = ARMv7Builder()
-        self._exit_code_addr = self.mc.curraddr()
-        self._gen_exit_path()
-        self.align()
-        self.mc._start_addr = self.mc.curraddr()
+        self.teardown()
+        self._exit_code_addr = 0
 
     def setup(self):
-        if self.mc is None:
-            self.setup_mc()
+        assert self.memcpy_addr != 0, 'setup_once() not called?'
+        self.mc = ARMv7Builder()
 
-            # Addresses of functions called by new_xxx operations
-            gc_ll_descr = self.cpu.gc_ll_descr
-            gc_ll_descr.initialize()
-            ll_new = gc_ll_descr.get_funcptr_for_new()
-            self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
-            if gc_ll_descr.get_funcptr_for_newarray is not None:
-                ll_new_array = gc_ll_descr.get_funcptr_for_newarray()
-                self.malloc_array_func_addr = rffi.cast(lltype.Signed,
-                                                        ll_new_array)
-            if gc_ll_descr.get_funcptr_for_newstr is not None:
-                ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
-                self.malloc_str_func_addr = rffi.cast(lltype.Signed,
-                                                      ll_new_str)
-            if gc_ll_descr.get_funcptr_for_newunicode is not None:
-                ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
-                self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
-                                                          ll_new_unicode)
-            self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
+    def setup_once(self):
+        # Addresses of functions called by new_xxx operations
+        gc_ll_descr = self.cpu.gc_ll_descr
+        gc_ll_descr.initialize()
+        ll_new = gc_ll_descr.get_funcptr_for_new()
+        self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
+        if gc_ll_descr.get_funcptr_for_newarray is not None:
+            ll_new_array = gc_ll_descr.get_funcptr_for_newarray()
+            self.malloc_array_func_addr = rffi.cast(lltype.Signed,
+                                                    ll_new_array)
+        if gc_ll_descr.get_funcptr_for_newstr is not None:
+            ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
+            self.malloc_str_func_addr = rffi.cast(lltype.Signed,
+                                                  ll_new_str)
+        if gc_ll_descr.get_funcptr_for_newunicode is not None:
+            ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
+            self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
+                                                      ll_new_unicode)
+        self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
+        self._exit_code_addr = self._gen_exit_path()
 
 
     def setup_failure_recovery(self):
@@ -198,19 +195,21 @@
         mem[i+3] = chr((n >> 24) & 0xFF)
 
     def _gen_exit_path(self):
+        mc = ARMv7Builder()
         decode_registers_addr = llhelper(self.recovery_func_sign, self.failure_recovery_func)
 
-        self.mc.PUSH([reg.value for reg in r.all_regs])     # registers r0 .. r10
-        self.mc.MOV_rr(r.r0.value, r.lr.value) # move mem block address, to r0 to pass as
-        self.mc.MOV_rr(r.r1.value, r.fp.value) # pass the current frame pointer as second param
-        self.mc.MOV_rr(r.r2.value, r.sp.value) # pass the current stack pointer as third param
+        mc.PUSH([reg.value for reg in r.all_regs])     # registers r0 .. r10
+        mc.MOV_rr(r.r0.value, r.lr.value) # move mem block address, to r0 to pass as
+        mc.MOV_rr(r.r1.value, r.fp.value) # pass the current frame pointer as second param
+        mc.MOV_rr(r.r2.value, r.sp.value) # pass the current stack pointer as third param
 
-        self.mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
-        self.mc.MOV_rr(r.ip.value, r.r0.value)
-        self.mc.POP([reg.value for reg in r.all_regs])
-        self.mc.MOV_rr(r.r0.value, r.ip.value)
-        self.mc.ensure_can_fit(self.epilog_size)
-        self.gen_func_epilog()
+        mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
+        mc.MOV_rr(r.ip.value, r.r0.value)
+        mc.POP([reg.value for reg in r.all_regs])
+        mc.MOV_rr(r.r0.value, r.ip.value)
+        self.gen_func_epilog(mc=mc)
+        return mc.materialize(self.cpu.asmmemmgr, [],
+                                   self.cpu.gc_ll_descr.gcrootmap)
 
     def _gen_path_to_exit_path(self, op, args, arglocs, fcond=c.AL):
         descr = op.getdescr()
@@ -259,7 +258,6 @@
 
         n = self.cpu.get_fail_descr_number(descr)
         self.encode32(mem, j+1, n)
-        self.mc.ensure_can_fit(4*WORD)
         self.mc.LDR_ri(r.lr.value, r.pc.value, imm=WORD)
         self.mc.B(self._exit_code_addr)
         self.mc.write32(memaddr)
@@ -267,14 +265,16 @@
         return memaddr
 
     def align(self):
-        while(self.mc.curraddr() % FUNC_ALIGN != 0):
+        while(self.mc.currpos() % FUNC_ALIGN != 0):
             self.mc.writechar(chr(0))
 
     epilog_size = 3*WORD
-    def gen_func_epilog(self,cond=c.AL):
-        self.mc.MOV_rr(r.sp.value, r.fp.value)
-        self.mc.ADD_ri(r.sp.value, r.sp.value, WORD)
-        self.mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond)
+    def gen_func_epilog(self, mc=None, cond=c.AL):
+        if mc is None:
+            mc = self.mc
+        mc.MOV_rr(r.sp.value, r.fp.value)
+        mc.ADD_ri(r.sp.value, r.sp.value, WORD)
+        mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond)
 
     def gen_func_prolog(self):
         self.mc.PUSH([reg.value for reg in r.callee_saved_registers])
@@ -300,7 +300,6 @@
 
     direct_bootstrap_code_size=100*WORD
     def gen_direct_bootstrap_code(self, arglocs, loop_head, regalloc):
-        self.mc.ensure_can_fit(self.direct_bootstrap_code_size)
         self.gen_func_prolog()
         if len(arglocs) > 4:
             reg_args = 4
@@ -323,53 +322,102 @@
                 self.mov_loc_loc(r.ip, loc)
             else:
                 assert 0, 'invalid location'
-        sp_patch_location = self._prepare_sp_patch_location()
-        self.mc.B(loop_head)
+        sp_patch_location = self._prepare_sp_patch_position()
+        self.mc.B_offs(loop_head)
         self._patch_sp_offset(sp_patch_location, regalloc)
 
     # cpu interface
-    def assemble_loop(self, inputargs, operations, looptoken):
+    def assemble_loop(self, inputargs, operations, looptoken, log):
         self.setup()
-        self.debug = False
         longevity = compute_vars_longevity(inputargs, operations)
         regalloc = ARMRegisterManager(longevity, assembler=self, frame_manager=ARMFrameManager())
+
+        clt = CompiledLoopToken(self.cpu, looptoken.number)
+        looptoken.compiled_loop_token = clt
+
         self.align()
-        loop_start=self.mc.curraddr()
         self.gen_func_prolog()
+        arglocs = self.gen_bootstrap_code(inputargs, regalloc, looptoken)
+        sp_patch_location = self._prepare_sp_patch_position()
 
+        loop_head = self.mc.currpos()
 
-        arglocs = self.gen_bootstrap_code(inputargs, regalloc, looptoken)
-        sp_patch_location = self._prepare_sp_patch_location()
+        looptoken._arm_loop_code = loop_head
+        looptoken._arm_bootstrap_code = 0
 
-        loop_head=self.mc.curraddr()
-        looptoken._arm_bootstrap_code = loop_start
-        looptoken._arm_loop_code = loop_head
-        print 'Loop', inputargs, operations
         self._walk_operations(operations, regalloc)
 
         self._patch_sp_offset(sp_patch_location, regalloc)
 
         self.align()
 
-        looptoken._arm_direct_bootstrap_code = self.mc.curraddr()
+        direct_bootstrap_code = self.mc.currpos()
         self.gen_direct_bootstrap_code(arglocs, loop_head, regalloc)
 
-        if self._debug_asm:
-            self._dump_trace('loop.asm')
-        print 'Done assembling loop with token %r' % looptoken
+        loop_start = self.materialize_loop(looptoken)
+        looptoken._arm_bootstrap_code = loop_start
+        looptoken._arm_direct_bootstrap_code = loop_start + direct_bootstrap_code
 
-    def _prepare_sp_patch_location(self):
+        if log:
+            print 'Loop', inputargs, operations
+            self.mc._dump_trace(loop_start, 'loop.asm')
+            print 'Done assembling loop with token %r' % looptoken
+        self.teardown()
+
+    def assemble_bridge(self, faildescr, inputargs, operations,
+                                                    original_loop_token, log):
+        self.setup()
+        assert isinstance(faildescr, AbstractFailDescr)
+        code = faildescr._failure_recovery_code
+        enc = rffi.cast(rffi.CCHARP, code)
+        longevity = compute_vars_longevity(inputargs, operations)
+        regalloc = ARMRegisterManager(longevity, assembler=self,
+                                            frame_manager=ARMFrameManager())
+
+        frame_depth = faildescr._arm_frame_depth
+        locs = self.decode_inputargs(enc, inputargs, regalloc)
+        regalloc.update_bindings(locs, frame_depth, inputargs)
+        sp_patch_location = self._prepare_sp_patch_position()
+
+        self._walk_operations(operations, regalloc)
+
+        self._patch_sp_offset(sp_patch_location, regalloc)
+
+        bridge_start = self.materialize_loop(original_loop_token)
+
+        self.patch_trace(faildescr, original_loop_token, bridge_start, regalloc)
+        if log:
+            print 'Bridge', inputargs, operations
+            self.mc._dump_trace(bridge_start, 'bridge.asm')
+        self.teardown()
+
+    def materialize_loop(self, looptoken):
+        allblocks = self.get_asmmemmgr_blocks(looptoken)
+        return self.mc.materialize(self.cpu.asmmemmgr, allblocks,
+                                   self.cpu.gc_ll_descr.gcrootmap)
+
+    def teardown(self):
+        self.mc = None
+        #self.looppos = -1
+        #self.currently_compiling_loop = None
+
+    def get_asmmemmgr_blocks(self, looptoken):
+        clt = looptoken.compiled_loop_token
+        if clt.asmmemmgr_blocks is None:
+            clt.asmmemmgr_blocks = []
+        return clt.asmmemmgr_blocks
+
+    def _prepare_sp_patch_position(self):
         """Generate NOPs as placeholder to patch the instruction(s) to update the
         sp according to the number of spilled variables"""
         size = (self.mc.size_of_gen_load_int+WORD)
-        self.mc.ensure_can_fit(size)
-        l = self.mc.curraddr()
+        l = self.mc.currpos()
         for _ in range(size//WORD):
             self.mc.MOV_rr(r.r0.value, r.r0.value)
         return l
 
-    def _patch_sp_offset(self, addr, regalloc):
-        cb = ARMv7InMemoryBuilder(addr, ARMv7InMemoryBuilder.size_of_gen_load_int)
+    def _patch_sp_offset(self, pos, regalloc):
+        cb = OverwritingBuilder(self.mc, pos, OverwritingBuilder.size_of_gen_load_int)
         # Note: the frame_depth is one less than the value stored in the frame
         # manager
         if regalloc.frame_manager.frame_depth == 1:
@@ -426,36 +474,6 @@
             return True
         return False
 
-    def assemble_bridge(self, faildescr, inputargs, operations):
-        self.setup()
-        self.debug = False
-        code = faildescr._failure_recovery_code
-        assert isinstance(code, int)
-        enc = rffi.cast(rffi.CCHARP, code)
-        longevity = compute_vars_longevity(inputargs, operations)
-        regalloc = ARMRegisterManager(longevity, assembler=self, frame_manager=ARMFrameManager())
-
-        bridge_head = self.mc.curraddr()
-        frame_depth = faildescr._arm_frame_depth
-        locs = self.decode_inputargs(enc, inputargs, regalloc)
-        regalloc.update_bindings(locs, frame_depth, inputargs)
-        sp_patch_location = self._prepare_sp_patch_location()
-
-        print 'Bridge', inputargs, operations
-        self._walk_operations(operations, regalloc)
-
-        self._patch_sp_offset(sp_patch_location, regalloc)
-
-        print 'Done building bridges'
-        self.patch_trace(faildescr, bridge_head, regalloc)
-        print 'Done patching trace'
-        if self._debug_asm:
-            self._dump_trace('bridge.asm')
-
-
-    def _dump_trace(self, name):
-        self.mc._dump_trace(name)
-
 
     def _ensure_result_bit_extension(self, resloc, size, signed):
         if size == 4:
@@ -477,12 +495,13 @@
                 self.mc.LSL_ri(resloc.value, resloc.value, 16)
                 self.mc.ASR_ri(resloc.value, resloc.value, 16)
 
-    def patch_trace(self, faildescr, bridge_addr, regalloc):
+    def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc):
         # The first instruction (word) is not overwritten, because it is the
         # one that actually checks the condition
-        b = ARMv7InMemoryBuilder(faildescr._arm_guard_code,
-                                        self.guard_size-WORD)
-        b.B(bridge_addr, some_reg=r.lr)
+        b = ARMv7Builder()
+        patch_addr = looptoken._arm_bootstrap_code + faildescr._arm_guard_pos
+        b.B(bridge_addr)
+        b.copy_to_raw_memory(patch_addr)
 
     # regalloc support
     def load(self, loc, value):

diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -9,7 +9,7 @@
 from pypy.jit.backend.arm.helper.assembler import (gen_emit_op_by_helper_call,
                                                     gen_emit_op_unary_cmp,
                                                     gen_emit_op_ri, gen_emit_cmp_op)
-from pypy.jit.backend.arm.codebuilder import ARMv7Builder, ARMv7InMemoryBuilder
+from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
 from pypy.jit.backend.arm.jump import remap_frame_layout
 from pypy.jit.backend.arm.regalloc import ARMRegisterManager
 from pypy.jit.backend.llsupport import symbolic
@@ -139,11 +139,9 @@
         if not we_are_translated() and hasattr(op, 'getfailargs'):
            print 'Failargs: ', op.getfailargs()
 
-        self.mc.ensure_can_fit(self.guard_size)
         self.mc.ADD_ri(r.pc.value, r.pc.value, self.guard_size-PC_OFFSET, cond=fcond)
-        descr._arm_guard_code = self.mc.curraddr()
-
         self.mc.PUSH([reg.value for reg in r.caller_resp])
+        descr._arm_guard_pos = self.mc.currpos()
         addr = self.cpu.get_on_leave_jitted_int(save_exception=save_exc)
         self.mc.BL(addr)
         self.mc.POP([reg.value for reg in r.caller_resp])
@@ -194,10 +192,6 @@
 
     def emit_op_guard_nonnull_class(self, op, arglocs, regalloc, fcond):
         offset = self.cpu.vtable_offset
-        if offset is not None:
-            self.mc.ensure_can_fit(self.guard_size+3*WORD)
-        else:
-            raise NotImplementedError
 
         self.mc.CMP_ri(arglocs[0].value, 0)
         if offset is not None:
@@ -229,10 +223,14 @@
         descr = op.getdescr()
         assert isinstance(descr, LoopToken)
         destlocs = descr._arm_arglocs
-        loop_code = descr._arm_loop_code
+        assert fcond == c.AL
 
         remap_frame_layout(self, arglocs, destlocs, r.ip)
-        self.mc.B(loop_code, fcond)
+        if descr._arm_bootstrap_code == 0:
+            self.mc.B_offs(descr._arm_loop_code, fcond)
+        else:
+            target = descr._arm_bootstrap_code + descr._arm_loop_code
+            self.mc.B(target, fcond)
         return fcond
 
     def emit_op_finish(self, op, arglocs, regalloc, fcond):
@@ -287,7 +285,6 @@
 
         #the actual call
         self.mc.BL(adr)
-
         regalloc.possibly_free_vars(args)
         # readjust the sp in case we passed some args on the stack
         if n_args > 4:
@@ -629,11 +626,9 @@
     def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond):
         descr = op.getdescr()
         assert isinstance(descr, LoopToken)
-
         resbox = TempBox()
         self._emit_call(descr._arm_direct_bootstrap_code, op.getarglist(),
-                                                regalloc, fcond, result=resbox)
-        #self.mc.ensure_bytes_available(256)
+                                regalloc, fcond, result=resbox, spill_all_regs=True)
         if op.result is None:
             value = self.cpu.done_with_this_frame_void_v
         else:
@@ -649,14 +644,12 @@
         assert value <= 0xff
 
         # check value
-        loc, t = regalloc._ensure_value_is_boxed(ConstInt(value))
         resloc = regalloc.force_allocate_reg(resbox)
         self.mc.gen_load_int(r.ip.value, value)
         self.mc.CMP_rr(resloc.value, r.ip.value)
-        regalloc.possibly_free_var(resbox)
 
         fast_jmp_pos = self.mc.currpos()
-        fast_jmp_location = self.mc.curraddr()
+        #fast_jmp_location = self.mc.curraddr()
         self.mc.NOP()
 
         #if values are equal we take the fast pat
@@ -665,17 +658,18 @@
         jd = descr.outermost_jitdriver_sd
         assert jd is not None
         asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
-        self._emit_call(asm_helper_adr, [t, op.getarg(0)], regalloc, fcond, op.result)
-        regalloc.possibly_free_var(t)
+        self._emit_call(asm_helper_adr, [resbox, op.getarg(0)], regalloc, fcond, op.result)
+        regalloc.possibly_free_var(resbox)
         # jump to merge point
         jmp_pos = self.mc.currpos()
-        jmp_location = self.mc.curraddr()
+        #jmp_location = self.mc.curraddr()
         self.mc.NOP()
 
         # Fast Path using result boxes
         # patch the jump to the fast path
         offset = self.mc.currpos() - fast_jmp_pos
-        pmc = ARMv7InMemoryBuilder(fast_jmp_location, WORD)
+        pmc = OverwritingBuilder(self.mc, fast_jmp_pos, WORD)
+        #pmc = ARMv7InMemoryBuilder(fast_jmp_location, WORD)
         pmc.ADD_ri(r.pc.value, r.pc.value, offset - PC_OFFSET, cond=c.EQ)
 
         # Reset the vable token --- XXX really too much special logic here:-(
@@ -708,15 +702,13 @@
             self.mc.LDR_ri(resloc.value, r.ip.value)
 
         offset = self.mc.currpos() - jmp_pos
-        pmc = ARMv7InMemoryBuilder(jmp_location, WORD)
+        pmc = OverwritingBuilder(self.mc, jmp_pos, WORD)
         pmc.ADD_ri(r.pc.value, r.pc.value, offset - PC_OFFSET)
 
-        l0 = regalloc.force_allocate_reg(t)
-        self.mc.LDR_ri(l0.value, r.fp.value)
-        self.mc.CMP_ri(l0.value, 0)
+        self.mc.LDR_ri(r.ip.value, r.fp.value)
+        self.mc.CMP_ri(r.ip.value, 0)
 
         self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), c.GE)
-        regalloc.possibly_free_var(t)
         regalloc.possibly_free_vars_for_op(op)
         if op.result:
             regalloc.possibly_free_var(op.result)

diff --git a/pypy/jit/backend/arm/test/test_zll_random.py b/pypy/jit/backend/arm/test/test_zll_random.py
--- a/pypy/jit/backend/arm/test/test_zll_random.py
+++ b/pypy/jit/backend/arm/test/test_zll_random.py
@@ -9,6 +9,7 @@
 
 def test_stress():
     cpu = CPU(None, None)
+    cpu.setup_once()
     for i in range(1000):
         r = Random()
         check_random_function(cpu, LLtypeOperationBuilder, r, i, 1000)

diff --git a/pypy/jit/backend/arm/test/test_runner.py b/pypy/jit/backend/arm/test/test_runner.py
--- a/pypy/jit/backend/arm/test/test_runner.py
+++ b/pypy/jit/backend/arm/test/test_runner.py
@@ -18,13 +18,11 @@
     pass
 
 class TestARM(LLtypeBackendTest):
-
+    def __init__(self):
+        self.cpu = ArmCPU(rtyper=None, stats=FakeStats())
+        self.cpu.setup_once()
     # for the individual tests see
     # ====> ../../test/runner_test.py
-
-    def setup_method(self, meth):
-        self.cpu = ArmCPU(rtyper=None, stats=FakeStats())
-
     def test_result_is_spilled(self):
         cpu = self.cpu
         inp = [BoxInt(i) for i in range(1, 15)]

diff --git a/pypy/jit/backend/arm/test/test_generated.py b/pypy/jit/backend/arm/test/test_generated.py
--- a/pypy/jit/backend/arm/test/test_generated.py
+++ b/pypy/jit/backend/arm/test/test_generated.py
@@ -30,6 +30,7 @@
         v11 = BoxInt()
         v12 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_SUB, [ConstInt(-1073741824), v7], v11),
@@ -81,6 +82,7 @@
         v17 = BoxInt()
         v18 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_SUB, [ConstInt(21), v5], v11),
@@ -136,6 +138,7 @@
         v12 = BoxInt()
         tmp13 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_EQ, [ConstInt(17), v9], v11),
@@ -186,6 +189,7 @@
         v14 = BoxInt()
         v15 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_LT, [v9, v9], v11),
@@ -237,6 +241,7 @@
         v14 = BoxInt()
         v15 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_LT, [v5, ConstInt(-67)], v11),
@@ -294,6 +299,7 @@
         tmp16 = BoxInt()
         tmp17 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_IS_TRUE, [v1], tmp15),
@@ -352,6 +358,7 @@
         v16 = BoxInt()
         tmp17 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_ADD_OVF, [v8, ConstInt(-30)], v11),
@@ -408,6 +415,7 @@
         v15 = BoxInt()
         v16 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.UINT_LT, [ConstInt(-11), v7], v11),
@@ -469,6 +477,7 @@
         tmp16 = BoxInt()
         tmp17 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_IS_TRUE, [v3], tmp16),
@@ -527,6 +536,7 @@
         v11 = BoxInt()
         tmp12 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_ADD, [ConstInt(-1073741825), v3], v11),
@@ -578,6 +588,7 @@
         v14 = BoxInt()
         v15 = BoxInt()
         cpu = CPU(None, None)
+        cpu.setup_once()
         inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10]
         operations = [
             ResOperation(rop.INT_LE, [v6, v1], v11),

diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -46,6 +46,7 @@
     save_around_call_regs = r.caller_resp
 
     def __init__(self, longevity, frame_manager=None, assembler=None):
+        self.cpu = assembler.cpu
         RegisterManager.__init__(self, longevity, frame_manager, assembler)
 
     def convert_to_imm(self, c):
@@ -80,6 +81,21 @@
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
 
+    def before_call(self, force_store=[], save_all_regs=False):
+        for v, reg in self.reg_bindings.items():
+            if(reg in self.save_around_call_regs and v not in force_store and
+                        self.longevity[v][1] <= self.position):
+                # variable dies
+                del self.reg_bindings[v]
+                self.free_regs.append(reg)
+                continue
+            if not save_all_regs and reg not in self.save_around_call_regs:
+                # we don't have to
+                continue
+            self._sync_var(v)
+            del self.reg_bindings[v]
+            self.free_regs.append(reg)
+
     def force_spill_var(self, var):
         self._sync_var(var)
         try:
@@ -317,15 +333,15 @@
             boxes.append(op.result)
         else:
             resloc = None
-        pos_exc_value = imm(self.assembler.cpu.pos_exc_value())
-        pos_exception = imm(self.assembler.cpu.pos_exception())
+        pos_exc_value = imm(self.cpu.pos_exc_value())
+        pos_exception = imm(self.cpu.pos_exception())
         arglocs = self._prepare_guard(op, [loc, loc1, resloc, pos_exc_value, pos_exception])
         self.possibly_free_vars(boxes)
         return arglocs
 
     def prepare_op_guard_no_exception(self, op, fcond):
         loc, box = self._ensure_value_is_boxed(
-                    ConstInt(self.assembler.cpu.pos_exception()))
+                    ConstInt(self.cpu.pos_exception()))
         arglocs = self._prepare_guard(op, [loc])
         self.possibly_free_var(box)
         return arglocs
@@ -388,7 +404,7 @@
     def prepare_op_arraylen_gc(self, op, fcond):
         arraydescr = op.getdescr()
         assert isinstance(arraydescr, BaseArrayDescr)
-        ofs = arraydescr.get_ofs_length(self.assembler.cpu.translate_support_code)
+        ofs = arraydescr.get_ofs_length(self.cpu.translate_support_code)
         arg = op.getarg(0)
         base_loc, base_box = self._ensure_value_is_boxed(arg)
         self.possibly_free_vars([arg, base_box])
@@ -434,7 +450,7 @@
 
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         ofs_box = ConstInt(ofs_length)
         imm_ofs = self._check_imm_arg(ofs_box)
 
@@ -467,7 +483,7 @@
         self.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         assert itemsize == 1
         return [res, base_loc, ofs_loc, imm(basesize)]
 
@@ -486,7 +502,7 @@
         self.possibly_free_vars(boxes)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         assert itemsize == 1
         return [value_loc, base_loc, ofs_loc, imm(basesize)]
 
@@ -497,7 +513,7 @@
         l0, box = self._ensure_value_is_boxed(op.getarg(0))
         boxes = [box]
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         ofs_box = ConstInt(ofs_length)
         imm_ofs = self._check_imm_arg(ofs_box)
 
@@ -524,7 +540,7 @@
         self.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         scale = itemsize/2
         return [res, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
 
@@ -540,7 +556,7 @@
         self.possibly_free_vars(boxes)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
-                                         self.assembler.cpu.translate_support_code)
+                                         self.cpu.translate_support_code)
         scale = itemsize/2
         return [value_loc, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
 
@@ -568,7 +584,7 @@
 
     def prepare_op_new_with_vtable(self, op, fcond):
         classint = op.getarg(0).getint()
-        descrsize = heaptracker.vtable2descr(self.assembler.cpu, classint)
+        descrsize = heaptracker.vtable2descr(self.cpu, classint)
         callargs = self._prepare_args_for_new_op(descrsize)
         self.assembler._emit_call(self.assembler.malloc_func_addr,
                                     callargs, self, result=op.result)
@@ -577,7 +593,7 @@
         return [imm(classint)]
 
     def prepare_op_new_array(self, op, fcond):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        gc_ll_descr = self.cpu.gc_ll_descr
         if gc_ll_descr.get_funcptr_for_newarray is not None:
             raise NotImplementedError
         # boehm GC
@@ -586,24 +602,24 @@
         return self._malloc_varsize(basesize, ofs_length, itemsize, op)
 
     def prepare_op_newstr(self, op, fcond):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        gc_ll_descr = self.cpu.gc_ll_descr
         if gc_ll_descr.get_funcptr_for_newstr is not None:
             raise NotImplementedError
         # boehm GC
         ofs_items, itemsize, ofs = symbolic.get_array_token(rstr.STR,
-                            self.assembler.cpu.translate_support_code)
+                            self.cpu.translate_support_code)
         assert itemsize == 1
         return self._malloc_varsize(ofs_items, ofs, itemsize, op)
 
     def prepare_op_newunicode(self, op, fcond):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        gc_ll_descr = self.cpu.gc_ll_descr
         if gc_ll_descr.get_funcptr_for_newunicode is not None:
             raise NotImplementedError
         # boehm GC
         ofs_items, _, ofs = symbolic.get_array_token(rstr.UNICODE,
-                            self.assembler.cpu.translate_support_code)
+                            self.cpu.translate_support_code)
         _, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
-                            self.assembler.cpu.translate_support_code)
+                            self.cpu.translate_support_code)
         return self._malloc_varsize(ofs_items, ofs, itemsize, op)
 
     def _malloc_varsize(self, ofs_items, ofs_length, itemsize, op):
@@ -641,7 +657,7 @@
 
     def prepare_guard_call_may_force(self, op, guard_op, fcond):
         faildescr = guard_op.getdescr()
-        fail_index = self.assembler.cpu.get_fail_descr_number(faildescr)
+        fail_index = self.cpu.get_fail_descr_number(faildescr)
         self.assembler._write_fail_index(fail_index)
         args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
         # force all reg values to be spilled when calling
@@ -651,12 +667,12 @@
 
     def prepare_guard_call_assembler(self, op, guard_op, fcond):
         faildescr = guard_op.getdescr()
-        fail_index = self.assembler.cpu.get_fail_descr_number(faildescr)
+        fail_index = self.cpu.get_fail_descr_number(faildescr)
         self.assembler._write_fail_index(fail_index)
         return []
 
     def _prepare_args_for_new_op(self, new_args):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        gc_ll_descr = self.cpu.gc_ll_descr
         args = gc_ll_descr.args_for_new(new_args)
         arglocs = []
         for i in range(len(args)):
@@ -671,14 +687,14 @@
     def _unpack_fielddescr(self, fielddescr):
         assert isinstance(fielddescr, BaseFieldDescr)
         ofs = fielddescr.offset
-        size = fielddescr.get_field_size(self.assembler.cpu.translate_support_code)
+        size = fielddescr.get_field_size(self.cpu.translate_support_code)
         ptr = fielddescr.is_pointer_field()
         return ofs, size, ptr
 
     #XXX from ../x86/regalloc.py:779
     def _unpack_arraydescr(self, arraydescr):
         assert isinstance(arraydescr, BaseArrayDescr)
-        cpu = self.assembler.cpu
+        cpu = self.cpu
         ofs_length = arraydescr.get_ofs_length(cpu.translate_support_code)
         ofs = arraydescr.get_base_size(cpu.translate_support_code)
         size = arraydescr.get_item_size(cpu.translate_support_code)



More information about the Pypy-commit mailing list