[pypy-svn] r35810 - in pypy/dist/pypy/jit: codegen codegen/i386 codegen/i386/test timeshifter
ac at codespeak.net
ac at codespeak.net
Fri Dec 15 17:00:50 CET 2006
Author: ac
Date: Fri Dec 15 17:00:49 2006
New Revision: 35810
Modified:
pypy/dist/pypy/jit/codegen/i386/rgenop.py
pypy/dist/pypy/jit/codegen/i386/test/test_genc_portal.py
pypy/dist/pypy/jit/codegen/model.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
Log:
Pause builders when they are put on return/split/global_merge chains so they
can release temporary resources (The i386 one will release it's
MachineCodeBlock). This way we won't use up the addresspace so easily.
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 Fri Dec 15 17:00:49 2006
@@ -220,27 +220,51 @@
class Builder(GenBuilder):
- def __init__(self, rgenop, mc_factory, stackdepth):
+ def __init__(self, rgenop, stackdepth):
self.rgenop = rgenop
self.stackdepth = stackdepth
self.mc = None
- self._mc_factory = mc_factory
self._pending_come_from = {}
self.start = 0
+ self.closed = False
+ self.tail = (0, 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)
+ if self.mc is None and not self.closed:
+ self.mc = self.rgenop.open_mc()
+ if not self.start:
+ # This is the first open. remember the start address
+ # and patch all come froms.
+ 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()
+ else:
+ # We have been paused and are being opened again.
+ # Patch the jump at the end of the previous codeblock.
+ mc = self.rgenop.InMemoryCodeBuilder(*self.tail)
+ mc.JMP(rel32(self.mc.tell()))
mc.done()
+ def pause(self):
+ if self.mc is None:
+ return
+ start = self.mc.tell()
+ self.mc.JMP(rel32(0))
+ end = self.mc.tell()
+ self.tail = (start, end)
+ self.mc.done()
+ self.rgenop.close_mc(self.mc)
+ self.mc = None
+
+ def resume(self):
+ self._open()
+
def _emit_come_from(self, mc, insn, addr):
if insn == 'JMP':
mc.JMP(rel32(addr))
@@ -273,6 +297,7 @@
return [Var(pos) for pos in range(numargs-1, -1, -1)]
def _close(self):
+ self.closed = True
self.mc.done()
self.rgenop.close_mc(self.mc)
self.mc = None
@@ -459,6 +484,7 @@
return targetbuilder
def finish_and_return(self, sigtoken, gv_returnvar):
+ self._open()
numargs = sigtoken # for now
initialstackdepth = numargs + 1
self.mc.MOV(eax, gv_returnvar.operand(self))
@@ -467,6 +493,7 @@
self._close()
def finish_and_goto(self, outputargs_gv, target):
+ self._open()
remap_stack_layout(self, outputargs_gv, target)
self.mc.JMP(rel32(target.startaddr))
self._close()
@@ -961,7 +988,7 @@
assert len(self.mcs) == self.total_code_blocks
def openbuilder(self, stackdepth):
- return Builder(self, self.open_mc, stackdepth)
+ return Builder(self, stackdepth)
def newgraph(self, sigtoken, name):
numargs = sigtoken # for now
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 Fri Dec 15 17:00:49 2006
@@ -59,9 +59,6 @@
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/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py (original)
+++ pypy/dist/pypy/jit/codegen/model.py Fri Dec 15 17:00:49 2006
@@ -142,7 +142,15 @@
'''Optional method: prints or logs the position of the generated code
along with the given msg.
'''
-
+ def pause(self):
+ '''Optional method: Called when the builder will not be used for a
+ while. This allows the builder to free temporary resources needed
+ during code generation. The next call to the builder will have to be
+ to enter_next_block, finish_and_got, finish_and_return or resume.
+ '''
+ def resume(self):
+ 'Resumes a paused builder.'
+
class GenLabel(object):
'''A "smart" label. Represents an address of the start of a basic
block and the location of the inputargs on entry to that block.'''
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Fri Dec 15 17:00:49 2006
@@ -308,6 +308,7 @@
resuming.mergesleft -= 1
def guard_global_merge(jitstate, resumepoint):
+ jitstate.curbuilder.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate
@@ -392,6 +393,7 @@
elif dispatchqueue.global_merge_chain is not None:
jitstate = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate.next
+ jitstate.curbuilder.resume()
return jitstate
else:
oldjitstate.resumepoint = -1
@@ -439,6 +441,7 @@
def save_return(jitstate):
# add 'jitstate' to the chain of return-jitstates
+ jitstate.curbuilder.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.return_chain
dispatchqueue.return_chain = jitstate
@@ -913,10 +916,13 @@
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
+ jitstate.curbuilder.resume()
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
+ if still_pending:
+ still_pending.curbuilder.pause()
jitstate.next = still_pending
still_pending = jitstate
@@ -929,10 +935,13 @@
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
+ jitstate.curbuilder.resume()
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
+ if still_pending:
+ still_pending.curbuilder.pause()
jitstate.next = still_pending
still_pending = jitstate
return still_pending
@@ -992,4 +1001,3 @@
leave_frame(jitstate)
jitstate = jitstate.next
return return_chain # a jitstate, which is the head of the chain
-
More information about the pypy-svn
mailing list