[pypy-svn] r64721 - in pypy/branch/pyjitpl5-simplify/pypy/jit: backend backend/llgraph backend/minimal backend/test backend/x86 backend/x86/test metainterp metainterp/test tl
antocuni at codespeak.net
antocuni at codespeak.net
Mon Apr 27 12:00:09 CEST 2009
Author: antocuni
Date: Mon Apr 27 12:00:08 2009
New Revision: 64721
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/model.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_regalloc.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_child.py
pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_demo.py
Log:
merge more of the pyjitpl5 branch back to pyjitpl5-simplify (the first part of
the branch was merged in r64647)
svn merge svn+ssh://codespeak.net/svn/pypy/branch/pyjitpl5/ -r64647:HEAD
------------------------------------------------------------------------
r64649 | fijal | 2009-04-24 18:56:39 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
improve debugging
------------------------------------------------------------------------
r64651 | fijal | 2009-04-24 20:34:55 +0200 (Fri, 24 Apr 2009) | 4 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
disable this optimization. I have a vague feeling that those loops appear
in random places in old_loops of optimize_bridge and in simple optimize we don't
check it at all
------------------------------------------------------------------------
r64652 | fijal | 2009-04-24 20:37:31 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
that was dumb, I need to think
------------------------------------------------------------------------
r64653 | fijal | 2009-04-24 20:46:52 +0200 (Fri, 24 Apr 2009) | 4 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
don't store pseudo-loops in possible compiled merge points. I must admit I have
a bit no clue what I'm doing, except I'm pretty sure optimize_bridge should
not randomly return pseudo loop. Also don't know how to write a test.
------------------------------------------------------------------------
r64654 | fijal | 2009-04-24 20:52:07 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
don't add them here as well
------------------------------------------------------------------------
r64655 | fijal | 2009-04-24 21:17:32 +0200 (Fri, 24 Apr 2009) | 7 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
according to my limited knowledge this should yield true. We should not have
more than one loop going from a single greenkey. It's obviously not true,
because we store there both starts from the interpreter and some other
stuff. Returning old_loops[0] makes no sense, so what should we return?
I have no clue so far.
------------------------------------------------------------------------
r64656 | fijal | 2009-04-24 21:18:45 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
make simple optimize the default
------------------------------------------------------------------------
r64657 | fijal | 2009-04-24 21:25:18 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
I think this should also yield true
------------------------------------------------------------------------
r64658 | fijal | 2009-04-24 21:25:47 +0200 (Fri, 24 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
attempt at making assertions pass, some tests fail thanks to different
counts, let's see..
------------------------------------------------------------------------
r64659 | fijal | 2009-04-24 21:38:53 +0200 (Fri, 24 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
oops
------------------------------------------------------------------------
r64660 | benjamin | 2009-04-25 00:23:14 +0200 (Sat, 25 Apr 2009) | 1 line
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
revert r64651 through r64659 because fijal says he didn't know what he was doing :P
------------------------------------------------------------------------
r64661 | fijal | 2009-04-25 02:28:22 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/interpreter/pyopcode.py
M /pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py
Seems our jit is not too happy with pypy's python interpreter. Make it
look like tests a bit more
------------------------------------------------------------------------
r64662 | benjamin | 2009-04-25 02:55:49 +0200 (Sat, 25 Apr 2009) | 6 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
implement serialization of prebuilt AbstractValues for space in the binary
At the moment, only simple ConstInt can be serialized
I refactored out jitcode decoding from MIFrame
------------------------------------------------------------------------
r64663 | benjamin | 2009-04-25 03:18:34 +0200 (Sat, 25 Apr 2009) | 1 line
Changed paths:
A /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_history.py
add a test for serializing ConstInt
------------------------------------------------------------------------
r64668 | arigo | 2009-04-25 12:12:57 +0200 (Sat, 25 Apr 2009) | 8 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
D /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_history.py
Revert r64662 and r64663 by benjamin. It seems completely useless to
me (saving prebuilt ConstInts that are anyway globally shared so they
cannot be so numerous), but I may be missing the point.
Additionally, as Samuele puts it, the current goal should be to maximize
debuggability. That seems to make things worse in this respect. Please
go to a (sub-)branch for this kind of experiments...
------------------------------------------------------------------------
r64670 | arigo | 2009-04-25 14:05:23 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py
Rename GuardBinaryOperation to GuardOperation
(they are not binary at all).
------------------------------------------------------------------------
r64671 | arigo | 2009-04-25 15:59:28 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
Avoid the 'make_new_vars' opcodes that only change the order
of variables, without removing any.
------------------------------------------------------------------------
r64673 | arigo | 2009-04-25 17:59:24 +0200 (Sat, 25 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Re-add a line accidentally(?) deleted at r63642.
------------------------------------------------------------------------
r64674 | arigo | 2009-04-25 18:05:47 +0200 (Sat, 25 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Translation fix (this time without breaking the semantics, hopefully).
------------------------------------------------------------------------
r64675 | arigo | 2009-04-25 18:14:43 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Revert r64577: I'm not completely sure I get it, but it seems
related to the accident in r63642 (fixed in r64673).
------------------------------------------------------------------------
r64676 | arigo | 2009-04-25 18:22:31 +0200 (Sat, 25 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/interpreter/pyopcode.py
M /pypy/branch/pyjitpl5/pypy/module/pypyjit/interp_jit.py
Revert r64661, as requested by fijal.
------------------------------------------------------------------------
r64677 | arigo | 2009-04-25 18:35:39 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
* Set DEBUG=True for now.
* execute() returns None.
------------------------------------------------------------------------
r64679 | arigo | 2009-04-25 19:44:08 +0200 (Sat, 25 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Save/restore the exception_box and exc_value_box too.
This is clearly not looking safe...
------------------------------------------------------------------------
r64681 | arigo | 2009-04-25 19:54:44 +0200 (Sat, 25 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Oups
------------------------------------------------------------------------
r64686 | arigo | 2009-04-26 14:17:49 +0200 (Sun, 26 Apr 2009) | 6 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/model.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Experimental: replace _save_recursive_call() with the ReturnBoxes class.
The idea is that the backend should not patch the real boxes in-place,
but only the boxes in ReturnBoxes. The front-end will then copy the
boxes in place in a try:finally:, and restore their value afterwards.
It's expected to be much safer than the previous hack.
------------------------------------------------------------------------
r64687 | arigo | 2009-04-26 14:23:40 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
Fix the minimal backend.
------------------------------------------------------------------------
r64688 | arigo | 2009-04-26 14:40:09 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/model.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Simplify the CPU interface a bit.
------------------------------------------------------------------------
r64689 | arigo | 2009-04-26 15:04:24 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/test/test_llgraph.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/test/test_runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/model.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Revert r64686-r64687-r64688; will do it differently.
------------------------------------------------------------------------
r64691 | arigo | 2009-04-26 16:35:53 +0200 (Sun, 26 Apr 2009) | 7 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/model.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Replace _save_recursive_call() with an interface change. The idea is
that the backend should not patch the real boxes in-place, but only
expose the result via an interface, get_latest_value_xxx(). The
front-end will then copy the values into the boxes in a try:finally:,
and restore their value afterwards. It's expected to be much safer than
the previous hack.
------------------------------------------------------------------------
r64692 | arigo | 2009-04-26 16:40:52 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
Fix the minimal backend.
------------------------------------------------------------------------
r64693 | arigo | 2009-04-26 17:00:26 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Translation fix.
------------------------------------------------------------------------
r64694 | arigo | 2009-04-26 17:01:00 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc2.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
Fix the x86 backend for r64691.
------------------------------------------------------------------------
r64695 | arigo | 2009-04-26 17:18:34 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
Minor clean-up.
------------------------------------------------------------------------
r64696 | arigo | 2009-04-26 18:18:15 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Debugging info.
------------------------------------------------------------------------
r64697 | arigo | 2009-04-26 18:22:38 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit_child.py
M /pypy/branch/pyjitpl5/pypy/jit/tl/pypyjit_demo.py
Updates.
------------------------------------------------------------------------
r64698 | fijal | 2009-04-26 18:55:06 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
make simple_optimize the default
------------------------------------------------------------------------
r64699 | fijal | 2009-04-26 18:55:48 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
Disable this checks
------------------------------------------------------------------------
r64700 | fijal | 2009-04-26 18:57:58 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_basic.py
Revert
------------------------------------------------------------------------
r64701 | arigo | 2009-04-26 18:59:22 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
Add an assert.
------------------------------------------------------------------------
r64702 | fijal | 2009-04-26 19:02:43 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py
a passing test that was lying down in my wc
------------------------------------------------------------------------
r64705 | arigo | 2009-04-26 20:18:38 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py
Probably an accidental checkin.
------------------------------------------------------------------------
r64707 | arigo | 2009-04-26 20:26:08 +0200 (Sun, 26 Apr 2009) | 7 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/llimpl.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/llgraph/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/model.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_recursive.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Use a custom interface to set the initial values to
cpu.execute_operations(), which is set_future_value_xxx(); this is
similar to the custom interface to fetch the values returned by a FAIL
operation, which is get_latest_value_xxx().
This allows us to remove the call to changevalue_xxx() in warmspot.py.
------------------------------------------------------------------------
r64708 | arigo | 2009-04-26 22:04:21 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/test/test_random.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/assembler.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc2.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
Fix the x86 and the minimal backends.
------------------------------------------------------------------------
r64709 | arigo | 2009-04-26 22:26:04 +0200 (Sun, 26 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/runner.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_regalloc.py
M /pypy/branch/pyjitpl5/pypy/jit/backend/x86/test/test_runner.py
Clean-ups.
------------------------------------------------------------------------
r64710 | fijal | 2009-04-27 02:40:02 +0200 (Mon, 27 Apr 2009) | 2 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/backend/minimal/runner.py
*ekhem*
------------------------------------------------------------------------
r64719 | arigo | 2009-04-27 11:33:48 +0200 (Mon, 27 Apr 2009) | 3 lines
Changed paths:
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/compile.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/history.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/pyjitpl5/pypy/jit/metainterp/warmspot.py
Constant string comparison is nicely folded too; forgot about that.
Simplifies result_type.
------------------------------------------------------------------------
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py Mon Apr 27 12:00:08 2009
@@ -809,26 +809,30 @@
frame = Frame(memocast)
return _to_opaque(frame)
+_future_values = []
+
def frame_clear(frame, loop):
frame = _from_opaque(frame)
loop = _from_opaque(loop)
frame.loop = loop
frame.env = {}
+ for i in range(len(loop.inputargs)):
+ frame.env[loop.inputargs[i]] = _future_values[i]
-def frame_add_int(frame, value):
- frame = _from_opaque(frame)
- i = len(frame.env)
- frame.env[frame.loop.inputargs[i]] = value
-
-def frame_add_ptr(frame, value):
- frame = _from_opaque(frame)
- i = len(frame.env)
- frame.env[frame.loop.inputargs[i]] = value
-
-def frame_add_obj(frame, value):
- frame = _from_opaque(frame)
- i = len(frame.env)
- frame.env[frame.loop.inputargs[i]] = value
+def set_future_value_int(index, value):
+ del _future_values[index:]
+ assert len(_future_values) == index
+ _future_values.append(value)
+
+def set_future_value_ptr(index, value):
+ del _future_values[index:]
+ assert len(_future_values) == index
+ _future_values.append(value)
+
+def set_future_value_obj(index, value):
+ del _future_values[index:]
+ assert len(_future_values) == index
+ _future_values.append(value)
def frame_execute(frame):
frame = _from_opaque(frame)
@@ -1199,9 +1203,9 @@
setannotation(new_frame, s_Frame)
setannotation(frame_clear, annmodel.s_None)
-setannotation(frame_add_int, annmodel.s_None)
-setannotation(frame_add_ptr, annmodel.s_None)
-setannotation(frame_add_obj, annmodel.s_None)
+setannotation(set_future_value_int, annmodel.s_None)
+setannotation(set_future_value_ptr, annmodel.s_None)
+setannotation(set_future_value_obj, annmodel.s_None)
setannotation(frame_execute, annmodel.SomeInteger())
setannotation(frame_int_getvalue, annmodel.SomeInteger())
setannotation(frame_ptr_getvalue, annmodel.SomePtr(llmemory.GCREF))
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/runner.py Mon Apr 27 12:00:08 2009
@@ -82,6 +82,7 @@
llimpl._llinterp = LLInterpreter(self.rtyper)
if translate_support_code:
self.mixlevelann = annmixlevel
+ self._future_values = []
def compile_operations(self, loop):
"""In a real assembler backend, this should assemble the given
@@ -152,54 +153,44 @@
llimpl.compile_add_fail(c, len(self.fail_ops))
self.fail_ops.append(op)
- def execute_operations(self, loop, valueboxes):
+ def execute_operations(self, loop):
"""Calls the assembler generated for the given loop.
Returns the ResOperation that failed, of type rop.FAIL.
"""
frame = llimpl.new_frame(self.memo_cast, self.is_oo)
# setup the frame
llimpl.frame_clear(frame, loop._compiled_version)
- for box in valueboxes:
- if isinstance(box, history.BoxInt):
- llimpl.frame_add_int(frame, box.value)
- elif isinstance(box, history.BoxPtr):
- llimpl.frame_add_ptr(frame, box.value)
- elif self.is_oo and isinstance(box, history.BoxObj):
- llimpl.frame_add_obj(frame, box.value)
- elif isinstance(box, history.ConstInt):
- llimpl.frame_add_int(frame, box.value)
- elif isinstance(box, history.ConstPtr):
- llimpl.frame_add_ptr(frame, box.value)
- elif self.is_oo and isinstance(box, history.ConstObj):
- llimpl.frame_add_obj(frame, box.value)
- else:
- raise Exception("bad box in valueboxes: %r" % (box,))
# run the loop
fail_index = llimpl.frame_execute(frame)
- # we hit a FAIL operation. Fish for the values
- # (in a real backend, this should be done by the FAIL operation
- # itself, not here)
- op = self.fail_ops[fail_index]
- for i in range(len(op.args)):
- box = op.args[i]
- if isinstance(box, history.BoxInt):
- value = llimpl.frame_int_getvalue(frame, i)
- box.changevalue_int(value)
- elif isinstance(box, history.BoxPtr):
- value = llimpl.frame_ptr_getvalue(frame, i)
- box.changevalue_ptr(value)
- elif self.is_oo and isinstance(box, history.BoxObj):
- value = llimpl.frame_ptr_getvalue(frame, i)
- box.changevalue_obj(value)
- elif isinstance(box, history.ConstInt):
- pass
- elif isinstance(box, history.ConstPtr):
- pass
- elif self.is_oo and isinstance(box, history.ConstObj):
- pass
- else:
- raise Exception("bad box in 'fail': %r" % (box,))
- return op
+ # we hit a FAIL operation.
+ self.latest_frame = frame
+ return self.fail_ops[fail_index]
+
+ def set_future_value_int(self, index, intvalue):
+ llimpl.set_future_value_int(index, intvalue)
+
+ def set_future_value_ptr(self, index, ptrvalue):
+ llimpl.set_future_value_ptr(index, ptrvalue)
+
+ def set_future_value_obj(self, index, objvalue):
+ llimpl.set_future_value_obj(index, objvalue)
+
+ def get_latest_value_int(self, index):
+ return llimpl.frame_int_getvalue(self.latest_frame, index)
+
+ def get_latest_value_ptr(self, index):
+ return llimpl.frame_ptr_getvalue(self.latest_frame, index)
+
+ def get_latest_value_obj(self, index):
+ return llimpl.frame_ptr_getvalue(self.latest_frame, index)
+
+ # ----------
+
+ def get_exception(self):
+ return self.cast_adr_to_int(llimpl.get_exception())
+
+ def get_exc_value(self):
+ return llimpl.get_exc_value()
def clear_exception(self):
llimpl.clear_exception()
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/minimal/runner.py Mon Apr 27 12:00:08 2009
@@ -6,6 +6,7 @@
from pypy.jit.metainterp import executor
from pypy.jit.metainterp.resoperation import rop, opname
+DEBUG = False
class CPU(object):
is_oo = False # XXX for now
@@ -19,6 +20,7 @@
self.is_oo = False
self.stats = stats
self.translate_support_code = translate_support_code
+ self._future_values = []
self.setup()
def setup(self):
@@ -38,11 +40,12 @@
def compile_operations(self, loop):
pass
- def execute_operations(self, loop, valueboxes):
- #debug_print("execute_operations: starting", loop)
- #for box in valueboxes:
- # debug_print("\t", box, "\t", box.get_())
- valueboxes = [box.clonebox() for box in valueboxes]
+ def execute_operations(self, loop):
+ valueboxes = self._future_values
+ if DEBUG:
+ print "execute_operations: starting", loop
+ for box in valueboxes:
+ print "\t", box, "\t", box.get_()
self.clear_exception()
self._guard_failed = False
while True:
@@ -60,20 +63,24 @@
op = operations[i]
i += 1
argboxes = []
- #lst = [' %s ' % opname[op.opnum]]
+ if DEBUG:
+ lst = [' %s ' % opname[op.opnum]]
for box in op.args:
if isinstance(box, Box):
box = env[box]
argboxes.append(box)
- #lst.append(str(box.get_()))
- #debug_print(' '.join(lst))
+ if DEBUG:
+ lst.append(str(box.get_()))
+ if DEBUG:
+ print ' '.join(lst)
if op.is_final():
break
if op.is_guard():
try:
resbox = self.execute_guard(op.opnum, argboxes)
except GuardFailed:
- #debug_print("\t*guard failed*")
+ if DEBUG:
+ print "\t*guard failed (%s)*" % op.getopname()
self._guard_failed = True
operations = op.suboperations
i = 0
@@ -85,7 +92,8 @@
if op.result is not None:
ll_assert(resbox is not None,
"execute_operations: unexpectedly got None")
- #debug_print('\t-->', resbox.get_())
+ if DEBUG:
+ print '\t-->', resbox.get_()
env[op.result] = resbox
else:
ll_assert(resbox is None,
@@ -98,19 +106,32 @@
if op.opnum == rop.FAIL:
break
ll_assert(False, "execute_operations: bad opnum")
- #
- #debug_print("execute_operations: leaving", loop)
- for i in range(len(op.args)):
- box = op.args[i]
- if isinstance(box, BoxInt):
- value = env[box].getint()
- box.changevalue_int(value)
- elif isinstance(box, BoxPtr):
- value = env[box].getptr_base()
- box.changevalue_ptr(value)
- #debug_print("\t", box, "\t", box.get_())
+
+ if DEBUG:
+ print "execute_operations: leaving", loop
+ for box in op.args:
+ print "\t", env[box], "\t", env[box].get_()
+ self.latest_fail = op, env
return op
+ def set_future_value_int(self, index, intvalue):
+ del self._future_values[index:]
+ assert len(self._future_values) == index
+ self._future_values.append(BoxInt(intvalue))
+
+ def set_future_value_ptr(self, index, ptrvalue):
+ del self._future_values[index:]
+ assert len(self._future_values) == index
+ self._future_values.append(BoxPtr(ptrvalue))
+
+ def get_latest_value_int(self, index):
+ op, env = self.latest_fail
+ return env[op.args[index]].getint()
+
+ def get_latest_value_ptr(self, index):
+ op, env = self.latest_fail
+ return env[op.args[index]].getptr_base()
+
def execute_guard(self, opnum, argboxes):
if opnum == rop.GUARD_TRUE:
value = argboxes[0].getint()
@@ -363,12 +384,14 @@
except Exception, e:
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
self.current_exc_inst = cast_instance_to_base_ptr(e)
- #debug_print('\tcall raised!', self.current_exc_inst)
+ if DEBUG:
+ print '\tcall raised!', self.current_exc_inst
box = calldescr.errbox
if box:
box = box.clonebox()
- #else:
- #debug_print('\tcall did not raise')
+ else:
+ if DEBUG:
+ print '\tcall did not raise'
return box
# ----------
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/model.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/model.py Mon Apr 27 12:00:08 2009
@@ -4,12 +4,40 @@
"""Assemble the given list of operations."""
raise NotImplementedError
- def execute_operations(self, loop, valueboxes):
+ def execute_operations(self, loop):
"""Calls the assembler generated for the given loop.
Returns the ResOperation that failed, of type rop.FAIL.
+ Use set_future_value_xxx() before, and get_latest_value_xxx() after.
"""
raise NotImplementedError
-
+
+ def set_future_value_int(self, index, intvalue):
+ """Set the value for the index'th argument for the loop to run."""
+ raise NotImplementedError
+
+ def set_future_value_ptr(self, index, ptrvalue):
+ """Set the value for the index'th argument for the loop to run."""
+ raise NotImplementedError
+
+ def set_future_value_obj(self, index, objvalue):
+ """Set the value for the index'th argument for the loop to run."""
+ raise NotImplementedError
+
+ def get_latest_value_int(self, index):
+ """Returns the value for the index'th argument to the
+ lastest rop.FAIL. Returns an int."""
+ raise NotImplementedError
+
+ def get_latest_value_ptr(self, index):
+ """Returns the value for the index'th argument to the
+ lastest rop.FAIL. Returns a ptr."""
+ raise NotImplementedError
+
+ def get_latest_value_obj(self, index):
+ """Returns the value for the index'th argument to the
+ lastest rop.FAIL. Returns an obj."""
+ raise NotImplementedError
+
def get_exception(self):
raise NotImplementedError
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py Mon Apr 27 12:00:08 2009
@@ -1,7 +1,7 @@
import sys
from pypy.jit.metainterp.history import (BoxInt, Box, BoxPtr, TreeLoop,
- ConstInt, ConstPtr)
+ ConstInt, ConstPtr, BoxObj)
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass
from pypy.jit.metainterp.executor import execute
@@ -23,14 +23,26 @@
def execute_operation(self, opname, valueboxes, result_type, descr=None):
loop = self.get_compiled_single_operation(opname, result_type,
valueboxes, descr)
- boxes = [box for box in valueboxes if isinstance(box, Box)]
- res = self.cpu.execute_operations(loop, boxes)
+ j = 0
+ for box in valueboxes:
+ if isinstance(box, BoxInt):
+ self.cpu.set_future_value_int(j, box.getint())
+ j += 1
+ elif isinstance(box, BoxPtr):
+ self.cpu.set_future_value_ptr(j, box.getptr_base())
+ j += 1
+ elif isinstance(box, BoxObj):
+ self.cpu.set_future_value_obj(j, box.getobj())
+ j += 1
+ res = self.cpu.execute_operations(loop)
if res is loop.operations[-1]:
self.guard_failed = False
else:
self.guard_failed = True
- if result_type != 'void':
- return res.args[0]
+ if result_type == 'int':
+ return BoxInt(self.cpu.get_latest_value_int(0))
+ elif result_type == 'ptr':
+ return BoxPtr(self.cpu.get_latest_value_ptr(0))
def get_compiled_single_operation(self, opnum, result_type, valueboxes,
descr):
@@ -155,7 +167,7 @@
def test_ovf_operations(self):
minint = -sys.maxint-1
- boom = 666
+ boom = 'boom'
for opnum, testcases in [
(rop.INT_ADD_OVF, [(10, -2, 8),
(-1, minint, boom),
@@ -200,15 +212,21 @@
]
if opnum in (rop.INT_NEG_OVF, rop.INT_ABS_OVF):
del ops[0].args[1]
- ops[1].suboperations = [ResOperation(rop.FAIL, [ConstInt(boom)],
+ ops[1].suboperations = [ResOperation(rop.FAIL, [],
None)]
loop = TreeLoop('name')
loop.operations = ops
loop.inputargs = [v1, v2]
self.cpu.compile_operations(loop)
for x, y, z in testcases:
- op = self.cpu.execute_operations(loop, [BoxInt(x), BoxInt(y)])
- assert op.args[0].value == z
+ self.cpu.set_future_value_int(0, x)
+ self.cpu.set_future_value_int(1, y)
+ op = self.cpu.execute_operations(loop)
+ if z == boom:
+ assert op is ops[1].suboperations[0]
+ else:
+ assert op is ops[-1]
+ assert self.cpu.get_latest_value_int(0) == z
# ----------
# the same thing but with the exception path reversed
## v1 = BoxInt(testcases[0][0])
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/test_random.py Mon Apr 27 12:00:08 2009
@@ -56,15 +56,18 @@
print >>s, ' ]'
print >>s, ' cpu = CPU(None, None)'
print >>s, ' cpu.compile_operations(loop)'
- print >>s, ' op = cpu.execute_operations(loop, [%s])' % (
- ', '.join(['BoxInt(%d)' % v.value for v in self.loop.inputargs]))
+ for i, v in enumerate(self.loop.inputargs):
+ print >>s, ' cpu.set_future_value_int(%d, %d)' % (i, v.value)
+ print >>s, ' op = cpu.execute_operations(loop)'
if self.should_fail_by is None:
- for v in self.loop.operations[-1].args:
- print >>s, ' assert %s.value == %d' % (names[v], v.value)
+ for i, v in enumerate(self.loop.operations[-1].args):
+ print >>s, ' assert cpu.get_latest_value_int(%d) == %d' % (
+ i, v.value)
else:
print >>s, ' assert op is loop.operations[%d].suboperations[0]' % self.should_fail_by_num
- for v in self.should_fail_by.args:
- print >>s, ' assert %s.value == %d' % (names[v], v.value)
+ for i, v in enumerate(self.should_fail_by.args):
+ print >>s, ' assert cpu.get_latest_value_int(%d) == %d' % (
+ i, v.value)
self.names = names
if demo_conftest.option.output:
s.close()
@@ -111,7 +114,7 @@
v_second = v
self.put(builder, [v_first, v_second])
-class GuardBinaryOperation(AbstractOperation):
+class GuardOperation(AbstractOperation):
def produce_into(self, builder, r):
v = builder.get_bool_var(r)
@@ -158,8 +161,9 @@
OPERATIONS.append(BinaryOperation(rop.INT_RSHIFT, LONG_BIT-1))
OPERATIONS.append(BinaryOperation(rop.INT_LSHIFT, LONG_BIT-1))
OPERATIONS.append(BinaryOperation(rop.UINT_RSHIFT, LONG_BIT-1))
-OPERATIONS.append(GuardBinaryOperation(rop.GUARD_TRUE))
-OPERATIONS.append(GuardBinaryOperation(rop.GUARD_FALSE))
+
+OPERATIONS.append(GuardOperation(rop.GUARD_TRUE))
+OPERATIONS.append(GuardOperation(rop.GUARD_FALSE))
for _op in [rop.INT_NEG,
rop.INT_INVERT,
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 Mon Apr 27 12:00:08 2009
@@ -264,20 +264,17 @@
self.make_sure_mc_exists()
addr = self.mc.tell()
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):
- self.mc.MOV(ecx, mem(eax, i * WORD))
+ self.mc.MOV(ecx,
+ addr_add(imm(self.fail_box_addr), imm(i*WORD)))
self.mc.MOV(loc, ecx)
for i in range(len(arglocs)):
loc = arglocs[i]
- if isinstance(loc, REG) and loc is not eax:
- self.mc.MOV(loc, mem(eax, i * WORD))
- for i in range(len(arglocs)):
- loc = arglocs[i]
- if loc is eax:
- self.mc.MOV(loc, mem(eax, i * WORD))
+ if isinstance(loc, REG):
+ self.mc.MOV(loc,
+ addr_add(imm(self.fail_box_addr), imm(i*WORD)))
self.mc.JMP(rel32(jumpaddr))
self.mc.done()
return addr
@@ -867,7 +864,7 @@
self.mc.PUSH(stack_pos(loc.position + extra_on_stack))
extra_on_stack += 1
if isinstance(op.args[0], Const):
- x = rel32(self.cpu.get_box_value_as_int(op.args[0]))
+ x = rel32(op.args[0].getint())
else:
x = arglocs[0]
if isinstance(x, MODRM):
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 Mon Apr 27 12:00:08 2009
@@ -11,7 +11,7 @@
from pypy.jit.metainterp import history, codewriter
from pypy.jit.metainterp.history import (ResOperation, Box, Const,
ConstInt, ConstPtr, BoxInt, BoxPtr, ConstAddr, AbstractDescr)
-from pypy.jit.backend.x86.assembler import Assembler386, WORD
+from pypy.jit.backend.x86.assembler import Assembler386, WORD, MAX_FAIL_BOXES
from pypy.jit.backend.x86 import symbolic
from pypy.jit.metainterp.resoperation import rop, opname
from pypy.jit.backend.x86.support import gc_malloc_fnaddr
@@ -69,8 +69,7 @@
debug = True
is_oo = False
- BOOTSTRAP_TP = lltype.FuncType([lltype.Ptr(rffi.CArray(lltype.Signed))],
- lltype.Signed)
+ BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
def __init__(self, rtyper, stats, translate_support_code=False,
mixlevelann=None):
@@ -92,7 +91,6 @@
self.current_interpreter._store_exception = _store_exception
TP = lltype.GcArray(llmemory.GCREF)
self.keepalives = []
- self.keepalives_index = 0
self._bootstrap_cache = {}
self._guard_list = []
self._compiled_ops = {}
@@ -179,8 +177,8 @@
# self.caught_exception = e
# return self.assembler.generic_return_addr
- def set_meta_interp(self, metainterp):
- self.metainterp = metainterp
+# def set_meta_interp(self, metainterp):
+# self.metainterp = metainterp
def get_exception(self):
self.assembler.make_sure_mc_exists()
@@ -231,28 +229,6 @@
self._bootstrap_cache[key] = func
return func
- def get_box_value_as_int(self, box):
- if isinstance(box, BoxInt):
- return box.value
- elif isinstance(box, ConstInt):
- return box.value
- elif isinstance(box, BoxPtr):
- self.keepalives.append(box.value)
- return self.cast_gcref_to_int(box.value)
- elif isinstance(box, ConstPtr):
- self.keepalives.append(box.value)
- return self.cast_gcref_to_int(box.value)
- elif isinstance(box, ConstAddr):
- return self.cast_adr_to_int(box.value)
- else:
- raise ValueError('get_box_value_as_int, wrong arg')
-
- def set_value_of_box(self, box, index, fail_boxes):
- if isinstance(box, BoxInt):
- box.value = fail_boxes[index]
- elif isinstance(box, BoxPtr):
- box.value = self.cast_int_to_gcref(fail_boxes[index])
-
def _new_box(self, ptr):
if ptr:
return BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
@@ -260,21 +236,16 @@
def _get_loop_for_call(self, argnum, calldescr, ptr):
try:
- loop = self.generated_mps[calldescr]
- box = self._new_box(ptr)
- loop.operations[0].result = box
- loop.operations[-1].args[0] = box
- loop.operations[1].suboperations[0].args[0] = box
- return loop
+ return self.generated_mps[calldescr]
except KeyError:
pass
- args = [BoxInt(0) for i in range(argnum + 1)]
+ args = [BoxInt() for i in range(argnum + 1)]
result = self._new_box(ptr)
operations = [
ResOperation(rop.CALL, args, result, calldescr),
ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
ResOperation(rop.FAIL, [result], None)]
- operations[1].suboperations = [ResOperation(rop.FAIL, [result], None)]
+ operations[1].suboperations = [ResOperation(rop.FAIL, [], None)]
loop = history.TreeLoop('call')
loop.inputargs = args
loop.operations = operations
@@ -282,36 +253,38 @@
self.generated_mps[calldescr] = loop
return loop
- def execute_operations(self, loop, valueboxes):
+ def execute_operations(self, loop):
func = self.get_bootstrap_code(loop)
- # turn all the values into integers
- TP = rffi.CArray(lltype.Signed)
- oldindex = self.keepalives_index
- values_as_int = lltype.malloc(TP, len(valueboxes), flavor='raw')
- for i in range(len(valueboxes)):
- box = valueboxes[i]
- v = self.get_box_value_as_int(box)
- values_as_int[i] = v
# debug info
#if self.debug and not we_are_translated():
# values_repr = ", ".join([str(values_as_int[i]) for i in
# range(len(valueboxes))])
# llop.debug_print(lltype.Void, 'exec:', name, values_repr)
- self.assembler.log_call(valueboxes)
- self.keepalives_index = len(self.keepalives)
- guard_index = self.execute_call(loop, func, values_as_int)
+ #self.assembler.log_call(valueboxes) --- XXX
+ guard_index = self.execute_call(loop, func)
self._guard_index = guard_index # for tests
- keepalive_until_here(valueboxes)
- self.keepalives_index = oldindex
- del self.keepalives[oldindex:]
op = self._guard_list[guard_index]
#print "Leaving at: %d" % self.assembler.fail_boxes[len(op.args)]
- for i in range(len(op.args)):
- box = op.args[i]
- self.set_value_of_box(box, i, self.assembler.fail_boxes)
return op
- def execute_call(self, loop, func, values_as_int):
+ def set_future_value_int(self, index, intvalue):
+ assert index < MAX_FAIL_BOXES, "overflow!"
+ self.assembler.fail_boxes[index] = intvalue
+
+ def set_future_value_ptr(self, index, ptrvalue):
+ assert index < MAX_FAIL_BOXES, "overflow!"
+ self.keepalives.append(ptrvalue)
+ intvalue = self.cast_gcref_to_int(ptrvalue)
+ self.assembler.fail_boxes[index] = intvalue
+
+ def get_latest_value_int(self, index):
+ return self.assembler.fail_boxes[index]
+
+ def get_latest_value_ptr(self, index):
+ intvalue = self.assembler.fail_boxes[index]
+ return self.cast_int_to_gcref(intvalue)
+
+ def execute_call(self, loop, func):
# help flow objspace
prev_interpreter = None
if not self.translate_support_code:
@@ -321,12 +294,12 @@
try:
self.caught_exception = None
#print "Entering: %d" % rffi.cast(lltype.Signed, func)
- res = func(values_as_int)
+ res = func()
+ del self.keepalives[:]
self.reraise_caught_exception()
finally:
if not self.translate_support_code:
LLInterpreter.current_interpreter = prev_interpreter
- lltype.free(values_as_int, flavor='raw')
return res
def reraise_caught_exception(self):
@@ -346,21 +319,21 @@
self._guard_list.append(guard_op)
return index
- def convert_box_to_int(self, valuebox):
- if isinstance(valuebox, ConstInt):
- return valuebox.value
- elif isinstance(valuebox, BoxInt):
- return valuebox.value
- elif isinstance(valuebox, BoxPtr):
- x = self.cast_gcref_to_int(valuebox.value)
- self.keepalives.append(valuebox.value)
- return x
- elif isinstance(valuebox, ConstPtr):
- x = self.cast_gcref_to_int(valuebox.value)
- self.keepalives.append(valuebox.value)
- return x
- else:
- raise ValueError(valuebox.type)
+# def convert_box_to_int(self, valuebox):
+# if isinstance(valuebox, ConstInt):
+# return valuebox.value
+# elif isinstance(valuebox, BoxInt):
+# return valuebox.value
+# elif isinstance(valuebox, BoxPtr):
+# x = self.cast_gcref_to_int(valuebox.value)
+# self.keepalives.append(valuebox.value)
+# return x
+# elif isinstance(valuebox, ConstPtr):
+# x = self.cast_gcref_to_int(valuebox.value)
+# self.keepalives.append(valuebox.value)
+# return x
+# else:
+# raise ValueError(valuebox.type)
# def getvaluebox(self, frameadr, guard_op, argindex):
# # XXX that's plain stupid, do we care about the return value???
@@ -565,10 +538,16 @@
num_args, size, ptr = self.unpack_calldescr(calldescr)
assert isinstance(calldescr, ConstDescr3)
loop = self._get_loop_for_call(num_args, calldescr, ptr)
- op = self.execute_operations(loop, args)
+ history.set_future_values(self, args)
+ self.execute_operations(loop)
+ # Note: if an exception is set, the rest of the code does a bit of
+ # nonsense but nothing wrong (the return value should be ignored)
if size == 0:
return None
- return op.args[0]
+ elif ptr:
+ return BoxPtr(self.get_latest_value_ptr(0))
+ else:
+ return BoxInt(self.get_latest_value_int(0))
def do_cast_ptr_to_int(self, args, descr=None):
return BoxInt(self.cast_gcref_to_int(args[0].getptr_base()))
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_regalloc.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_regalloc.py Mon Apr 27 12:00:08 2009
@@ -3,6 +3,7 @@
"""
import py
+py.test.skip("Think about a nice way of doing stuff below")
from pypy.jit.backend.x86.test.test_runner import FakeMetaInterp, FakeStats
from pypy.jit.metainterp.history import ResOperation, BoxInt, ConstInt,\
BoxPtr, ConstPtr
@@ -10,7 +11,6 @@
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp.resoperation import rop
from pypy.rpython.lltypesystem import lltype, llmemory
-py.test.skip("Think about a nice way of doing stuff below")
def test_simple_loop():
meta_interp = FakeMetaInterp()
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/test/test_runner.py Mon Apr 27 12:00:08 2009
@@ -15,9 +15,6 @@
class FakeStats(object):
pass
-class FakeMetaInterp(object):
- pass
-
# ____________________________________________________________
class TestX86(BaseBackendTest):
@@ -27,7 +24,6 @@
def setup_class(cls):
cls.cpu = CPU(rtyper=None, stats=FakeStats())
- cls.cpu.set_meta_interp(FakeMetaInterp())
def test_int_binary_ops(self):
for op, args, res in [
@@ -69,7 +65,6 @@
def test_execute_operations_in_env(self):
cpu = self.cpu
- cpu.set_meta_interp(FakeMetaInterp())
x = BoxInt(123)
y = BoxInt(456)
z = BoxInt(579)
@@ -88,8 +83,11 @@
operations[-1].jump_target = loop
operations[-2].suboperations = [ResOperation(rop.FAIL, [t, z], None)]
cpu.compile_operations(loop)
- res = self.cpu.execute_operations(loop, [BoxInt(0), BoxInt(10)])
- assert [arg.value for arg in res.args] == [0, 55]
+ self.cpu.set_future_value_int(0, 0)
+ self.cpu.set_future_value_int(1, 10)
+ res = self.cpu.execute_operations(loop)
+ assert self.cpu.get_latest_value_int(0) == 0
+ assert self.cpu.get_latest_value_int(1) == 55
def test_misc_int_ops(self):
for op, args, res in [
@@ -463,11 +461,13 @@
loop.operations = ops
loop.inputargs = [b]
self.cpu.compile_operations(loop)
- r = self.cpu.execute_operations(loop, [b])
+ self.cpu.set_future_value_ptr(0, b.value)
+ r = self.cpu.execute_operations(loop)
+ result = self.cpu.get_latest_value_int(0)
if guard == rop.GUARD_FALSE:
- assert r.args[0].value == execute(self.cpu, op, [b]).value
+ assert result == execute(self.cpu, op, [b]).value
else:
- assert r.args[0].value != execute(self.cpu, op, [b]).value
+ assert result != execute(self.cpu, op, [b]).value
def test_stuff_followed_by_guard(self):
@@ -503,11 +503,14 @@
loop.operations = ops
loop.inputargs = [i for i in (a, b) if isinstance(i, Box)]
self.cpu.compile_operations(loop)
- r = self.cpu.execute_operations(loop, loop.inputargs)
+ for i, box in enumerate(loop.inputargs):
+ self.cpu.set_future_value_int(i, box.value)
+ r = self.cpu.execute_operations(loop)
+ result = self.cpu.get_latest_value_int(0)
if guard == rop.GUARD_FALSE:
- assert r.args[0].value == execute(self.cpu, op, (a, b)).value
+ assert result == execute(self.cpu, op, (a, b)).value
else:
- assert r.args[0].value != execute(self.cpu, op, (a, b)).value
+ assert result != execute(self.cpu, op, (a, b)).value
def test_overflow_mc(self):
from pypy.jit.backend.x86.assembler import MachineCodeBlockWrapper
@@ -530,8 +533,9 @@
loop.operations = ops
loop.inputargs = [base_v]
self.cpu.compile_operations(loop)
- op = self.cpu.execute_operations(loop, [base_v])
- assert op.args[0].value == 1024
+ self.cpu.set_future_value_int(0, base_v.value)
+ op = self.cpu.execute_operations(loop)
+ assert self.cpu.get_latest_value_int(0) == 1024
finally:
MachineCodeBlockWrapper.MC_SIZE = orig_size
self.cpu.assembler.mc = old_mc
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py Mon Apr 27 12:00:08 2009
@@ -44,31 +44,32 @@
class IndirectCallset(history.AbstractValue):
def __init__(self, codewriter, graphs):
- keys = []
- values = []
+ self.keys = []
+ self.values = []
for graph in graphs:
fnptr = codewriter.rtyper.getcallable(graph)
fnaddress = codewriter.ts.cast_fnptr_to_root(fnptr)
- keys.append(fnaddress)
- values.append(codewriter.get_jitcode(graph))
+ self.keys.append(fnaddress)
+ self.values.append(codewriter.get_jitcode(graph))
+ self.dict = None
- def bytecode_for_address(fnaddress):
- if we_are_translated():
- if self.dict is None:
- # Build the dictionary at run-time. This is needed
- # because the keys are function addresses, so they
- # can change from run to run.
- self.dict = {}
- for i in range(len(keys)):
- self.dict[keys[i]] = values[i]
- return self.dict[fnaddress]
- else:
+ def bytecode_for_address(self, fnaddress):
+ if we_are_translated():
+ if self.dict is None:
+ # Build the dictionary at run-time. This is needed
+ # because the keys are function addresses, so they
+ # can change from run to run.
+ self.dict = {}
+ keys = self.keys
+ values = self.values
for i in range(len(keys)):
- if fnaddress == keys[i]:
- return values[i]
- raise KeyError(fnaddress)
- self.bytecode_for_address = bytecode_for_address
- self.dict = None
+ self.dict[keys[i]] = values[i]
+ return self.dict[fnaddress]
+ else:
+ for i in range(len(self.keys)):
+ if fnaddress == self.keys[i]:
+ return self.values[i]
+ raise KeyError(fnaddress)
class SwitchDict(history.AbstractValue):
"Get a 'dict' attribute mapping integer values to bytecode positions."
@@ -256,6 +257,7 @@
self.codewriter = codewriter
self.cpu = codewriter.metainterp_sd.cpu
self.portal = portal
+ self.block_start_order = {}
graph, oosend_methdescr = graph_key
self.bytecode = self.codewriter.get_jitcode(graph,
oosend_methdescr=oosend_methdescr)
@@ -326,6 +328,7 @@
self.emit("return")
elif len(block.inputargs) == 2:
# exception block, raising an exception from a function
+ assert self.force_block_args_order(block) == block.inputargs
self.emit("raise")
else:
raise Exception("?")
@@ -338,7 +341,7 @@
self.seen_blocks[block] = True
self.free_vars = 0
self.var_positions = {}
- for arg in block.inputargs:
+ for arg in self.force_block_args_order(block):
self.register_var(arg, verbose=False)
self.emit(label(block))
#self.make_prologue(block)
@@ -366,7 +369,7 @@
if len(block.exits) == 1 or block.exitswitch == c_last_exception:
link = block.exits[0]
assert link.exitcase is None
- self.emit(*self.insert_renaming(link.args))
+ self.emit(*self.insert_renaming(link))
self.make_bytecode_block(link.target)
elif (len(block.exits) == 2
and block.exitswitch.concretetype == lltype.Bool):
@@ -377,8 +380,8 @@
tlabel(linkfalse),
self.var_position(block.exitswitch))
self.minimize_variables(argument_only=True, exitswitch=False)
- truerenaming = self.insert_renaming(linktrue.args)
- falserenaming = self.insert_renaming(linkfalse.args)
+ truerenaming = self.insert_renaming(linktrue)
+ falserenaming = self.insert_renaming(linkfalse)
# true path:
self.emit(*truerenaming)
self.make_bytecode_block(linktrue.target)
@@ -406,11 +409,11 @@
self.emit_list([self.const_position(link.llexitcase)
for link in switches])
self.emit_list([tlabel(link) for link in switches])
- renamings = [self.insert_renaming(link.args)
+ renamings = [self.insert_renaming(link)
for link in switches]
if block.exits[-1].exitcase == 'default':
link = block.exits[-1]
- self.emit(*self.insert_renaming(link.args))
+ self.emit(*self.insert_renaming(link))
self.make_bytecode_block(link.target)
for renaming, link in zip(renamings, switches):
self.emit(label(link))
@@ -423,7 +426,8 @@
handler = object()
renamings = []
for i, link in enumerate(exception_exits):
- args_without_last_exc = [v for v in link.args
+ args = self.force_link_args_order(link)
+ args_without_last_exc = [v for v in args
if (v is not link.last_exception and
v is not link.last_exc_value)]
if (link.exitcase is Exception and
@@ -432,8 +436,8 @@
# stop at the catch-and-reraise-every-exception branch, if any
exception_exits = exception_exits[:i]
break
- renamings.append(self.insert_renaming(args_without_last_exc,
- force=True))
+ list = self.get_renaming_list(args_without_last_exc)
+ renamings.append(self.make_new_vars(list))
self.pending_exception_handlers.append((handler, exception_exits,
renamings))
self.emit("setup_exception_block",
@@ -471,15 +475,44 @@
args = [v for v in args if v.concretetype is not lltype.Void]
return [self.var_position(v) for v in args]
- def insert_renaming(self, args, force=False):
- list = self.get_renaming_list(args)
- if not force and list == range(0, self.free_vars*2, 2):
- return [] # no-op
+ def make_new_vars(self, list):
if len(list) >= MAX_MAKE_NEW_VARS:
return ["make_new_vars", len(list)] + list
else:
return ["make_new_vars_%d" % len(list)] + list
+ def force_block_args_order(self, block):
+ non_void = [v for v in block.inputargs
+ if v.concretetype is not lltype.Void]
+ if block not in self.block_start_order:
+ self.block_start_order[block] = range(len(non_void))
+ return [non_void[i] for i in self.block_start_order[block]]
+
+ def force_link_args_order(self, link):
+ self.force_block_args_order(link.target)
+ non_void = [v for v in link.args
+ if v.concretetype is not lltype.Void]
+ return [non_void[i] for i in self.block_start_order[link.target]]
+
+ def insert_renaming(self, link):
+ shortcut = False
+ list = self.get_renaming_list(link.args)
+ if link.target not in self.block_start_order:
+ if (sorted(list) == range(0, self.free_vars*2, 2)
+ and link.target.operations != ()):
+ nlist = [None] * len(list)
+ for index, n in enumerate(list):
+ nlist[n/2] = index
+ self.block_start_order[link.target] = nlist
+ shortcut = True
+ else:
+ self.force_block_args_order(link.target)
+ list = [list[i] for i in self.block_start_order[link.target]]
+ if list == range(0, self.free_vars*2, 2):
+ return [] # no-op
+ assert not shortcut
+ return self.make_new_vars(list)
+
def minimize_variables(self, argument_only=False, exitswitch=True):
if self.dont_minimize_variables:
assert not argument_only
@@ -496,12 +529,12 @@
vars = seen.items()
vars.sort()
vars = [v1 for pos, v1 in vars]
+ renaming_list = self.get_renaming_list(vars)
if argument_only:
# only generate the list of vars as an arg in a complex operation
- renaming_list = self.get_renaming_list(vars)
self.emit(len(renaming_list), *renaming_list)
- else:
- self.emit(*self.insert_renaming(vars))
+ elif renaming_list != range(0, self.free_vars*2, 2):
+ self.emit(*self.make_new_vars(renaming_list))
self.free_vars = 0
self.var_positions.clear()
for v1 in vars:
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/compile.py Mon Apr 27 12:00:08 2009
@@ -6,7 +6,8 @@
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp.history import TreeLoop, log, Box, History
-from pypy.jit.metainterp.history import AbstractDescr, BoxInt, BoxPtr
+from pypy.jit.metainterp.history import AbstractDescr, BoxInt, BoxPtr, BoxObj
+from pypy.jit.metainterp import history
from pypy.jit.metainterp.specnode import NotSpecNode
from pypy.rlib.debug import debug_print
@@ -58,7 +59,7 @@
else:
if target_loop is not None:
show_loop(metainterp, target_loop)
- if target_loop is not None and target_loop not in map_loop2descr:
+ if target_loop is not None and type(target_loop) is not TerminatingLoop:
target_loop.check_consistency()
return target_loop
@@ -71,7 +72,7 @@
errmsg += ': ' + str(error)
else:
errmsg = None
- if loop is None or loop in map_loop2descr:
+ if loop is None or type(loop) is TerminatingLoop:
extraloops = []
else:
extraloops = [loop]
@@ -122,50 +123,94 @@
# ____________________________________________________________
-class DoneWithThisFrameDescr0(AbstractDescr):
+class DoneWithThisFrameDescrVoid(AbstractDescr):
def handle_fail_op(self, metainterp_sd, fail_op):
- raise metainterp_sd.DoneWithThisFrame(None)
+ assert metainterp_sd.result_type == 'void'
+ raise metainterp_sd.DoneWithThisFrameVoid()
-class DoneWithThisFrameDescr1(AbstractDescr):
+class DoneWithThisFrameDescrInt(AbstractDescr):
def handle_fail_op(self, metainterp_sd, fail_op):
+ assert metainterp_sd.result_type == 'int'
resultbox = fail_op.args[0]
- raise metainterp_sd.DoneWithThisFrame(resultbox)
+ if isinstance(resultbox, BoxInt):
+ result = metainterp_sd.cpu.get_latest_value_int(0)
+ else:
+ assert isinstance(resultbox, history.Const)
+ result = resultbox.getint()
+ raise metainterp_sd.DoneWithThisFrameInt(result)
+
+class DoneWithThisFrameDescrPtr(AbstractDescr):
+ def handle_fail_op(self, metainterp_sd, fail_op):
+ assert metainterp_sd.result_type == 'ptr'
+ resultbox = fail_op.args[0]
+ if isinstance(resultbox, BoxPtr):
+ result = metainterp_sd.cpu.get_latest_value_ptr(0)
+ else:
+ assert isinstance(resultbox, history.Const)
+ result = resultbox.getptr_base()
+ raise metainterp_sd.DoneWithThisFramePtr(result)
+
+class DoneWithThisFrameDescrObj(AbstractDescr):
+ def handle_fail_op(self, metainterp_sd, fail_op):
+ assert metainterp_sd.result_type == 'obj'
+ resultbox = fail_op.args[0]
+ if isinstance(resultbox, BoxObj):
+ result = metainterp_sd.cpu.get_latest_value_obj(0)
+ else:
+ assert isinstance(resultbox, history.Const)
+ result = resultbox.getobj()
+ raise metainterp_sd.DoneWithThisFrameObj(result)
class ExitFrameWithExceptionDescr(AbstractDescr):
def handle_fail_op(self, metainterp_sd, fail_op):
assert len(fail_op.args) == 1
valuebox = fail_op.args[0]
- raise metainterp_sd.ExitFrameWithException(valuebox)
-
-done_with_this_frame_descr_0 = DoneWithThisFrameDescr0()
-done_with_this_frame_descr_1 = DoneWithThisFrameDescr1()
+ if isinstance(valuebox, BoxPtr):
+ value = metainterp_sd.cpu.get_latest_value_ptr(0)
+ else:
+ assert isinstance(valuebox, history.Const)
+ value = valuebox.getptr_base()
+ raise metainterp_sd.ExitFrameWithException(value)
+
+done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid()
+done_with_this_frame_descr_int = DoneWithThisFrameDescrInt()
+done_with_this_frame_descr_ptr = DoneWithThisFrameDescrPtr()
+done_with_this_frame_descr_obj = DoneWithThisFrameDescrObj()
exit_frame_with_exception_descr = ExitFrameWithExceptionDescr()
-map_loop2descr = {}
+
+class TerminatingLoop(TreeLoop):
+ pass
# pseudo-loops to make the life of optimize.py easier
-_loop = TreeLoop('done_with_this_frame_int')
+_loop = TerminatingLoop('done_with_this_frame_int')
_loop.specnodes = [NotSpecNode()]
_loop.inputargs = [BoxInt()]
+_loop.finishdescr = done_with_this_frame_descr_int
loops_done_with_this_frame_int = [_loop]
-map_loop2descr[_loop] = done_with_this_frame_descr_1
-_loop = TreeLoop('done_with_this_frame_ptr')
+_loop = TerminatingLoop('done_with_this_frame_ptr')
_loop.specnodes = [NotSpecNode()]
_loop.inputargs = [BoxPtr()]
+_loop.finishdescr = done_with_this_frame_descr_ptr
loops_done_with_this_frame_ptr = [_loop]
-map_loop2descr[_loop] = done_with_this_frame_descr_1
-_loop = TreeLoop('done_with_this_frame_void')
+_loop = TerminatingLoop('done_with_this_frame_obj')
+_loop.specnodes = [NotSpecNode()]
+_loop.inputargs = [BoxObj()]
+_loop.finishdescr = done_with_this_frame_descr_obj
+loops_done_with_this_frame_obj = [_loop]
+
+_loop = TerminatingLoop('done_with_this_frame_void')
_loop.specnodes = []
_loop.inputargs = []
+_loop.finishdescr = done_with_this_frame_descr_void
loops_done_with_this_frame_void = [_loop]
-map_loop2descr[_loop] = done_with_this_frame_descr_0
-_loop = TreeLoop('exit_frame_with_exception')
+_loop = TerminatingLoop('exit_frame_with_exception')
_loop.specnodes = [NotSpecNode()]
_loop.inputargs = [BoxPtr()]
+_loop.finishdescr = exit_frame_with_exception_descr
loops_exit_frame_with_exception = [_loop]
-map_loop2descr[_loop] = exit_frame_with_exception_descr
del _loop
@@ -181,7 +226,49 @@
def handle_fail_op(self, metainterp_sd, fail_op):
from pypy.jit.metainterp.pyjitpl import MetaInterp
metainterp = MetaInterp(metainterp_sd)
- return metainterp.handle_guard_failure(fail_op, self)
+ patch = self.patch_boxes_temporarily(metainterp_sd, fail_op)
+ try:
+ return metainterp.handle_guard_failure(fail_op, self)
+ finally:
+ self.restore_patched_boxes(metainterp_sd, fail_op, patch)
+
+ def patch_boxes_temporarily(self, metainterp_sd, fail_op):
+ # A bit indirect: when we hit a rop.FAIL, the current values are
+ # stored somewhere in the CPU backend. Below we fetch them and
+ # copy them into the real boxes, i.e. the 'fail_op.args'. We
+ # are in a try:finally path at the end of which, in
+ # restore_patched_boxes(), we can safely undo exactly the
+ # changes done here.
+ cpu = metainterp_sd.cpu
+ patch = []
+ for i in range(len(fail_op.args)):
+ box = fail_op.args[i]
+ patch.append(box.clonebox())
+ if isinstance(box, BoxInt):
+ srcvalue = cpu.get_latest_value_int(i)
+ box.changevalue_int(srcvalue)
+ elif isinstance(box, BoxPtr):
+ srcvalue = cpu.get_latest_value_ptr(i)
+ box.changevalue_ptr(srcvalue)
+ elif cpu.is_oo and isinstance(box, BoxObj):
+ srcvalue = cpu.get_latest_value_obj(i)
+ box.changevalue_obj(srcvalue)
+ else:
+ assert False
+ return patch
+
+ def restore_patched_boxes(self, metainterp_sd, fail_op, patch):
+ for i in range(len(patch)-1, -1, -1):
+ srcbox = patch[i]
+ dstbox = fail_op.args[i]
+ if isinstance(srcbox, BoxInt):
+ srcbox.changevalue_int(dstbox.getint())
+ elif isinstance(srcbox, BoxPtr):
+ srcbox.changevalue_ptr(dstbox.getptr_base())
+ elif metainterp_sd.cpu.is_oo and isinstance(srcbox, BoxObj):
+ srcbox.changevalue_obj(dstbox.getobj())
+ else:
+ assert False
def get_guard_op(self):
guard_op = self.history.operations[self.history_guard_index]
@@ -270,13 +357,13 @@
def prepare_last_operation(new_loop, target_loop):
op = new_loop.operations[-1]
- if target_loop not in map_loop2descr:
+ if not isinstance(target_loop, TerminatingLoop):
# normal case
op.jump_target = target_loop
else:
- # The target_loop is a pseudo-loop done_with_this_frame. Replace
- # the operation with the real operation we want, i.e. a FAIL.
- descr = map_loop2descr[target_loop]
+ # The target_loop is a pseudo-loop, e.g. done_with_this_frame.
+ # Replace the operation with the real operation we want, i.e. a FAIL.
+ descr = target_loop.finishdescr
new_op = ResOperation(rop.FAIL, op.args, None, descr=descr)
new_loop.operations[-1] = new_op
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/history.py Mon Apr 27 12:00:08 2009
@@ -202,6 +202,9 @@
def get_(self):
return self.value
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_int(j, self.value)
+
def equals(self, other):
return self.value == other.getint()
@@ -241,6 +244,9 @@
def get_(self):
return llmemory.cast_adr_to_int(self.value)
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_int(j, self.getint())
+
def equals(self, other):
return self.value == other.getaddr(self.cpu)
@@ -270,6 +276,9 @@
def getaddr(self, cpu):
return llmemory.cast_ptr_to_adr(self.value)
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_ptr(j, self.value)
+
def equals(self, other):
return self.value == other.getptr_base()
@@ -295,11 +304,14 @@
def get_(self):
return ootype.ooidentityhash(self.value) # XXX: check me
- def getaddr(self, cpu):
- # so far this is used only when calling
- # CodeWriter.IndirectCallset.bytecode_for_address. We don't need a
- # real addr, but just a key for the dictionary
- return self.value
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_obj(j, self.value)
+
+## def getaddr(self, cpu):
+## # so far this is used only when calling
+## # CodeWriter.IndirectCallset.bytecode_for_address. We don't need a
+## # real addr, but just a key for the dictionary
+## return self.value
def equals(self, other):
return self.value == other.getobj()
@@ -376,6 +388,9 @@
def get_(self):
return self.value
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_int(j, self.value)
+
def _getrepr_(self):
return self.value
@@ -404,6 +419,9 @@
def get_(self):
return lltype.cast_ptr_to_int(self.value)
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_ptr(j, self.value)
+
_getrepr_ = repr_pointer
changevalue_ptr = __init__
@@ -430,10 +448,17 @@
def get_(self):
return ootype.ooidentityhash(self.value) # XXX: check me
+ def set_future_value(self, cpu, j):
+ cpu.set_future_value_obj(j, self.value)
+
_getrepr_ = repr_object
changevalue_obj = __init__
+def set_future_values(cpu, boxes):
+ for j in range(len(boxes)):
+ boxes[j].set_future_value(cpu, j)
+
# ____________________________________________________________
# The TreeLoop class contains a loop or a generalized loop, i.e. a tree
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py Mon Apr 27 12:00:08 2009
@@ -26,7 +26,8 @@
for arg in args:
assert isinstance(arg, (Box, Const))
-DEBUG = False
+# debug level: 0 off, 1 normal, 2 detailed
+DEBUG = 2
def log(msg):
if not we_are_translated():
@@ -120,6 +121,8 @@
class MIFrame(object):
+ exception_box = None
+ exc_value_box = None
def __init__(self, metainterp, jitcode):
assert isinstance(jitcode, codewriter.JitCode)
@@ -466,7 +469,7 @@
if not we_are_translated():
self.metainterp._debug_history.append(['call',
varargs[0], varargs[1:]])
- return self.execute(rop.CALL, varargs, descr=calldescr)
+ self.execute(rop.CALL, varargs, descr=calldescr)
@arguments("descr", "varargs")
def opimpl_residual_call_pure(self, calldescr, varargs):
@@ -527,7 +530,11 @@
def opimpl_indirect_call(self, pc, indirectcallset, box, varargs):
box = self.implement_guard_value(pc, box)
cpu = self.metainterp.cpu
- jitcode = indirectcallset.bytecode_for_address(box.getaddr(cpu))
+ if cpu.is_oo:
+ key = box.getobj()
+ else:
+ key = box.getaddr(cpu)
+ jitcode = indirectcallset.bytecode_for_address(key)
f = self.metainterp.newframe(jitcode)
f.setup_call(varargs)
return True
@@ -707,6 +714,11 @@
else:
box = consts[~num]
self.env.append(box)
+ if DEBUG:
+ values = [box.get_() for box in self.env]
+ log('setup_resume_at_op %s:%d %s %d' % (self.jitcode.name,
+ self.pc, values,
+ self.exception_target))
def run_one_step(self):
# Execute the frame forward. This method contains a loop that leaves
@@ -804,6 +816,9 @@
self.options = options
self.globaldata = MetaInterpGlobalData()
+ RESULT = portal_graph.getreturnvar().concretetype
+ self.result_type = history.getkind(RESULT)
+
self.opcode_implementations = []
self.opcode_names = []
self.opname_to_index = {}
@@ -861,32 +876,11 @@
# ____________________________________________________________
class MetaInterpGlobalData(object):
-
- blackhole = False
-
def __init__(self):
- self.metainterp_doing_call = None
self._debug_history = []
self.compiled_merge_points = r_dict(history.mp_eq, history.mp_hash)
# { greenkey: list-of-MergePoints }
- def set_metainterp_doing_call(self, metainterp):
- self.save_recursive_call()
- self.metainterp_doing_call = metainterp
-
- def unset_metainterp_doing_call(self, metainterp):
- if self.metainterp_doing_call != metainterp:
- metainterp._restore_recursive_call()
- self.metainterp_doing_call = None
-
- def save_recursive_call(self):
- if self.metainterp_doing_call is not None:
- self.metainterp_doing_call._save_recursive_call()
- self.metainterp_doing_call = None
-
- def assert_empty(self):
- assert self.metainterp_doing_call is None
-
# ____________________________________________________________
class MetaInterp(object):
@@ -914,7 +908,18 @@
else:
if not isinstance(self.history, history.BlackHole):
self.compile_done_with_this_frame(resultbox)
- raise self.staticdata.DoneWithThisFrame(resultbox)
+ sd = self.staticdata
+ if sd.result_type == 'void':
+ assert resultbox is None
+ raise sd.DoneWithThisFrameVoid()
+ elif sd.result_type == 'int':
+ raise sd.DoneWithThisFrameInt(resultbox.getint())
+ elif sd.result_type == 'ptr':
+ raise sd.DoneWithThisFramePtr(resultbox.getptr_base())
+ elif self.cpu.is_oo and sd.result_type == 'obj':
+ raise sd.DoneWithThisFrameObj(resultbox.getobj())
+ else:
+ assert False
def finishframe_exception(self, exceptionbox, excvaluebox):
if we_are_translated(): # detect and propagate AssertionErrors early
@@ -936,7 +941,7 @@
self.framestack.pop()
if not isinstance(self.history, history.BlackHole):
self.compile_exit_frame_with_exception(excvaluebox)
- raise self.staticdata.ExitFrameWithException(excvaluebox)
+ raise self.staticdata.ExitFrameWithException(excvaluebox.getptr_base())
def create_empty_history(self):
self.history = history.History(self.cpu)
@@ -951,9 +956,6 @@
@specialize.arg(1)
def execute_and_record(self, opnum, argboxes, descr=None):
- # detect recursions when using rop.CALL
- if opnum == rop.CALL:
- self.staticdata.globaldata.set_metainterp_doing_call(self)
# execute the operation first
history.check_descr(descr)
resbox = executor.execute(self.cpu, opnum, argboxes, descr)
@@ -969,68 +971,11 @@
resbox = resbox.nonconstbox() # ensure it is a Box
else:
assert resbox is None or isinstance(resbox, Box)
- if opnum == rop.CALL:
- self.staticdata.globaldata.unset_metainterp_doing_call(self)
# record the operation if not constant-folded away
if not canfold:
self.history.record(opnum, argboxes, resbox, descr)
return resbox
- def _save_recursive_call(self):
- # A bit of a hack: we need to be safe against box.changevalue_xxx()
- # called by cpu.execute_operations(), in case we are recursively
- # in another MetaInterp. Temporarily save away the content of the
- # boxes.
- log('recursive call to execute_operations()!')
- saved_env = []
- framestack = []
- for f in self.framestack:
- newenv = []
- for box in f.env:
- if isinstance(box, Box):
- saved_env.append(box.clonebox())
- newenv.append(box)
- framestack.append(newenv)
- pseudoframe = instantiate(MIFrame)
- pseudoframe.env = saved_env
- pseudoframe._saved_framestack = framestack
- self.framestack.append(pseudoframe)
-
- def _restore_recursive_call(self):
- log('recursion detected, restoring state')
- if not we_are_translated():
- assert not hasattr(self.framestack[-1], 'jitcode')
- assert hasattr(self.framestack[-2], 'jitcode')
- pseudoframe = self.framestack.pop()
- saved_env = pseudoframe.env
- i = 0
- assert len(pseudoframe._saved_framestack) == len(self.framestack)
- for j in range(len(self.framestack)):
- f = self.framestack[j]
- pseudoenv = pseudoframe._saved_framestack[j]
- assert len(f.env) == len(pseudoenv)
- for k in range(len(f.env)):
- box = f.env[k]
- if isinstance(box, BoxInt):
- assert isinstance(pseudoenv[k], BoxInt)
- box.changevalue_int(saved_env[i].getint())
- i += 1
- elif isinstance(box, BoxPtr):
- assert isinstance(pseudoenv[k], BoxPtr)
- box.changevalue_ptr(saved_env[i].getptr_base())
- i += 1
- elif isinstance(box, BoxObj):
- assert isinstance(pseudoenv[k], BoxObj)
- box.changevalue_obj(saved_env[i].getobj())
- i += 1
- else:
- if isinstance(box, ConstInt):
- assert box.getint() == pseudoenv[k].getint()
- elif isinstance(box, ConstPtr):
- assert box.getptr_base() == pseudoenv[k].getptr_base()
- assert isinstance(box, Const)
- assert i == len(saved_env)
-
def _interpret(self):
# Execute the frames forward until we raise a DoneWithThisFrame,
# a ContinueRunningNormally, or a GenerateMergePoint exception.
@@ -1147,7 +1092,8 @@
num_green_args = self.staticdata.num_green_args
residual_args = self.get_residual_args(loop,
gmp.argboxes[num_green_args:])
- return (loop, residual_args)
+ history.set_future_values(self.cpu, residual_args)
+ return loop
def prepare_resume_from_failure(self, opnum):
if opnum == rop.GUARD_TRUE: # a goto_if_not that jumps only now
@@ -1187,15 +1133,22 @@
def compile_done_with_this_frame(self, exitbox):
# temporarily put a JUMP to a pseudo-loop
- if exitbox is not None:
- exits = [exitbox]
- if isinstance(exitbox, BoxInt) or isinstance(exitbox, ConstInt):
- loops = compile.loops_done_with_this_frame_int
- else:
- loops = compile.loops_done_with_this_frame_ptr
- else:
+ sd = self.staticdata
+ if sd.result_type == 'void':
+ assert exitbox is None
exits = []
loops = compile.loops_done_with_this_frame_void
+ elif sd.result_type == 'int':
+ exits = [exitbox]
+ loops = compile.loops_done_with_this_frame_int
+ elif sd.result_type == 'ptr':
+ exits = [exitbox]
+ loops = compile.loops_done_with_this_frame_ptr
+ elif sd.cpu.is_oo and sd.result_type == 'obj':
+ exits = [exitbox]
+ loops = compile.loops_done_with_this_frame_obj
+ else:
+ assert False
self.history.record(rop.JUMP, exits, None)
target_loop = compile.compile_new_bridge(self, loops, self.resumekey)
assert target_loop is loops[0]
@@ -1276,14 +1229,14 @@
if suboperations[-1].opnum != rop.FAIL:
must_compile = False
log("ignoring old version of the guard")
- self.history = history.History(self.cpu)
- extra = len(suboperations) - 1
- assert extra >= 0
- for i in range(extra):
- self.history.operations.append(suboperations[i])
- self.extra_rebuild_operations = extra
- else:
- self.staticdata.globaldata.blackhole = True
+ else:
+ self.history = history.History(self.cpu)
+ extra = len(suboperations) - 1
+ assert extra >= 0
+ for i in range(extra):
+ self.history.operations.append(suboperations[i])
+ self.extra_rebuild_operations = extra
+ if not must_compile:
self.history = history.BlackHole(self.cpu)
# the BlackHole is invalid because it doesn't start with
# guard_failure.key.guard_op.suboperations, but that's fine
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/simple_optimize.py Mon Apr 27 12:00:08 2009
@@ -5,6 +5,7 @@
def optimize_loop(options, old_loops, loop, cpu=None):
if old_loops:
+ assert len(old_loops) == 1
return old_loops[0]
else:
newoperations = []
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py Mon Apr 27 12:00:08 2009
@@ -77,14 +77,16 @@
cw.make_one_bytecode(graph_key, False, called_from)
metainterp.staticdata.portal_code = maingraph
metainterp.staticdata.state = FakeWarmRunnerDesc()
- metainterp.staticdata.DoneWithThisFrame = DoneWithThisFrame
+ metainterp.staticdata.DoneWithThisFrameInt = DoneWithThisFrame
+ metainterp.staticdata.DoneWithThisFramePtr = DoneWithThisFrame
+ metainterp.staticdata.DoneWithThisFrameObj = DoneWithThisFrame
self.metainterp = metainterp
try:
metainterp.compile_and_run_once(*args)
except DoneWithThisFrame, e:
#if conftest.option.view:
# metainterp.stats.view()
- return e.args[0].value
+ return e.args[0]
else:
raise Exception("FAILED")
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_loop.py Mon Apr 27 12:00:08 2009
@@ -213,6 +213,45 @@
assert res == expected
self.check_loop_count_at_most(19)
+ def test_interp_many_paths_2(self):
+ myjitdriver = JitDriver(greens = ['i'], reds = ['x', 'node'])
+ NODE = self._get_NODE()
+ bytecode = "xxxxxxxb"
+
+ def can_enter_jit(i, x, node):
+ myjitdriver.can_enter_jit(i=i, x=x, node=node)
+
+ def f(node):
+ x = 0
+ i = 0
+ while i < len(bytecode):
+ myjitdriver.jit_merge_point(i=i, x=x, node=node)
+ op = bytecode[i]
+ if op == 'x':
+ if not node:
+ break
+ if node.value < 100: # a pseudo-random choice
+ x += 1
+ node = node.next
+ elif op == 'b':
+ i = 0
+ can_enter_jit(i, x, node)
+ continue
+ i += 1
+ return x
+
+ node1 = self.nullptr(NODE)
+ for i in range(300):
+ prevnode = self.malloc(NODE)
+ prevnode.value = pow(47, i, 199)
+ prevnode.next = node1
+ node1 = prevnode
+
+ expected = f(node1)
+ res = self.meta_interp(f, [node1])
+ assert res == expected
+ self.check_loop_count_at_most(19)
+
def test_nested_loops(self):
myjitdriver = JitDriver(greens = ['i'], reds = ['x', 'y'])
bytecode = "abc<de"
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_recursive.py Mon Apr 27 12:00:08 2009
@@ -1,6 +1,7 @@
import py
from pypy.rlib.jit import JitDriver
from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.simple_optimize import Optimizer
class RecursiveTests:
@@ -20,7 +21,7 @@
return f(n+1)
else:
return 1
- res = self.meta_interp(main, [20])
+ res = self.meta_interp(main, [20], optimizer=Optimizer)
assert res == main(20)
def test_recursion_three_times(self):
@@ -43,7 +44,7 @@
print
for i in range(1, 11):
print '%3d %9d' % (i, f(i))
- res = self.meta_interp(main, [10])
+ res = self.meta_interp(main, [10], optimizer=Optimizer)
assert res == main(10)
self.check_enter_count_at_most(10)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/warmspot.py Mon Apr 27 12:00:08 2009
@@ -189,8 +189,6 @@
def maybe_enter_jit(*args):
try:
- if self.metainterp_sd.globaldata.blackhole:
- return
state.maybe_compile_and_run(*args)
except JitException:
raise # go through
@@ -206,11 +204,14 @@
args = op.args[2:]
ALLARGS = []
self.green_args_spec = []
+ self.red_args_types = []
for i, v in enumerate(args):
TYPE = v.concretetype
ALLARGS.append(TYPE)
if i < len(self.jitdriver.greens):
self.green_args_spec.append(TYPE)
+ else:
+ self.red_args_types.append(history.getkind(TYPE))
RESTYPE = graph.getreturnvar().concretetype
(self.JIT_ENTER_FUNCTYPE,
self.PTR_JIT_ENTER_FUNCTYPE) = self.ts.get_FuncType(ALLARGS, lltype.Void)
@@ -272,9 +273,9 @@
# except ContinueRunningNormally, e:
# *args = *e.new_args
# except DoneWithThisFrame, e:
- # return e.result
+ # return e.return
# except ExitFrameWithException, e:
- # raise e.type, e.value
+ # raise Exception, e.value
#
# def portal(*args):
# while 1:
@@ -290,17 +291,37 @@
portal_ptr = self.ts.functionptr(PORTALFUNC, 'portal',
graph = portalgraph)
- class DoneWithThisFrame(JitException):
- def __init__(self, resultbox):
- self.resultbox = resultbox
+ class DoneWithThisFrameVoid(JitException):
def __str__(self):
- return 'DoneWithThisFrame(%s)' % (self.resultbox,)
+ return 'DoneWithThisFrameVoid()'
+
+ class DoneWithThisFrameInt(JitException):
+ def __init__(self, result):
+ assert lltype.typeOf(result) is lltype.Signed
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFrameInt(%s)' % (self.result,)
+
+ class DoneWithThisFramePtr(JitException):
+ def __init__(self, result):
+ assert lltype.typeOf(result) == llmemory.GCREF
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFramePtr(%s)' % (self.result,)
+
+ class DoneWithThisFrameObj(JitException):
+ def __init__(self, result):
+ assert ootype.typeOf(result) == ootype.Object
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFrameObj(%s)' % (self.result,)
class ExitFrameWithException(JitException):
- def __init__(self, valuebox):
- self.valuebox = valuebox
+ def __init__(self, value):
+ assert lltype.typeOf(value) == llmemory.GCREF
+ self.value = value
def __str__(self):
- return 'ExitFrameWithException(%s)' % (self.valuebox,)
+ return 'ExitFrameWithException(%s)' % (self.value,)
class ContinueRunningNormally(JitException):
def __init__(self, args):
@@ -310,42 +331,56 @@
return 'ContinueRunningNormally(%s)' % (
', '.join(map(str, self.args)),)
- self.DoneWithThisFrame = DoneWithThisFrame
+ self.DoneWithThisFrameVoid = DoneWithThisFrameVoid
+ self.DoneWithThisFrameInt = DoneWithThisFrameInt
+ self.DoneWithThisFramePtr = DoneWithThisFramePtr
+ self.DoneWithThisFrameObj = DoneWithThisFrameObj
self.ExitFrameWithException = ExitFrameWithException
self.ContinueRunningNormally = ContinueRunningNormally
- self.metainterp_sd.DoneWithThisFrame = DoneWithThisFrame
+ self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid
+ self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt
+ self.metainterp_sd.DoneWithThisFramePtr = DoneWithThisFramePtr
+ self.metainterp_sd.DoneWithThisFrameObj = DoneWithThisFrameObj
self.metainterp_sd.ExitFrameWithException = ExitFrameWithException
self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally
rtyper = self.translator.rtyper
portalfunc_ARGS = unrolling_iterable(list(enumerate(PORTALFUNC.ARGS)))
RESULT = PORTALFUNC.RESULT
+ result_kind = history.getkind(RESULT)
unwrap_exc_value_box = self.metainterp_sd.ts.unwrap_exc_value_box
def ll_portal_runner(*args):
while 1:
try:
- try:
- return support.maybe_on_top_of_llinterp(rtyper,
- portal_ptr)(*args)
- except ContinueRunningNormally, e:
- args = ()
- for i, ARG in portalfunc_ARGS:
- v = unwrap(ARG, e.args[i])
- args = args + (v,)
- except DoneWithThisFrame, e:
- return unwrap(RESULT, e.resultbox)
- except ExitFrameWithException, e:
- value = unwrap_exc_value_box(e.valuebox)
- if not we_are_translated():
- if hasattr(value, 'typeptr'):
- raise LLException(value.typeptr, value)
- else:
- raise LLException(ootype.classof(value), value)
+ return support.maybe_on_top_of_llinterp(rtyper,
+ portal_ptr)(*args)
+ except ContinueRunningNormally, e:
+ args = ()
+ for i, ARG in portalfunc_ARGS:
+ v = unwrap(ARG, e.args[i])
+ args = args + (v,)
+ except DoneWithThisFrameVoid:
+ assert result_kind == 'void'
+ return
+ except DoneWithThisFrameInt, e:
+ assert result_kind == 'int'
+ return lltype.cast_primitive(RESULT, e.result)
+ except DoneWithThisFramePtr, e:
+ assert result_kind == 'ptr'
+ return lltype.cast_opaque_ptr(RESULT, e.result)
+ except DoneWithThisFrameObj, e:
+ assert result_kind == 'obj'
+ return ootype.cast_from_object(RESULT, e.result)
+ except ExitFrameWithException, e:
+ value = unwrap_exc_value_box(e.valuebox)
+ if not we_are_translated():
+ if hasattr(value, 'typeptr'):
+ raise LLException(value.typeptr, value)
else:
- value = cast_base_ptr_to_instance(Exception, value)
- raise Exception, value
- finally:
- self.metainterp_sd.globaldata.blackhole = False
+ raise LLException(ootype.classof(value), value)
+ else:
+ value = cast_base_ptr_to_instance(Exception, value)
+ raise Exception, value
ll_portal_runner._recursive_portal_call_ = True
@@ -416,7 +451,7 @@
warmrunnerdesc.num_green_args = num_green_args
green_args_spec = unrolling_iterable(warmrunnerdesc.green_args_spec)
green_args_names = unrolling_iterable(jitdriver.greens)
- red_args_index = unrolling_iterable(range(len(jitdriver.reds)))
+ red_args_types = unrolling_iterable(warmrunnerdesc.red_args_types)
if num_green_args:
MAX_HASH_TABLE_BITS = 28
else:
@@ -444,24 +479,22 @@
return False
i = i + 1
return True
- def fill_boxes(self, *redargs):
- boxes = self.bridge.inputargs
- for j in red_args_index:
+ def set_future_values(self, cpu, *redargs):
+ j = 0
+ for typecode in red_args_types:
value = redargs[j]
- box = boxes[j]
- TYPE = lltype.typeOf(value)
- if isinstance(TYPE, lltype.Ptr):
- assert isinstance(box, history.BoxPtr)
- box.changevalue_ptr(lltype.cast_opaque_ptr(llmemory.GCREF, value))
- elif isinstance(TYPE, ootype.OOType):
- assert isinstance(box, history.BoxObj)
- box.changevalue_obj(ootype.cast_to_object(value))
- elif TYPE == lltype.Signed:
- assert isinstance(box, history.BoxInt)
- box.changevalue_int(value)
+ if typecode == 'ptr':
+ ptrvalue = lltype.cast_opaque_ptr(llmemory.GCREF, value)
+ cpu.set_future_value_ptr(j, ptrvalue)
+ elif typecode == 'obj':
+ objvalue = ootype.cast_to_object(value)
+ cpu.set_future_value_obj(j, objvalue)
+ elif typecode == 'int':
+ intvalue = lltype.cast_primitive(lltype.Signed, value)
+ cpu.set_future_value_int(j, intvalue)
else:
- raise AssertionError("box is: %s" % (box,))
- return boxes
+ assert False
+ j = j + 1
class WarmEnterState:
def __init__(self):
@@ -508,29 +541,26 @@
#interp.debug_trace("jit_compile", *greenargs)
metainterp_sd = warmrunnerdesc.metainterp_sd
metainterp = MetaInterp(metainterp_sd)
- loop, boxes = metainterp.compile_and_run_once(*args)
+ loop = metainterp.compile_and_run_once(*args)
else:
# machine code was already compiled for these greenargs
# (or we have a hash collision)
assert isinstance(cell, MachineCodeEntryPoint)
if not cell.equalkey(*greenargs):
# hash collision
- loop, boxes = self.handle_hash_collision(cell, argshash,
- *args)
+ loop = self.handle_hash_collision(cell, argshash, *args)
if loop is None:
return
else:
# get the assembler and fill in the boxes
+ cpu = warmrunnerdesc.metainterp_sd.cpu
+ cell.set_future_values(cpu, *args[num_green_args:])
loop = cell.bridge
- boxes = cell.fill_boxes(*args[num_green_args:])
# ---------- execute assembler ----------
- warmrunnerdesc.metainterp_sd.globaldata.save_recursive_call()
while True: # until interrupted by an exception
metainterp_sd = warmrunnerdesc.metainterp_sd
- metainterp_sd.globaldata.assert_empty()
- fail_op = metainterp_sd.cpu.execute_operations(loop, boxes)
- loop, boxes = fail_op.descr.handle_fail_op(metainterp_sd,
- fail_op)
+ fail_op = metainterp_sd.cpu.execute_operations(loop)
+ loop = fail_op.descr.handle_fail_op(metainterp_sd, fail_op)
maybe_compile_and_run._dont_inline_ = True
def handle_hash_collision(self, cell, argshash, *args):
@@ -543,15 +573,16 @@
cell.next = next.next
next.next = self.cells[argshash]
self.cells[argshash] = next
- return (next.bridge,
- next.fill_boxes(*args[num_green_args:]))
+ cpu = warmrunnerdesc.metainterp_sd.cpu
+ next.set_future_values(cpu, *args[num_green_args:])
+ return next.bridge
cell = next
next = cell.next
# not found at all, do profiling
n = next.counter + 1
if n < self.threshold:
cell.next = Counter(n)
- return (None, None)
+ return None
metainterp_sd = warmrunnerdesc.metainterp_sd
metainterp = MetaInterp(metainterp_sd)
return metainterp.compile_and_run_once(*args)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_child.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_child.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_child.py Mon Apr 27 12:00:08 2009
@@ -1,6 +1,7 @@
from pypy.conftest import option
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp import warmspot
+from pypy.jit.metainterp.simple_optimize import Optimizer
from pypy.module.pypyjit.policy import PyPyJitPolicy
# Current output: http://paste.pocoo.org/show/106540/
@@ -34,7 +35,9 @@
interp.heap.malloc_nonmovable = returns_null # XXX
print 'warmspot.jittify_and_run() started...'
+ from pypy.jit.backend.llgraph.runner import LLtypeCPU
policy = PyPyJitPolicy(interp.typer.annotator.translator)
option.view = True
warmspot.jittify_and_run(interp, graph, [], policy=policy,
- listops=True)
+ listops=True, CPUClass=LLtypeCPU,
+ optimizer=Optimizer)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_demo.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_demo.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/tl/pypyjit_demo.py Mon Apr 27 12:00:08 2009
@@ -1,14 +1,10 @@
-def simple_loop():
- print "simple loop"
-
- i = 0
- while i < 100:
- i = i + 3
- print i
- assert i == 102
+def do():
+ import test.regrtest, sys
+ sys.argv = ['regrtest.py', 'test_builtin']
+ test.regrtest.main()
try:
- simple_loop()
+ do()
except Exception, e:
print '/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\'
import sys
More information about the Pypy-commit
mailing list