Author: David Schneider <[email protected]>
Branch: remove-globals-in-jit
Changeset: r59672:4494a20539bb
Date: 2012-12-21 15:05 +0100
http://bitbucket.org/pypy/pypy/changeset/4494a20539bb/

Log:    (wip) continue porting deadframe creation

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
@@ -1,5 +1,6 @@
 from __future__ import with_statement
 import os
+from pypy.jit.backend.llsupport import jitframe
 from pypy.jit.backend.arm.helper.assembler import saved_registers
 from pypy.jit.backend.arm import conditions as c
 from pypy.jit.backend.arm import registers as r
@@ -326,7 +327,7 @@
 
     def setup_failure_recovery(self):
 
-        @rgc.no_collect
+        #@rgc.no_collect -- XXX still true, but hacked gc_set_extra_threshold
         def failure_recovery_func(mem_loc, frame_pointer, stack_pointer):
             """mem_loc is a structure in memory describing where the values for
             the failargs are stored.  frame loc is the address of the frame
@@ -345,21 +346,62 @@
     @staticmethod
     def decode_registers_and_descr(cpu, mem_loc, frame_pointer,
                                                 registers, vfp_registers):
-       # XXX rewrite
-        """Decode locations encoded in memory at mem_loc and write the values
-        to the failboxes.  Values for spilled vars and registers are stored on
-        stack at frame_loc """
-        assert frame_pointer & 1 == 0
-        self.fail_force_index = frame_pointer
+        # no malloc allowed here!!  xxx apart from one, hacking a lot
+        #self.fail_ebp = allregisters[16 + ebp.value]
+        num = 0
+        deadframe = lltype.nullptr(jitframe.DEADFRAME)
         bytecode = rffi.cast(rffi.UCHARP, mem_loc)
+        # step 1: lots of mess just to count the final value of 'num'
+        bytecode1 = bytecode
+        while 1:
+            code = rffi.cast(lltype.Signed, bytecode1[0])
+            bytecode1 = rffi.ptradd(bytecode1, 1)
+            if code >= AssemblerARM.CODE_FROMSTACK:
+                while code > 0x7F:
+                    code = rffi.cast(lltype.Signed, bytecode1[0])
+                    bytecode1 = rffi.ptradd(bytecode1, 1)
+            else:
+                kind = code & 3
+                if kind == AssemblerARM.DESCR_SPECIAL:
+                    if code == AssemblerARM.CODE_HOLE:
+                        num += 1
+                        continue
+                    if code == AssemblerARM.CODE_INPUTARG:
+                        continue
+                    if code == AssemblerARM.CODE_FORCED:
+                        # resuming from a GUARD_NOT_FORCED
+                        xxx
+                        token = allregisters[16 + ebp.value]
+                        deadframe = (
+                            cpu.assembler.force_token_to_dead_frame.pop(token))
+                        deadframe = lltype.cast_opaque_ptr(
+                            jitframe.DEADFRAMEPTR, deadframe)
+                        continue
+                    assert code == AssemblerARM.CODE_STOP
+                    break
+            num += 1
+
+        # allocate the deadframe
+        if not deadframe:
+            # Remove the "reserve" at the end of the nursery.  This means
+            # that it is guaranteed that the following malloc() works
+            # without requiring a collect(), but it needs to be re-added
+            # as soon as possible.
+            cpu.gc_clear_extra_threshold()
+            assert num <= cpu.get_failargs_limit()
+            try:
+                deadframe = lltype.malloc(jitframe.DEADFRAME, num)
+            except MemoryError:
+                fatalerror("memory usage error in grab_frame_values")
+        # fill it
+        code_inputarg = False
         num = 0
-        value = 0
-        fvalue = 0
-        code_inputarg = False
-        while True:
+        value_hi = 0
+        while 1:
+            # decode the next instruction from the bytecode
             code = rffi.cast(lltype.Signed, bytecode[0])
             bytecode = rffi.ptradd(bytecode, 1)
-            if code >= self.CODE_FROMSTACK:
+            if code >= AssemblerARM.CODE_FROMSTACK:
                 if code > 0x7F:
                     shift = 7
                     code &= 0x7F
@@ -372,54 +414,63 @@
                             break
                 # load the value from the stack
                 kind = code & 3
-                code = int((code - self.CODE_FROMSTACK) >> 2)
+                code = (code - AssemblerARM.CODE_FROMSTACK) >> 2
                 if code_inputarg:
                     code = ~code
                     code_inputarg = False
-                if kind == self.DESCR_FLOAT:
-                    # we use code + 1 to get the hi word of the double worded 
float
-                    stackloc = frame_pointer - get_fp_offset(int(code) + 1)
-                    assert stackloc & 3 == 0
-                    fvalue = rffi.cast(rffi.LONGLONGP, stackloc)[0]
-                else:
-                    stackloc = frame_pointer - get_fp_offset(int(code))
-                    assert stackloc & 1 == 0
-                    value = rffi.cast(rffi.LONGP, stackloc)[0]
+                stackloc = frame_addr + get_fp_offset(int(code))
+                value = rffi.cast(rffi.LONGP, stackloc)[0]
+                if kind == AssemblerARM.DESCR_FLOAT:
+                    assert WORD == 4
+                    value_hi = value
+                    value = rffi.cast(rffi.LONGP, stackloc - WORD)[0]
             else:
-                # 'code' identifies a register: load its value
                 kind = code & 3
-                if kind == self.DESCR_SPECIAL:
-                    if code == self.CODE_HOLE:
+                if kind == AssemblerARM.DESCR_SPECIAL:
+                    if code == AssemblerARM.CODE_HOLE:
                         num += 1
                         continue
-                    if code == self.CODE_INPUTARG:
+                    if code == AssemblerARM.CODE_INPUTARG:
                         code_inputarg = True
                         continue
-                    assert code == self.CODE_STOP
+                    if code == AssemblerARM.CODE_FORCED:
+                        continue
+                    assert code == AssemblerARM.CODE_STOP
                     break
+                # 'code' identifies a register: load its value
                 code >>= 2
-                if kind == self.DESCR_FLOAT:
-                    fvalue = vfp_registers[code]
+                if kind == AssemblerARM.DESCR_FLOAT:
+                    if WORD == 4:
+                        value = vfp_registers[2*code]
+                        value_hi = vfp_registers[2*code + 1]
+                    else:
+                        value = allregisters[code]
                 else:
                     value = registers[code]
             # store the loaded value into fail_boxes_<type>
-            if kind == self.DESCR_FLOAT:
-                tgt = self.fail_boxes_float.get_addr_for_num(num)
-                rffi.cast(rffi.LONGLONGP, tgt)[0] = fvalue
+            if kind == AssemblerARM.DESCR_INT:
+                deadframe.jf_values[num].int = value
+            elif kind == AssemblerARM.DESCR_REF:
+                deadframe.jf_values[num].ref = rffi.cast(llmemory.GCREF, value)
+            elif kind == AssemblerARM.DESCR_FLOAT:
+                assert WORD == 4
+                assert not longlong.is_64_bit
+                floatvalue = rffi.cast(lltype.SignedLongLong, value_hi)
+                floatvalue <<= 32
+                floatvalue |= rffi.cast(lltype.SignedLongLong,
+                                        rffi.cast(lltype.Unsigned, value))
+                deadframe.jf_values[num].float = floatvalue
             else:
-                if kind == self.DESCR_INT:
-                    tgt = self.fail_boxes_int.get_addr_for_num(num)
-                elif kind == self.DESCR_REF:
-                    assert (value & 3) == 0, "misaligned pointer"
-                    tgt = self.fail_boxes_ptr.get_addr_for_num(num)
-                else:
-                    assert 0, "bogus kind"
-                rffi.cast(rffi.LONGP, tgt)[0] = value
+                assert 0, "bogus kind"
             num += 1
-        self.fail_boxes_count = num
+        #
+        assert num == len(deadframe.jf_values)
+        if not we_are_translated():
+            assert bytecode[4] == 0xCC
         fail_index = rffi.cast(rffi.INTP, bytecode)[0]
-        fail_index = rffi.cast(lltype.Signed, fail_index)
-        return fail_index
+        fail_descr = cpu.get_fail_descr_from_number(fail_index)
+        deadframe.jf_descr = fail_descr.hide(cpu)
+        return lltype.cast_opaque_ptr(llmemory.GCREF, deadframe)
 
     def decode_inputargs(self, code):
         descr_to_box_type = [REF, INT, FLOAT]
@@ -508,6 +559,16 @@
                                             self.failure_recovery_func)
         self._insert_checks(mc)
         with saved_registers(mc, r.all_regs, r.all_vfp_regs):
+            if exc:
+                # We might have an exception pending.  Load it into r4
+                # (this is a register saved across calls)
+                mc.gen_load_int(r.r5.value, self.cpu.pos_exc_value())
+                mc.LDR_ri(r.r4.value, self.cpu.pos_exc_value())
+                # clear the exc flags
+                mc.gen_load_int(r.r6.value, 0)
+                mc.STR_ri(r.r6.value, r.r5.value)
+                mc.gen_load_int(r.r5.value, self.cpu.pos_exception())
+                mc.STR_ri(r.r6.value, r.r5.value)
             # move mem block address, to r0 to pass as
             mc.MOV_rr(r.r0.value, r.lr.value)
             # pass the current frame pointer as second param
@@ -516,6 +577,12 @@
             mc.MOV_rr(r.r2.value, r.sp.value)
             self._insert_checks(mc)
             mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
+            if exc:
+                # save ebx into 'jf_guard_exc'
+                from pypy.jit.backend.llsupport.descr import unpack_fielddescr
+                descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
+                offset, size, _ = unpack_fielddescr(descrs.jf_guard_exc)
+                mc.STR_rr(r.r4.value, r.r0.value, offset, cond=c.AL)
             mc.MOV_rr(r.ip.value, r.r0.value)
         mc.MOV_rr(r.r0.value, r.ip.value)
         self.gen_func_epilog(mc=mc)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to