[pypy-svn] r35759 - in pypy/dist/pypy/jit/codegen/i386: . test
ac at codespeak.net
ac at codespeak.net
Thu Dec 14 19:50:19 CET 2006
Author: ac
Date: Thu Dec 14 19:50:18 2006
New Revision: 35759
Modified:
pypy/dist/pypy/jit/codegen/i386/codebuf.py
pypy/dist/pypy/jit/codegen/i386/rgenop.py
pypy/dist/pypy/jit/codegen/i386/test/test_genc_portal.py
pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
Log:
(pedronis, arre) Delay creating the codeblock for a builder in order to reduce
the number of open codeblocks. This didn't reduce the number very much (on
richards from 114 to 112). More work is needed: it seems that the source
of open mcs are "open" builders put on queues by collect_split.
Modified: pypy/dist/pypy/jit/codegen/i386/codebuf.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/codebuf.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/codebuf.py Thu Dec 14 19:50:18 2006
@@ -135,7 +135,6 @@
def __init__(self, map_size):
self._size = map_size
self._pos = 0
- self._data = lltype.malloc(BUF, map_size)
self._base = LLTypeMachineCodeBlock.state.base
LLTypeMachineCodeBlock.state.base += 2 * map_size
@@ -143,13 +142,20 @@
p = self._pos
if p + len(data) > self._size:
raise CodeBlockOverflow
- for c in data:
- self._data[p] = c
- p += 1
- self._pos = p
+ self._pos += len(data)
+ return
def tell(self):
return self._base + 2 * self._pos
def done(self):
pass
+
+class LLTypeInMemoryCodeBuilder(LLTypeMachineCodeBlock):
+ _last_dump_start = 0
+
+ def __init__(self, start, end):
+ self._size = (end - start) / 2
+ self._pos = 0
+ self._base = start
+
Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py Thu Dec 14 19:50:18 2006
@@ -1,8 +1,8 @@
-import sys, py
+import sys, py, os
from pypy.rlib.objectmodel import specialize
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.i386.ri386 import *
-from pypy.jit.codegen.i386.codebuf import InMemoryCodeBuilder, CodeBlockOverflow
+from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.rlib import objectmodel
@@ -149,7 +149,9 @@
def __init__(self, rgenop):
self.rgenop = rgenop
- self.default_case_addr = 0
+ self.default_case_builder = None
+ self.default_case_key = 0
+ self._je_key = 0
def initialize(self, builder, gv_exitswitch):
mc = builder.mc
@@ -171,62 +173,101 @@
newmc = self.rgenop.open_mc()
self._reserve(newmc)
self.rgenop.close_mc(newmc)
- fullmc = InMemoryCodeBuilder(start, end)
+ fullmc = self.rgenop.InMemoryCodeBuilder(start, end)
fullmc.JMP(rel32(self.nextfreepos))
fullmc.done()
def add_case(self, gv_case):
rgenop = self.rgenop
targetbuilder = Builder._new_from_state(rgenop, self.saved_state)
- target_addr = targetbuilder.mc.tell()
try:
- self._add_case(gv_case, target_addr)
+ self._add_case(gv_case, targetbuilder)
except CodeBlockOverflow:
self._reserve_more()
- self._add_case(gv_case, target_addr)
+ self._add_case(gv_case, targetbuilder)
return targetbuilder
- def _add_case(self, gv_case, target_addr):
+ def _add_case(self, gv_case, targetbuilder):
start = self.nextfreepos
end = self.endfreepos
- mc = InMemoryCodeBuilder(start, end)
+ mc = self.rgenop.InMemoryCodeBuilder(start, end)
mc.CMP(eax, gv_case.operand(None))
- mc.JE(rel32(target_addr))
+ self._je_key = targetbuilder.come_from(mc, 'JE', self._je_key)
pos = mc.tell()
- if self.default_case_addr:
- mc.JMP(rel32(self.default_case_addr))
+ if self.default_case_builder:
+ self.default_case_key = self.default_case_builder.come_from(
+ mc, 'JMP', self.default_case_key)
else:
illegal_start = mc.tell()
mc.JMP(rel32(0))
ud2_addr = mc.tell()
mc.UD2()
- illegal_mc = InMemoryCodeBuilder(illegal_start, end)
+ illegal_mc = self.rgenop.InMemoryCodeBuilder(illegal_start, end)
illegal_mc.JMP(rel32(ud2_addr))
mc.done()
+ self._je_key = 0
self.nextfreepos = pos
def add_default(self):
rgenop = self.rgenop
targetbuilder = Builder._new_from_state(rgenop, self.saved_state)
- self.default_case_addr = targetbuilder.mc.tell()
+ self.default_case_builder = targetbuilder
start = self.nextfreepos
end = self.endfreepos
- mc = InMemoryCodeBuilder(start, end)
- mc.JMP(rel32(self.default_case_addr))
- mc.done()
+ mc = self.rgenop.InMemoryCodeBuilder(start, end)
+ self.default_case_key = targetbuilder.come_from(mc, 'JMP')
return targetbuilder
class Builder(GenBuilder):
- def __init__(self, rgenop, mc, stackdepth):
+ def __init__(self, rgenop, mc_factory, stackdepth):
self.rgenop = rgenop
self.stackdepth = stackdepth
- self.mc = mc
-
+ self.mc = None
+ self._mc_factory = mc_factory
+ self._pending_come_from = {}
+ self.start = 0
+ rgenop.openbuilders += 1
+ #os.write(1, 'Open builders+: %d\n' % rgenop.openbuilders)
+
+ def _open(self):
+ if self.mc is None and self._pending_come_from is not None:
+ self.mc = self._mc_factory()
+ self.start = self.mc.tell()
+ come_froms = self._pending_come_from
+ self._pending_come_from = None
+ for start, (end, insn) in come_froms.iteritems():
+ mc = self.rgenop.InMemoryCodeBuilder(start, end)
+ self._emit_come_from(mc, insn, self.start)
+ mc.done()
+
+ def _emit_come_from(self, mc, insn, addr):
+ if insn == 'JMP':
+ mc.JMP(rel32(addr))
+ elif insn == 'JE':
+ mc.JE(rel32(addr))
+ elif insn == 'JNE':
+ mc.JNE(rel32(addr))
+ else:
+ raise ValueError('Unsupported jump')
+
+ def come_from(self, mc, insn, key=0):
+ start = mc.tell()
+ if self._pending_come_from is None:
+ self._emit_come_from(mc, insn, self.start)
+ else:
+ self._emit_come_from(mc, insn, 0)
+ end = mc.tell()
+ if key != 0:
+ del self._pending_come_from[key]
+ self._pending_come_from[start] = (end, insn)
+ return start
+
def end(self):
pass
def _write_prologue(self, sigtoken):
+ self._open()
numargs = sigtoken # for now
#self.mc.BREAKPOINT()
return [Var(pos) for pos in range(numargs-1, -1, -1)]
@@ -235,6 +276,8 @@
self.mc.done()
self.rgenop.close_mc(self.mc)
self.mc = None
+ self.rgenop.openbuilders -= 1
+ #os.write(1, 'Open builders-: %d\n' % self.rgenop.openbuilders)
def _fork(self):
return self.rgenop.openbuilder(self.stackdepth)
@@ -389,6 +432,7 @@
self.mc.BREAKPOINT()
def enter_next_block(self, kinds, args_gv):
+ self._open()
arg_positions = []
seen = {}
for i in range(len(args_gv)):
@@ -405,13 +449,13 @@
def jump_if_false(self, gv_condition):
targetbuilder = self._fork()
self.mc.CMP(gv_condition.operand(self), imm8(0))
- self.mc.JE(rel32(targetbuilder.mc.tell()))
+ targetbuilder.come_from(self.mc, 'JE')
return targetbuilder
def jump_if_true(self, gv_condition):
targetbuilder = self._fork()
self.mc.CMP(gv_condition.operand(self), imm8(0))
- self.mc.JNE(rel32(targetbuilder.mc.tell()))
+ targetbuilder.come_from(self.mc, 'JNE')
return targetbuilder
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -885,12 +929,13 @@
def show_incremental_progress(self):
pass
-
class RI386GenOp(AbstractRGenOp):
from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
+ from pypy.jit.codegen.i386.codebuf import InMemoryCodeBuilder
MC_SIZE = 65536
-
+ openbuilders = 0
+
def __init__(self):
self.mcs = [] # machine code blocks where no-one is currently writing
self.keepalive_gc_refs = []
@@ -903,6 +948,7 @@
else:
# XXX supposed infinite for now
self.total_code_blocks += 1
+ #os.write(1, 'Open codeblocks: %d\n' % (self.total_code_blocks,))
return self.MachineCodeBlock(self.MC_SIZE)
def close_mc(self, mc):
@@ -915,12 +961,13 @@
assert len(self.mcs) == self.total_code_blocks
def openbuilder(self, stackdepth):
- return Builder(self, self.open_mc(), stackdepth)
+ return Builder(self, self.open_mc, stackdepth)
def newgraph(self, sigtoken, name):
numargs = sigtoken # for now
initialstackdepth = numargs+1
builder = self.openbuilder(initialstackdepth)
+ builder._open() # Force builder to have an mc
entrypoint = builder.mc.tell()
inputargs_gv = builder._write_prologue(sigtoken)
return builder, IntConst(entrypoint), inputargs_gv
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_genc_portal.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_genc_portal.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_genc_portal.py Thu Dec 14 19:50:18 2006
@@ -59,6 +59,9 @@
backendoptimize=backendoptimize)
cmdargs = ' '.join([str(arg) for arg in main_args])
output = self.cbuilder.cmdexec(cmdargs)
+ print '-'*60
+ print output
+ print '-'*60
lines = output.split()
lastline = lines[-1]
assert not lastline.startswith('EXCEPTION:')
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py Thu Dec 14 19:50:18 2006
@@ -13,6 +13,8 @@
class RGenOp(RGenOpPacked):
from pypy.jit.codegen.i386.codebuf import LLTypeMachineCodeBlock \
as MachineCodeBlock
+ from pypy.jit.codegen.i386.codebuf import LLTypeInMemoryCodeBuilder \
+ as InMemoryCodeBuilder
def timeshift(self, ll_function, values, opt_consts=[], *args, **kwds):
values = self.timeshift_cached(ll_function, values, *args, **kwds)
More information about the Pypy-commit
mailing list