[pypy-commit] pypy jitframe-on-heap: revive continulet-jit-3 branch in new reality. For starters, a JIT frame

fijal noreply at buildbot.pypy.org
Tue Jan 8 17:22:04 CET 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: jitframe-on-heap
Changeset: r59874:46a6aeacf807
Date: 2013-01-08 18:20 +0200
http://bitbucket.org/pypy/pypy/changeset/46a6aeacf807/

Log:	revive continulet-jit-3 branch in new reality. For starters, a JIT
	frame description

diff --git a/pypy/jit/backend/llsupport/jitframe.py b/pypy/jit/backend/llsupport/jitframe.py
--- a/pypy/jit/backend/llsupport/jitframe.py
+++ b/pypy/jit/backend/llsupport/jitframe.py
@@ -1,33 +1,29 @@
-from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.jit.codewriter import longlong
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 
+GCINDEXLIST = lltype.GcArray(rffi.UINT)
 
-# XXX not an actual union for now
-VALUEUNION = lltype.Struct('VALUEUNION',
-                           ('int', lltype.Signed),
-                           ('ref', llmemory.GCREF),
-                           ('float', longlong.FLOATSTORAGE))
+# the JITFRAME that's stored on the heap. See backend/<backend>/arch.py for
+# detailed explanation how it is on your architecture
 
-DEADFRAME = lltype.GcStruct(
-    'DEADFRAME',
-
+JITFRAME = lltype.GcStruct(
+    'JITFRAME',
+    # gcindexlist is a list of indexes of GC ptrs
+    # in the actual array
+    ('jf_gcindexlist', lltype.Ptr(GCINDEXLIST)),
     # Once the execute_token() returns, the field 'jf_descr' stores the
     # descr of the last executed operation (either a GUARD, or FINISH).
     # This field is also set immediately before doing CALL_MAY_FORCE
     # or CALL_ASSEMBLER.
     ('jf_descr', llmemory.GCREF),
-
     # For the front-end: a GCREF for the savedata
     ('jf_savedata', llmemory.GCREF),
-
     # For GUARD_(NO)_EXCEPTION and GUARD_NOT_FORCED: the exception we
     # got.  (Note that in case of a regular FINISH generated from
     # RPython code that finishes the function with an exception, the
     # exception is not stored there, but in jf_values[0].ref.)
     ('jf_guard_exc', llmemory.GCREF),
+    # the actual frame
+    ('jf_frame', lltype.Array(lltype.Signed))
+)
 
-    # All values are stored in the following array, for now not
-    # compactly at all
-    ('jf_values', lltype.Array(VALUEUNION)))
-
-DEADFRAMEPTR = lltype.Ptr(DEADFRAME)
+JITFRAMEPTR = lltype.Ptr(JITFRAME)
diff --git a/pypy/jit/backend/x86/arch.py b/pypy/jit/backend/x86/arch.py
--- a/pypy/jit/backend/x86/arch.py
+++ b/pypy/jit/backend/x86/arch.py
@@ -8,22 +8,52 @@
 import sys
 if sys.maxint == (2**31 - 1):
     WORD = 4
-    # ebp + ebx + esi + edi + 4 extra words + force_index = 9 words
-    FRAME_FIXED_SIZE = 9
-    FORCE_INDEX_OFS = -8*WORD
-    MY_COPY_OF_REGS = -7*WORD
     IS_X86_32 = True
     IS_X86_64 = False
 else:
     WORD = 8
-    # rbp + rbx + r12 + r13 + r14 + r15 + 11 extra words + force_index = 18
-    FRAME_FIXED_SIZE = 18
-    FORCE_INDEX_OFS = -17*WORD
-    MY_COPY_OF_REGS = -16*WORD
     IS_X86_32 = False
     IS_X86_64 = True
 
-# The extra space has room for almost all registers, apart from eax and edx
+# The stack for a JIT call is fixed, but it contains only scratch space
+# used e.g. for storing arguments to further calls:
+#
+#        +--------------------+    <== aligned to 16 bytes
+#        |   return address   |
+#        +--------------------+
+#        |   scratch          |
+#        |      space         |
+#        +--------------------+    <== aligned to 16 bytes
+
+if WORD == 4:
+    SCRATCH_SIZE = 7     # total size: 32 bytes
+else:
+    SCRATCH_SIZE = 3     # total size: 32 bytes
+
+# All the rest of the data is in a GC-managed variable-size "frame".
+# This frame object's address is always stored in the register EBP/RBP.
+# A frame is a jit.backend.llsupport.llmodel.JITFRAME = GcArray(Signed).
+# The following locations are indices in this array.
+
+# The frame's fixed size gives the standard fixed part at the
+# start of every frame: the saved value of some registers,
+# one word for the force_index, and some extra space used only
+# during a malloc that needs to go via its slow path.
+
+if WORD == 4:
+    # ebp + ebx + esi + edi + 4 extra words + force_index = 9 words
+    FRAME_FIXED_SIZE = 9
+    FORCE_INDEX_OFS = 0
+    SAVED_REGISTERS = 1    # range(1, 5)
+    MY_COPY_OF_REGS = 5    # range(5, 9)
+else:
+    # rbp + rbx + r12 + r13 + r14 + r15 + 11 extra words + force_index = 18
+    FRAME_FIXED_SIZE = 18
+    FORCE_INDEX_OFS = 0
+    SAVED_REGISTERS = 1    # range(1, 7)
+    MY_COPY_OF_REGS = 7    # range(7, 18)
+
+# "My copy of regs" has room for almost all registers, apart from eax and edx
 # which are used in the malloc itself.  They are:
 #   ecx, ebx, esi, edi               [32 and 64 bits]
 #   r8, r9, r10, r12, r13, r14, r15    [64 bits only]


More information about the pypy-commit mailing list