Author: Armin Rigo <[email protected]>
Branch: remove-globals-in-jit
Changeset: r58926:6d3427389ceb
Date: 2012-11-15 14:34 +0100
http://bitbucket.org/pypy/pypy/changeset/6d3427389ceb/

Log:    Progress.

diff --git a/pypy/jit/backend/test/runner_test.py 
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -365,7 +365,8 @@
         i0 = BoxInt()
         class UntouchableFailDescr(AbstractFailDescr):
             def __setattr__(self, name, value):
-                if name == 'index':
+                if (name == 'index' or name == '_carry_around_for_tests'
+                        or name == '_TYPE'):
                     return AbstractFailDescr.__setattr__(self, name, value)
                 py.test.fail("finish descrs should not be touched")
         faildescr = UntouchableFailDescr() # to check that is not touched
diff --git a/pypy/jit/backend/x86/assembler.py 
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1,5 +1,5 @@
 import sys, os
-from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.backend.llsupport import symbolic, jitframe
 from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from pypy.jit.metainterp.history import Const, Box, BoxInt, ConstInt
 from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
@@ -39,6 +39,7 @@
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter import longlong
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib import longlong2float
 from pypy.rlib.objectmodel import compute_unique_id
 
 # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 
4.5.0,
@@ -1949,10 +1950,37 @@
             arglocs.append(loc)
         return arglocs[:]
 
-    @rgc.no_collect
-    def grab_frame_values(self, bytecode, frame_addr, allregisters):
-        # no malloc allowed here!!
-        self.fail_ebp = allregisters[16 + ebp.value]
+    #@rgc.no_collect XXX
+    @staticmethod
+    def grab_frame_values(cpu, bytecode, frame_addr, allregisters):
+        # no malloc allowed here!! XXX we allocate anyway the deadframe.
+        # It will only work on Boehm.
+        assert cpu.gc_ll_descr.kind == "boehm", "XXX Boehm only"
+        #self.fail_ebp = allregisters[16 + ebp.value]
+        num = 0
+        # 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 >= Assembler386.CODE_FROMSTACK:
+                while code > 0x7F:
+                    code = rffi.cast(lltype.Signed, bytecode1[0])
+                    bytecode1 = rffi.ptradd(bytecode1, 1)
+            else:
+                kind = code & 3
+                if kind == Assembler386.DESCR_SPECIAL:
+                    if code == Assembler386.CODE_HOLE:
+                        num += 1
+                        continue
+                    if code == Assembler386.CODE_INPUTARG:
+                        continue
+                    assert code == Assembler386.CODE_STOP
+                    break
+            num += 1
+        # allocate the deadframe
+        deadframe = lltype.malloc(jitframe.DEADFRAME, num)
+        # fill it
         code_inputarg = False
         num = 0
         value_hi = 0
@@ -1960,7 +1988,7 @@
             # 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 >= Assembler386.CODE_FROMSTACK:
                 if code > 0x7F:
                     shift = 7
                     code &= 0x7F
@@ -1973,29 +2001,29 @@
                             break
                 # load the value from the stack
                 kind = code & 3
-                code = (code - self.CODE_FROMSTACK) >> 2
+                code = (code - Assembler386.CODE_FROMSTACK) >> 2
                 if code_inputarg:
                     code = ~code
                     code_inputarg = False
                 stackloc = frame_addr + get_ebp_ofs(code)
                 value = rffi.cast(rffi.LONGP, stackloc)[0]
-                if kind == self.DESCR_FLOAT and WORD == 4:
+                if kind == Assembler386.DESCR_FLOAT and WORD == 4:
                     value_hi = value
                     value = rffi.cast(rffi.LONGP, stackloc - 4)[0]
             else:
-                # 'code' identifies a register: load its value
                 kind = code & 3
-                if kind == self.DESCR_SPECIAL:
-                    if code == self.CODE_HOLE:
+                if kind == Assembler386.DESCR_SPECIAL:
+                    if code == Assembler386.CODE_HOLE:
                         num += 1
                         continue
-                    if code == self.CODE_INPUTARG:
+                    if code == Assembler386.CODE_INPUTARG:
                         code_inputarg = True
                         continue
-                    assert code == self.CODE_STOP
+                    assert code == Assembler386.CODE_STOP
                     break
+                # 'code' identifies a register: load its value
                 code >>= 2
-                if kind == self.DESCR_FLOAT:
+                if kind == Assembler386.DESCR_FLOAT:
                     if WORD == 4:
                         value = allregisters[2*code]
                         value_hi = allregisters[2*code + 1]
@@ -2005,29 +2033,37 @@
                     value = allregisters[16 + code]
 
             # store the loaded value into fail_boxes_<type>
-            if kind == self.DESCR_INT:
-                tgt = self.fail_boxes_int.get_addr_for_num(num)
-            elif kind == self.DESCR_REF:
-                tgt = self.fail_boxes_ptr.get_addr_for_num(num)
-            elif kind == self.DESCR_FLOAT:
-                tgt = self.fail_boxes_float.get_addr_for_num(num)
+            if kind == Assembler386.DESCR_INT:
+                deadframe.jf_values[num].int = value
+            elif kind == Assembler386.DESCR_REF:
+                deadframe.jf_values[num].ref = rffi.cast(llmemory.GCREF, value)
+            elif kind == Assembler386.DESCR_FLOAT:
                 if WORD == 4:
-                    rffi.cast(rffi.LONGP, tgt)[1] = value_hi
+                    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))
+                else:
+                    assert longlong.is_64_bit
+                    floatvalue = longlong2float.longlong2float(value)
+                deadframe.jf_values[num].float = floatvalue
             else:
                 assert 0, "bogus kind"
-            rffi.cast(rffi.LONGP, tgt)[0] = value
             num += 1
         #
+        assert num == len(deadframe.jf_values)
         if not we_are_translated():
             assert bytecode[4] == 0xCC
-        self.fail_boxes_count = num
+        #self.fail_boxes_count = num
         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 setup_failure_recovery(self):
 
-        @rgc.no_collect
+        #@rgc.no_collect XXX
         def failure_recovery_func(registers):
             # 'registers' is a pointer to a structure containing the
             # original value of the registers, optionally the original
@@ -2036,13 +2072,14 @@
             stack_at_ebp = registers[ebp.value]
             bytecode = rffi.cast(rffi.UCHARP, registers[self.cpu.NUM_REGS])
             allregisters = rffi.ptradd(registers, -16)
-            return self.grab_frame_values(bytecode, stack_at_ebp, allregisters)
+            return self.grab_frame_values(self.cpu, bytecode, stack_at_ebp,
+                                          allregisters)
 
         self.failure_recovery_func = failure_recovery_func
         self.failure_recovery_code = [0, 0, 0, 0]
 
     _FAILURE_RECOVERY_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP],
-                                                        lltype.Signed))
+                                                        llmemory.GCREF))
 
     def _build_failure_recovery(self, exc, withfloats=False):
         failure_recovery_func = llhelper(self._FAILURE_RECOVERY_FUNC,
@@ -2065,25 +2102,20 @@
             for i in range(self.cpu.NUM_REGS):
                 mc.MOVSD_sx(8*i, i)
 
-        # we call a provided function that will
-        # - call our on_leave_jitted_hook which will mark
-        #   the fail_boxes_ptr array as pointing to young objects to
-        #   avoid unwarranted freeing
-        # - optionally save exception depending on the flag
-        addr = self.cpu.get_on_leave_jitted_int(save_exception=exc)
-        mc.CALL(imm(addr))
+        if exc:
+            mc.UD2()     # XXX
 
         # the following call saves all values from the stack and from
-        # registers to the right 'fail_boxes_<type>' location.
+        # registers to a fresh new deadframe object.
         # Note that the registers are saved so far in esi[0] to esi[7],
         # as pushed above, plus optionally in esi[-16] to esi[-1] for
         # the XMM registers.  Moreover, esi[8] is a pointer to the recovery
         # bytecode, pushed just before by the CALL instruction written by
-        # generate_quick_failure().  XXX misaligned stack in the call, but
-        # it's ok because failure_recovery_func is not calling anything more
+        # generate_quick_failure().
 
         # XXX
         if IS_X86_32:
+            mc.SUB_ri(esp.value, 3*WORD)    # for stack alignment
             mc.PUSH_r(ebx.value)
         elif IS_X86_64:
             mc.MOV_rr(edi.value, ebx.value)
@@ -2091,7 +2123,7 @@
             raise AssertionError("Shouldn't happen")
 
         mc.CALL(imm(failure_recovery_func))
-        # returns in eax the fail_index
+        # returns in eax the deadframe object
 
         # now we return from the complete frame, which starts from
         # _call_header_with_stack_check().  The LEA in _call_footer below
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to