Author: Armin Rigo <[email protected]>
Branch: continulet-jit-3
Changeset: r58298:ff197755dc98
Date: 2012-10-21 09:27 +0200
http://bitbucket.org/pypy/pypy/changeset/ff197755dc98/
Log: Finally found the fix for test_memmgr.
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -1,4 +1,4 @@
-
+import weakref
from pypy.jit.backend import model
from pypy.jit.backend.llgraph import support
from pypy.jit.metainterp.history import Const, getkind, AbstractDescr
@@ -18,8 +18,36 @@
invalid = False
def __init__(self, inputargs, operations):
- self.inputargs = inputargs
- self.operations = operations
+ # We need to clone the list of operations because the
+ # front-end will mutate them under our feet again. We also
+ # need to make sure things get freed.
+ def mapping(box, _cache={}):
+ if isinstance(box, Const) or box is None:
+ return box
+ try:
+ newbox = _cache[box]
+ except KeyError:
+ newbox = _cache[box] = box.clonebox()
+ return newbox
+ #
+ self.inputargs = map(mapping, inputargs)
+ self.operations = []
+ for op in operations:
+ if op.getdescr() is not None:
+ newdescr = WeakrefDescr(op.getdescr())
+ else:
+ newdescr = None
+ newop = op.copy_and_change(op.getopnum(),
+ map(mapping, op.getarglist()),
+ mapping(op.result),
+ newdescr)
+ if op.getfailargs() is not None:
+ newop.setfailargs(map(mapping, op.getfailargs()))
+ self.operations.append(newop)
+
+class WeakrefDescr(AbstractDescr):
+ def __init__(self, realdescr):
+ self.realdescrref = weakref.ref(realdescr)
class GuardFailed(Exception):
def __init__(self, failargs, descr):
@@ -189,14 +217,9 @@
self._record_labels(lltrace)
def _record_labels(self, lltrace):
- # xxx pfff, we need to clone the list of operations because the
- # front-end will mutate them under our feet again
- # xXX pffffffff2 not enough to make sure things are freed
- lltrace.operations = [op.copy_and_change(op.getopnum())
- for op in lltrace.operations]
for i, op in enumerate(lltrace.operations):
if op.getopnum() == rop.LABEL:
- op.getdescr()._llgraph_target = (lltrace, i)
+ _getdescr(op)._llgraph_target = (lltrace, i)
def invalidate_loop(self, looptoken):
for trace in looptoken.compiled_loop_token._llgraph_alltraces:
@@ -277,7 +300,7 @@
else:
guard_op = frame.lltrace.operations[frame.current_index + 1]
frame.latest_values = frame._getfailargs(guard_op, call_op.result)
- descr = guard_op.getdescr()
+ descr = _getdescr(guard_op)
frame.latest_descr = descr
return descr
@@ -637,8 +660,8 @@
self.current_op = op # for label
self.current_index = i
try:
- resval = getattr(self, 'execute_' +
op.getopname())(op.getdescr(),
- *args)
+ resval = getattr(self, 'execute_' + op.getopname())(
+ _getdescr(op), *args)
except Jump, j:
self.lltrace, i = j.descr._llgraph_target
label_op = self.lltrace.operations[i]
@@ -879,6 +902,13 @@
def execute_jit_frame(self, _):
return self
+def _getdescr(op):
+ d = op.getdescr()
+ if d is not None:
+ d = d.realdescrref()
+ assert d is not None, "the descr disappeared: %r" % (op,)
+ return d
+
def _setup():
def _make_impl_from_blackhole_interp(opname):
from pypy.jit.metainterp.blackhole import BlackholeInterpreter
diff --git a/pypy/jit/metainterp/test/test_memmgr.py
b/pypy/jit/metainterp/test/test_memmgr.py
--- a/pypy/jit/metainterp/test/test_memmgr.py
+++ b/pypy/jit/metainterp/test/test_memmgr.py
@@ -117,8 +117,7 @@
# we should see only the loop and the entry bridge
self.check_target_token_count(2)
- def XXXskipped_test_target_loop_kept_alive_or_not(self):
- # SKIPPED: the llgraph backend keeps too much things alive
+ def test_target_loop_kept_alive_or_not(self):
myjitdriver = JitDriver(greens=['m'], reds=['n'])
def g(m):
n = 10
@@ -161,8 +160,7 @@
# we should see a loop for each call to g()
self.check_enter_count(8 + 20*2)
- def XXXskipped_test_throw_away_old_loops(self):
- # SKIPPED: the llgraph backend keeps too much things alive
+ def test_throw_away_old_loops(self):
myjitdriver = JitDriver(greens=['m'], reds=['n'])
def g(m):
n = 10
@@ -214,33 +212,12 @@
g(u, 0); g(u+2, 0) # \ make more loops for g(u+1) to g(u+4),
g(u, 0); g(u+3, 0) # / but keeps g(u) alive
g(u, 0); g(u+4, 0) # /
- g(u, 0); g(u+5, 0) # /
- g(u, 0); g(u+6, 0) # /
- g(u, 0); g(u+7, 0) # /
- g(u, 0); g(u+8, 0) # /
- g(u, 0); g(u+9, 0) # /
- g(u, 0); g(u+10, 0) # /
- g(u, 0); g(u+11, 0) # /
- g(u, 0); g(u+12, 0) # /
g(u, 8) # call g(u) again, with its call_assembler to h(u)
return 42
- res = self.meta_interp(f, [1], loop_longevity=3, inline=True)
+ res = self.meta_interp(f, [1], loop_longevity=4, inline=True)
assert res == 42
- self.check_jitcell_token_count(6+8)
- #
- # manually free the inner loops of the llgraph backend
- tokens = [t() for t in get_stats().jitcell_token_wrefs]
- for token in tokens:
- if token is not None:
- for key in token.compiled_loop_token.__dict__.keys():
- if key.startswith('_llgraph_'):
- setattr(token.compiled_loop_token, key, 'STUBBED')
- del tokens, token
- import gc; gc.collect(); gc.collect(); gc.collect(); gc.collect()
- # from pypy.translator.tool.reftracker import track
- # track(get_stats().jitcell_token_wrefs[8]())
- #
+ self.check_jitcell_token_count(6)
tokens = [t() for t in get_stats().jitcell_token_wrefs]
# Some loops have been freed
assert None in tokens
@@ -277,3 +254,4 @@
finally:
if hasattr(test, 'teardown_class'):
test.teardown_class()
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit