[pypy-svn] r63811 - pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86
fijal at codespeak.net
fijal at codespeak.net
Wed Apr 8 01:18:07 CEST 2009
Author: fijal
Date: Wed Apr 8 01:18:05 2009
New Revision: 63811
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
Log:
A very delicate change - compute frame sizes and restore caching of bootstraps.
Tests are passing, but I would not mind having some extra tests for particular
pieces (3 of them)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py Wed Apr 8 01:18:05 2009
@@ -8,7 +8,7 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.annotation import model as annmodel
from pypy.tool.uid import fixid
-from pypy.jit.backend.x86.regalloc import (RegAlloc, FRAMESIZE, WORD, REGS,
+from pypy.jit.backend.x86.regalloc import (RegAlloc, WORD, REGS,
arg_pos, lower_byte, stack_pos)
from pypy.rlib.objectmodel import we_are_translated, specialize, compute_unique_id
from pypy.jit.backend.x86 import codebuf
@@ -58,6 +58,7 @@
return mc
def give_mc_back(self, mc):
+ mc.done()
assert self.mcstack[self.counter - 1] is mc
self.counter -= 1
@@ -191,10 +192,12 @@
return max_so_far
def assemble(self, tree):
+ self.places_to_patch_framesize = []
# the last operation can be 'jump', 'return' or 'guard_pause';
# a 'jump' can either close a loop, or end a bridge to some
# previously-compiled code.
self._compute_longest_fail_op(tree.operations)
+ self.tree = tree
self.make_sure_mc_exists()
inputargs = tree.inputargs
self.eventually_log_operations(tree.inputargs, tree.operations, None,
@@ -206,6 +209,11 @@
self.sanitize_tree(tree.operations)
self.mc.done()
self.mc2.done()
+ tree._x86_stack_depth = regalloc.max_stack_depth
+ for place, offset in self.places_to_patch_framesize:
+ mc = codebuf.InMemoryCodeBuilder(place, 128)
+ mc.ADD(esp, imm32((tree._x86_stack_depth - offset) * WORD))
+ mc.done()
def sanitize_tree(self, operations):
""" Cleans up all attributes attached by regalloc and backend
@@ -216,11 +224,11 @@
op.longevity = None
self.sanitize_tree(op.suboperations)
- def assemble_bootstrap_code(self, jumpaddr, arglocs):
+ def assemble_bootstrap_code(self, jumpaddr, arglocs, framesize):
self.make_sure_mc_exists()
addr = self.mc.tell()
- self.mc.SUB(esp, imm(FRAMESIZE))
- self.mc.MOV(eax, arg_pos(0))
+ self.mc.SUB(esp, imm(framesize * WORD))
+ self.mc.MOV(eax, arg_pos(0, framesize * WORD))
for i in range(len(arglocs)):
loc = arglocs[i]
if not isinstance(loc, REG):
@@ -588,14 +596,20 @@
#tree.comeback_bootstrap_addr = self.assemble_comeback_bootstrap(pos,
# locs, stacklocs)
- def patch_jump(self, old_pos, new_pos, oldlocs, newlocs):
+ def patch_jump(self, old_pos, new_pos, oldlocs, newlocs, olddepth, newdepth):
if len(oldlocs) != len(newlocs):
# virtualizable mess
return
if not we_are_translated():
assert str(oldlocs) == str(newlocs)
+ mc2 = self.mcstack.next_mc()
+ pos = mc2.tell()
+ mc2.SUB(esp, imm32((newdepth - olddepth) * WORD))
+ mc2.JMP(rel32(new_pos))
+ self.mcstack.give_mc_back(mc2)
mc = codebuf.InMemoryCodeBuilder(old_pos, MachineCodeStack.MC_SIZE)
- mc.JMP(rel32(new_pos))
+ mc.JMP(rel32(pos))
+ mc.done()
# def genop_discard_return(self, op, locs):
# if op.args:
@@ -617,6 +631,10 @@
def genop_discard_jump(self, op, locs):
targetmp = op.jump_target
+ if targetmp is not self.tree:
+ targetdepth = targetmp._x86_stack_depth
+ self.places_to_patch_framesize.append((self.mc.tell(), targetdepth))
+ self.mc.ADD(esp, imm32(0))
self.mc.JMP(rel32(targetmp._x86_compiled))
def genop_guard_guard_true(self, op, ign_1, addr, locs, ign_2):
@@ -734,7 +752,8 @@
# clean up the original exception, we don't want
# to enter more rpython code with exc set
self.mc.MOV(heap(self._exception_addr), imm(0))
- self.mc.ADD(esp, imm(FRAMESIZE))
+ self.places_to_patch_framesize.append((self.mc.tell(), 0))
+ self.mc.ADD(esp, imm32(0))
self.mc.MOV(eax, imm(guard_index))
self.mc.RET()
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py Wed Apr 8 01:18:05 2009
@@ -15,7 +15,6 @@
# saved and restored
REGS = [eax, ecx, edx, ebx]
WORD = 4
-FRAMESIZE = 1024 # XXX should not be a constant at all!!
class TempBox(Box):
def __init__(self):
@@ -46,14 +45,15 @@
class RegAlloc(object):
guard_index = -1
+ max_stack_depth = 0
def __init__(self, assembler, tree, translate_support_code=False,
regalloc=None, guard_op=None):
# variables that have place in register
self.assembler = assembler
self.translate_support_code = translate_support_code
- self.tree = tree
if regalloc is None:
+ self.tree = tree
self.reg_bindings = newcheckdict()
self.stack_bindings = newcheckdict()
# compute longevity of variables
@@ -88,6 +88,7 @@
self.longevity = guard_op.longevity
jump_or_fail = guard_op.suboperations[-1]
self.loop_consts = {}
+ self.tree = regalloc.tree
if jump_or_fail.opnum == rop.FAIL:
self.jump_reg_candidates = {}
else:
@@ -212,6 +213,8 @@
self.assembler.regalloc_perform_with_guard(op, guard_op, regalloc,
arglocs, result_loc,
overflow)
+ self.max_stack_depth = max(self.max_stack_depth,
+ regalloc.max_stack_depth)
def perform_guard(self, op, regalloc, arglocs, result_loc):
if not we_are_translated():
@@ -220,6 +223,8 @@
else:
self.assembler.dump('%s(%s)' % (op, arglocs))
self.assembler.regalloc_perform_guard(op, regalloc, arglocs, result_loc)
+ self.max_stack_depth = max(self.max_stack_depth,
+ regalloc.max_stack_depth)
def PerformDiscard(self, op, arglocs):
if not we_are_translated():
@@ -250,6 +255,8 @@
self.position = -1
self.process_inputargs(tree)
self._walk_operations(operations)
+ self.max_stack_depth = max(self.max_stack_depth,
+ self.current_stack_depth)
def walk_guard_ops(self, inputargs, operations):
for arg in inputargs:
@@ -257,6 +264,8 @@
assert arg in self.stack_bindings
assert arg not in self.dirty_stack
self._walk_operations(operations)
+ self.max_stack_depth = max(self.max_stack_depth,
+ self.current_stack_depth)
def _walk_operations(self, operations):
i = 0
@@ -462,8 +471,6 @@
self.current_stack_depth += 1
res = newloc
assert isinstance(res, MODRM)
- if res.position > FRAMESIZE/WORD:
- raise NotImplementedError("Exceeded FRAME_SIZE")
return res
def make_sure_var_in_reg(self, v, forbidden_vars, selected_reg=None,
@@ -1132,9 +1139,9 @@
num = getattr(rop, name.upper())
oplist[num] = value
-def arg_pos(i):
- res = mem(esp, FRAMESIZE + WORD * (i + 1))
- res.position = (i + 1) + FRAMESIZE // WORD
+def arg_pos(i, framesize):
+ res = mem(esp, framesize + WORD * (i + 1))
+ res.position = (i + 1) + framesize // WORD
return res
def stack_pos(i):
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py Wed Apr 8 01:18:05 2009
@@ -85,7 +85,7 @@
TP = lltype.GcArray(llmemory.GCREF)
self.keepalives = []
self.keepalives_index = 0
- #self._bootstrap_cache = {}
+ self._bootstrap_cache = {}
self._guard_list = []
self._compiled_ops = {}
self._builtin_implementations = {}
@@ -187,28 +187,32 @@
def compile_operations(self, tree):
old_loop = tree._x86_compiled
if old_loop:
+ olddepth = tree._x86_stack_depth
oldlocs = tree.arglocs
else:
oldlocs = None
- self.assembler.assemble(tree)
+ olddepth = 0
+ stack_depth = self.assembler.assemble(tree)
newlocs = tree.arglocs
if old_loop != 0:
self.assembler.patch_jump(old_loop, tree._x86_compiled,
- oldlocs, newlocs)
+ oldlocs, newlocs, olddepth,
+ tree._x86_stack_depth)
def get_bootstrap_code(self, loop):
# key is locations of arguments
- #key = ','.join([str(i) for i in loop.arglocs])
- #try:
- # func = self._bootstrap_cache[key]
- #except KeyError:
- arglocs = loop.arglocs
- addr = self.assembler.assemble_bootstrap_code(loop._x86_compiled,
- arglocs)
- # arguments are as follows - address to jump to,
- # and a list of args
- func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
- return func
+ key = loop._x86_compiled
+ try:
+ return self._bootstrap_cache[key]
+ except KeyError:
+ arglocs = loop.arglocs
+ addr = self.assembler.assemble_bootstrap_code(loop._x86_compiled,
+ arglocs,
+ loop._x86_stack_depth)
+ # passing arglist as the only arg
+ func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
+ self._bootstrap_cache[key] = func
+ return func
def get_box_value_as_int(self, box):
if isinstance(box, BoxInt):
More information about the Pypy-commit
mailing list