[pypy-commit] pypy default: Try heuristically to check when running on top of CPython
arigo
noreply at buildbot.pypy.org
Wed Feb 22 18:32:17 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r52763:1c381a211cb1
Date: 2012-02-22 18:23 +0100
http://bitbucket.org/pypy/pypy/changeset/1c381a211cb1/
Log: Try heuristically to check when running on top of CPython that the
arguments of jitdriver.jit_merge_point() have been specified in the
correct order. Unsure that all cases are covered correctly, but
should mostly work.
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -450,6 +450,7 @@
assert v in self.reds
self._alllivevars = dict.fromkeys(
[name for name in self.greens + self.reds if '.' not in name])
+ self._heuristic_order = {} # check if 'reds' and 'greens' are ordered
self._make_extregistryentries()
self.get_jitcell_at = get_jitcell_at
self.set_jitcell_at = set_jitcell_at
@@ -461,13 +462,59 @@
def _freeze_(self):
return True
+ def _check_arguments(self, livevars):
+ assert dict.fromkeys(livevars) == self._alllivevars
+ # check heuristically that 'reds' and 'greens' are ordered as
+ # the JIT will need them to be: first INTs, then REFs, then
+ # FLOATs.
+ if len(self._heuristic_order) < len(livevars):
+ from pypy.rlib.rarithmetic import (r_singlefloat, r_longlong,
+ r_ulonglong)
+ added = False
+ for var, value in livevars.items():
+ if var not in self._heuristic_order:
+ if isinstance(value, (r_longlong, r_ulonglong)):
+ assert 0, ("should not pass a r_longlong argument for "
+ "now, because on 32-bit machines it would "
+ "need to be ordered as a FLOAT")
+ elif isinstance(value, (int, long, r_singlefloat)):
+ kind = '1:INT'
+ elif isinstance(value, float):
+ kind = '3:FLOAT'
+ elif isinstance(value, (str, unicode)) and len(value) != 1:
+ kind = '2:REF'
+ elif isinstance(value, (list, dict)):
+ kind = '2:REF'
+ elif (hasattr(value, '__class__')
+ and value.__class__.__module__ != '__builtin__'):
+ if hasattr(value, '_freeze_'):
+ continue # value._freeze_() is better not called
+ elif getattr(value, '_alloc_flavor_', 'gc') == 'gc':
+ kind = '2:REF'
+ else:
+ kind = '1:INT'
+ else:
+ continue
+ self._heuristic_order[var] = kind
+ added = True
+ if added:
+ for color in ('reds', 'greens'):
+ lst = getattr(self, color)
+ allkinds = [self._heuristic_order.get(name, '?')
+ for name in lst]
+ kinds = [k for k in allkinds if k != '?']
+ assert kinds == sorted(kinds), (
+ "bad order of %s variables in the jitdriver: "
+ "must be INTs, REFs, FLOATs; got %r" %
+ (color, allkinds))
+
def jit_merge_point(_self, **livevars):
# special-cased by ExtRegistryEntry
- assert dict.fromkeys(livevars) == _self._alllivevars
+ _self._check_arguments(livevars)
def can_enter_jit(_self, **livevars):
# special-cased by ExtRegistryEntry
- assert dict.fromkeys(livevars) == _self._alllivevars
+ _self._check_arguments(livevars)
def loop_header(self):
# special-cased by ExtRegistryEntry
diff --git a/pypy/rlib/test/test_jit.py b/pypy/rlib/test/test_jit.py
--- a/pypy/rlib/test/test_jit.py
+++ b/pypy/rlib/test/test_jit.py
@@ -146,6 +146,38 @@
res = self.interpret(f, [-234])
assert res == 1
+ def test_argument_order_ok(self):
+ myjitdriver = JitDriver(greens=['i1', 'r1', 'f1'], reds=[])
+ class A(object):
+ pass
+ myjitdriver.jit_merge_point(i1=42, r1=A(), f1=3.5)
+ # assert did not raise
+
+ def test_argument_order_wrong(self):
+ myjitdriver = JitDriver(greens=['r1', 'i1', 'f1'], reds=[])
+ class A(object):
+ pass
+ e = raises(AssertionError,
+ myjitdriver.jit_merge_point, i1=42, r1=A(), f1=3.5)
+
+ def test_argument_order_more_precision_later(self):
+ myjitdriver = JitDriver(greens=['r1', 'i1', 'r2', 'f1'], reds=[])
+ class A(object):
+ pass
+ myjitdriver.jit_merge_point(i1=42, r1=None, r2=None, f1=3.5)
+ e = raises(AssertionError,
+ myjitdriver.jit_merge_point, i1=42, r1=A(), r2=None, f1=3.5)
+ assert "got ['2:REF', '1:INT', '?', '3:FLOAT']" in repr(e.value)
+
+ def test_argument_order_more_precision_later_2(self):
+ myjitdriver = JitDriver(greens=['r1', 'i1', 'r2', 'f1'], reds=[])
+ class A(object):
+ pass
+ myjitdriver.jit_merge_point(i1=42, r1=None, r2=A(), f1=3.5)
+ e = raises(AssertionError,
+ myjitdriver.jit_merge_point, i1=42, r1=A(), r2=None, f1=3.5)
+ assert "got ['2:REF', '1:INT', '2:REF', '3:FLOAT']" in repr(e.value)
+
class TestJITLLtype(BaseTestJIT, LLRtypeMixin):
pass
More information about the pypy-commit
mailing list