[pypy-svn] pypy out-of-line-guards-2: merge default
fijal
commits-noreply at bitbucket.org
Fri Apr 15 14:05:41 CEST 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: out-of-line-guards-2
Changeset: r43390:58c9e01d357e
Date: 2011-04-15 13:44 +0200
http://bitbucket.org/pypy/pypy/changeset/58c9e01d357e/
Log: merge default
diff --git a/pypy/rlib/rsre/test/test_zjit.py b/pypy/rlib/rsre/test/test_zjit.py
--- a/pypy/rlib/rsre/test/test_zjit.py
+++ b/pypy/rlib/rsre/test/test_zjit.py
@@ -1,5 +1,5 @@
import py
-from pypy.jit.metainterp.test import test_basic
+from pypy.jit.metainterp.test import support
from pypy.rlib.nonconst import NonConstant
from pypy.rlib.rsre.test.test_match import get_code
from pypy.rlib.rsre import rsre_core
@@ -45,7 +45,7 @@
assert m._jit_unroll_safe_
-class TestJitRSre(test_basic.LLJitMixin):
+class TestJitRSre(support.LLJitMixin):
def meta_interp_match(self, pattern, string, repeat=1):
r = get_code(pattern)
diff --git a/pypy/rlib/rfloat.py b/pypy/rlib/rfloat.py
--- a/pypy/rlib/rfloat.py
+++ b/pypy/rlib/rfloat.py
@@ -167,128 +167,132 @@
result = formatd(value, tp, precision, flags)
return result, special
-if USE_SHORT_FLOAT_REPR:
- def round_double(value, ndigits):
- # The basic idea is very simple: convert and round the double to
- # a decimal string using _Py_dg_dtoa, then convert that decimal
- # string back to a double with _Py_dg_strtod. There's one minor
- # difficulty: Python 2.x expects round to do
- # round-half-away-from-zero, while _Py_dg_dtoa does
- # round-half-to-even. So we need some way to detect and correct
- # the halfway cases.
+def round_double(value, ndigits):
+ if USE_SHORT_FLOAT_REPR:
+ return round_double_short_repr(value, ndigits)
+ else:
+ return round_double_fallback_repr(value, ndigits)
- # a halfway value has the form k * 0.5 * 10**-ndigits for some
- # odd integer k. Or in other words, a rational number x is
- # exactly halfway between two multiples of 10**-ndigits if its
- # 2-valuation is exactly -ndigits-1 and its 5-valuation is at
- # least -ndigits. For ndigits >= 0 the latter condition is
- # automatically satisfied for a binary float x, since any such
- # float has nonnegative 5-valuation. For 0 > ndigits >= -22, x
- # needs to be an integral multiple of 5**-ndigits; we can check
- # this using fmod. For -22 > ndigits, there are no halfway
- # cases: 5**23 takes 54 bits to represent exactly, so any odd
- # multiple of 0.5 * 10**n for n >= 23 takes at least 54 bits of
- # precision to represent exactly.
+def round_double_short_repr(value, ndigits):
+ # The basic idea is very simple: convert and round the double to
+ # a decimal string using _Py_dg_dtoa, then convert that decimal
+ # string back to a double with _Py_dg_strtod. There's one minor
+ # difficulty: Python 2.x expects round to do
+ # round-half-away-from-zero, while _Py_dg_dtoa does
+ # round-half-to-even. So we need some way to detect and correct
+ # the halfway cases.
- sign = copysign(1.0, value)
- value = abs(value)
+ # a halfway value has the form k * 0.5 * 10**-ndigits for some
+ # odd integer k. Or in other words, a rational number x is
+ # exactly halfway between two multiples of 10**-ndigits if its
+ # 2-valuation is exactly -ndigits-1 and its 5-valuation is at
+ # least -ndigits. For ndigits >= 0 the latter condition is
+ # automatically satisfied for a binary float x, since any such
+ # float has nonnegative 5-valuation. For 0 > ndigits >= -22, x
+ # needs to be an integral multiple of 5**-ndigits; we can check
+ # this using fmod. For -22 > ndigits, there are no halfway
+ # cases: 5**23 takes 54 bits to represent exactly, so any odd
+ # multiple of 0.5 * 10**n for n >= 23 takes at least 54 bits of
+ # precision to represent exactly.
- # find 2-valuation value
- m, expo = math.frexp(value)
- while m != math.floor(m):
- m *= 2.0
- expo -= 1
+ sign = copysign(1.0, value)
+ value = abs(value)
- # determine whether this is a halfway case.
- halfway_case = 0
- if expo == -ndigits - 1:
- if ndigits >= 0:
+ # find 2-valuation value
+ m, expo = math.frexp(value)
+ while m != math.floor(m):
+ m *= 2.0
+ expo -= 1
+
+ # determine whether this is a halfway case.
+ halfway_case = 0
+ if expo == -ndigits - 1:
+ if ndigits >= 0:
+ halfway_case = 1
+ elif ndigits >= -22:
+ # 22 is the largest k such that 5**k is exactly
+ # representable as a double
+ five_pow = 1.0
+ for i in range(-ndigits):
+ five_pow *= 5.0
+ if math.fmod(value, five_pow) == 0.0:
halfway_case = 1
- elif ndigits >= -22:
- # 22 is the largest k such that 5**k is exactly
- # representable as a double
- five_pow = 1.0
- for i in range(-ndigits):
- five_pow *= 5.0
- if math.fmod(value, five_pow) == 0.0:
- halfway_case = 1
- # round to a decimal string; use an extra place for halfway case
- strvalue = formatd(value, 'f', ndigits + halfway_case)
+ # round to a decimal string; use an extra place for halfway case
+ strvalue = formatd(value, 'f', ndigits + halfway_case)
- if halfway_case:
- buf = [c for c in strvalue]
- if ndigits >= 0:
- endpos = len(buf) - 1
- else:
- endpos = len(buf) + ndigits
- # Sanity checks: there should be exactly ndigits+1 places
- # following the decimal point, and the last digit in the
- # buffer should be a '5'
- if not objectmodel.we_are_translated():
- assert buf[endpos] == '5'
- if '.' in buf:
- assert endpos == len(buf) - 1
- assert buf.index('.') == len(buf) - ndigits - 2
+ if halfway_case:
+ buf = [c for c in strvalue]
+ if ndigits >= 0:
+ endpos = len(buf) - 1
+ else:
+ endpos = len(buf) + ndigits
+ # Sanity checks: there should be exactly ndigits+1 places
+ # following the decimal point, and the last digit in the
+ # buffer should be a '5'
+ if not objectmodel.we_are_translated():
+ assert buf[endpos] == '5'
+ if '.' in buf:
+ assert endpos == len(buf) - 1
+ assert buf.index('.') == len(buf) - ndigits - 2
- # increment and shift right at the same time
- i = endpos - 1
- carry = 1
- while i >= 0:
+ # increment and shift right at the same time
+ i = endpos - 1
+ carry = 1
+ while i >= 0:
+ digit = ord(buf[i])
+ if digit == ord('.'):
+ buf[i+1] = chr(digit)
+ i -= 1
digit = ord(buf[i])
- if digit == ord('.'):
- buf[i+1] = chr(digit)
- i -= 1
- digit = ord(buf[i])
- carry += digit - ord('0')
- buf[i+1] = chr(carry % 10 + ord('0'))
- carry /= 10
- i -= 1
- buf[0] = chr(carry + ord('0'))
- if ndigits < 0:
- buf.append('0')
+ carry += digit - ord('0')
+ buf[i+1] = chr(carry % 10 + ord('0'))
+ carry /= 10
+ i -= 1
+ buf[0] = chr(carry + ord('0'))
+ if ndigits < 0:
+ buf.append('0')
- strvalue = ''.join(buf)
+ strvalue = ''.join(buf)
- return sign * rstring_to_float(strvalue)
+ return sign * rstring_to_float(strvalue)
-else:
- # fallback version, to be used when correctly rounded
- # binary<->decimal conversions aren't available
- def round_double(value, ndigits):
- if ndigits >= 0:
- if ndigits > 22:
- # pow1 and pow2 are each safe from overflow, but
- # pow1*pow2 ~= pow(10.0, ndigits) might overflow
- pow1 = math.pow(10.0, ndigits - 22)
- pow2 = 1e22
- else:
- pow1 = math.pow(10.0, ndigits)
- pow2 = 1.0
+# fallback version, to be used when correctly rounded
+# binary<->decimal conversions aren't available
+def round_double_fallback_repr(value, ndigits):
+ if ndigits >= 0:
+ if ndigits > 22:
+ # pow1 and pow2 are each safe from overflow, but
+ # pow1*pow2 ~= pow(10.0, ndigits) might overflow
+ pow1 = math.pow(10.0, ndigits - 22)
+ pow2 = 1e22
+ else:
+ pow1 = math.pow(10.0, ndigits)
+ pow2 = 1.0
- y = (value * pow1) * pow2
- # if y overflows, then rounded value is exactly x
- if isinf(y):
- return value
+ y = (value * pow1) * pow2
+ # if y overflows, then rounded value is exactly x
+ if isinf(y):
+ return value
- else:
- pow1 = math.pow(10.0, -ndigits);
- pow2 = 1.0 # unused; for translation
- y = value / pow1
+ else:
+ pow1 = math.pow(10.0, -ndigits);
+ pow2 = 1.0 # unused; for translation
+ y = value / pow1
- if y >= 0.0:
- z = math.floor(y + 0.5)
- else:
- z = math.ceil(y - 0.5)
- if math.fabs(y-z) == 1.0: # obscure case, see the test
- z = y
+ if y >= 0.0:
+ z = math.floor(y + 0.5)
+ else:
+ z = math.ceil(y - 0.5)
+ if math.fabs(y-z) == 1.0: # obscure case, see the test
+ z = y
- if ndigits >= 0:
- z = (z / pow2) / pow1
- else:
- z *= pow1
- return z
+ if ndigits >= 0:
+ z = (z / pow2) / pow1
+ else:
+ z *= pow1
+ return z
INFINITY = 1e200 * 1e200
NAN = INFINITY / INFINITY
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -119,13 +119,16 @@
Impara, Germany
Change Maker, Sweden
+The PyPy Logo as used by http://speed.pypy.org and others was created
+by Samuel Reis and is distributed on terms of Creative Commons Share Alike
+License.
-License for 'lib-python/2.5.2' and 'lib-python/2.5.2-modified'
+License for 'lib-python/2.7.0' and 'lib-python/2.7.0-modified'
==============================================================
Except when otherwise stated (look for LICENSE files or
copyright/license information at the beginning of each file) the files
-in the 'lib-python/2.5.2' and 'lib-python/2.5.2-modified' directories
+in the 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' directories
are all copyrighted by the Python Software Foundation and licensed under
the Python Software License of which you can find a copy here:
http://www.python.org/doc/Copyright.html
@@ -158,21 +161,12 @@
======================================
The following files are from the website of The Unicode Consortium
-at http://www.unicode.org/. For the terms of use of these files, see
-http://www.unicode.org/terms_of_use.html
+at http://www.unicode.org/. For the terms of use of these files, see
+http://www.unicode.org/terms_of_use.html . Or they are derived from
+files from the above website, and the same terms of use apply.
- CompositionExclusions-3.2.0.txt
- CompositionExclusions-4.1.0.txt
- CompositionExclusions-5.0.0.txt
- EastAsianWidth-3.2.0.txt
- EastAsianWidth-4.1.0.txt
- EastAsianWidth-5.0.0.txt
- UnicodeData-3.2.0.txt
- UnicodeData-4.1.0.txt
- UnicodeData-5.0.0.txt
-
-The following files are derived from files from the above website. The same
-terms of use apply.
- UnihanNumeric-3.2.0.txt
- UnihanNumeric-4.1.0.txt
- UnihanNumeric-5.0.0.txt
+ CompositionExclusions-*.txt
+ EastAsianWidth-*.txt
+ LineBreak-*.txt
+ UnicodeData-*.txt
+ UnihanNumeric-*.txt
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -1,6 +1,6 @@
import py
from pypy.rlib.jit import JitDriver
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class ListTests:
diff --git a/pypy/jit/metainterp/test/test_basic.py b/pypy/jit/metainterp/test/test_ajit.py
copy from pypy/jit/metainterp/test/test_basic.py
copy to pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_basic.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -4,269 +4,17 @@
from pypy.rlib.jit import loop_invariant
from pypy.rlib.jit import jit_debug, assert_green, AssertGreenFailed
from pypy.rlib.jit import unroll_safe, current_trace_length
-from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
-from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp import pyjitpl, history
from pypy.jit.metainterp.warmstate import set_future_value
+from pypy.jit.metainterp.warmspot import get_stats
from pypy.jit.codewriter.policy import JitPolicy, StopAtXPolicy
-from pypy.jit.codewriter import longlong
from pypy import conftest
from pypy.rlib.rarithmetic import ovfcheck
from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT
-
-def _get_jitcodes(testself, CPUClass, func, values, type_system,
- supports_longlong=False, **kwds):
- from pypy.jit.codewriter import support, codewriter
-
- class FakeJitCell:
- __compiled_merge_points = []
- def get_compiled_merge_points(self):
- return self.__compiled_merge_points[:]
- def set_compiled_merge_points(self, lst):
- self.__compiled_merge_points = lst
-
- class FakeWarmRunnerState:
- def attach_unoptimized_bridge_from_interp(self, greenkey, newloop):
- pass
-
- def jit_cell_at_key(self, greenkey):
- assert greenkey == []
- return self._cell
- _cell = FakeJitCell()
-
- trace_limit = sys.maxint
- enable_opts = ALL_OPTS_DICT
-
- func._jit_unroll_safe_ = True
- rtyper = support.annotate(func, values, type_system=type_system)
- graphs = rtyper.annotator.translator.graphs
- result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]
-
- class FakeJitDriverSD:
- num_green_args = 0
- portal_graph = graphs[0]
- virtualizable_info = None
- greenfield_info = None
- result_type = result_kind
- portal_runner_ptr = "???"
-
- stats = history.Stats()
- cpu = CPUClass(rtyper, stats, None, False)
- cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
- testself.cw = cw
- policy = JitPolicy()
- policy.set_supports_longlong(supports_longlong)
- cw.find_all_graphs(policy)
- #
- testself.warmrunnerstate = FakeWarmRunnerState()
- testself.warmrunnerstate.cpu = cpu
- FakeJitDriverSD.warmstate = testself.warmrunnerstate
- if hasattr(testself, 'finish_setup_for_interp_operations'):
- testself.finish_setup_for_interp_operations()
- #
- cw.make_jitcodes(verbose=True)
-
-def _run_with_blackhole(testself, args):
- from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
- cw = testself.cw
- blackholeinterpbuilder = BlackholeInterpBuilder(cw)
- blackholeinterp = blackholeinterpbuilder.acquire_interp()
- count_i = count_r = count_f = 0
- for value in args:
- T = lltype.typeOf(value)
- if T == lltype.Signed:
- blackholeinterp.setarg_i(count_i, value)
- count_i += 1
- elif T == llmemory.GCREF:
- blackholeinterp.setarg_r(count_r, value)
- count_r += 1
- elif T == lltype.Float:
- value = longlong.getfloatstorage(value)
- blackholeinterp.setarg_f(count_f, value)
- count_f += 1
- else:
- raise TypeError(T)
- [jitdriver_sd] = cw.callcontrol.jitdrivers_sd
- blackholeinterp.setposition(jitdriver_sd.mainjitcode, 0)
- blackholeinterp.run()
- return blackholeinterp._final_result_anytype()
-
-def _run_with_pyjitpl(testself, args):
-
- class DoneWithThisFrame(Exception):
- pass
-
- class DoneWithThisFrameRef(DoneWithThisFrame):
- def __init__(self, cpu, *args):
- DoneWithThisFrame.__init__(self, *args)
-
- cw = testself.cw
- opt = history.Options(listops=True)
- metainterp_sd = pyjitpl.MetaInterpStaticData(cw.cpu, opt)
- metainterp_sd.finish_setup(cw)
- [jitdriver_sd] = metainterp_sd.jitdrivers_sd
- metainterp = pyjitpl.MetaInterp(metainterp_sd, jitdriver_sd)
- metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrame
- metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef
- metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrame
- testself.metainterp = metainterp
- try:
- metainterp.compile_and_run_once(jitdriver_sd, *args)
- except DoneWithThisFrame, e:
- #if conftest.option.view:
- # metainterp.stats.view()
- return e.args[0]
- else:
- raise Exception("FAILED")
-
-def _run_with_machine_code(testself, args):
- metainterp = testself.metainterp
- num_green_args = metainterp.jitdriver_sd.num_green_args
- loop_tokens = metainterp.get_compiled_merge_points(args[:num_green_args])
- if len(loop_tokens) != 1:
- return NotImplemented
- # a loop was successfully created by _run_with_pyjitpl(); call it
- cpu = metainterp.cpu
- for i in range(len(args) - num_green_args):
- x = args[num_green_args + i]
- typecode = history.getkind(lltype.typeOf(x))
- set_future_value(cpu, i, x, typecode)
- faildescr = cpu.execute_token(loop_tokens[0])
- assert faildescr.__class__.__name__.startswith('DoneWithThisFrameDescr')
- if metainterp.jitdriver_sd.result_type == history.INT:
- return cpu.get_latest_value_int(0)
- elif metainterp.jitdriver_sd.result_type == history.REF:
- return cpu.get_latest_value_ref(0)
- elif metainterp.jitdriver_sd.result_type == history.FLOAT:
- return cpu.get_latest_value_float(0)
- else:
- return None
-
-
-class JitMixin:
- basic = True
- def check_loops(self, expected=None, everywhere=False, **check):
- get_stats().check_loops(expected=expected, everywhere=everywhere,
- **check)
- def check_loop_count(self, count):
- """NB. This is a hack; use check_tree_loop_count() or
- check_enter_count() for the real thing.
- This counts as 1 every bridge in addition to every loop; and it does
- not count at all the entry bridges from interpreter, although they
- are TreeLoops as well."""
- assert get_stats().compiled_count == count
- def check_tree_loop_count(self, count):
- assert len(get_stats().loops) == count
- def check_loop_count_at_most(self, count):
- assert get_stats().compiled_count <= count
- def check_enter_count(self, count):
- assert get_stats().enter_count == count
- def check_enter_count_at_most(self, count):
- assert get_stats().enter_count <= count
- def check_jumps(self, maxcount):
- assert get_stats().exec_jumps <= maxcount
- def check_aborted_count(self, count):
- assert get_stats().aborted_count == count
- def check_aborted_count_at_least(self, count):
- assert get_stats().aborted_count >= count
-
- def meta_interp(self, *args, **kwds):
- kwds['CPUClass'] = self.CPUClass
- kwds['type_system'] = self.type_system
- if "backendopt" not in kwds:
- kwds["backendopt"] = False
- return ll_meta_interp(*args, **kwds)
-
- def interp_operations(self, f, args, **kwds):
- # get the JitCodes for the function f
- _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
- # try to run it with blackhole.py
- result1 = _run_with_blackhole(self, args)
- # try to run it with pyjitpl.py
- result2 = _run_with_pyjitpl(self, args)
- assert result1 == result2
- # try to run it by running the code compiled just before
- result3 = _run_with_machine_code(self, args)
- assert result1 == result3 or result3 == NotImplemented
- #
- if (longlong.supports_longlong and
- isinstance(result1, longlong.r_float_storage)):
- result1 = longlong.getrealfloat(result1)
- return result1
-
- def check_history(self, expected=None, **isns):
- # this can be used after calling meta_interp
- get_stats().check_history(expected, **isns)
-
- def check_operations_history(self, expected=None, **isns):
- # this can be used after interp_operations
- if expected is not None:
- expected = dict(expected)
- expected['jump'] = 1
- self.metainterp.staticdata.stats.check_history(expected, **isns)
-
-
-class LLJitMixin(JitMixin):
- type_system = 'lltype'
- CPUClass = runner.LLtypeCPU
-
- @staticmethod
- def Ptr(T):
- return lltype.Ptr(T)
-
- @staticmethod
- def GcStruct(name, *fields, **kwds):
- S = lltype.GcStruct(name, *fields, **kwds)
- return S
-
- malloc = staticmethod(lltype.malloc)
- nullptr = staticmethod(lltype.nullptr)
-
- @staticmethod
- def malloc_immortal(T):
- return lltype.malloc(T, immortal=True)
-
- def _get_NODE(self):
- NODE = lltype.GcForwardReference()
- NODE.become(lltype.GcStruct('NODE', ('value', lltype.Signed),
- ('next', lltype.Ptr(NODE))))
- return NODE
-
-class OOJitMixin(JitMixin):
- type_system = 'ootype'
- #CPUClass = runner.OOtypeCPU
-
- def setup_class(cls):
- py.test.skip("ootype tests skipped for now")
-
- @staticmethod
- def Ptr(T):
- return T
-
- @staticmethod
- def GcStruct(name, *fields, **kwds):
- if 'hints' in kwds:
- kwds['_hints'] = kwds['hints']
- del kwds['hints']
- I = ootype.Instance(name, ootype.ROOT, dict(fields), **kwds)
- return I
-
- malloc = staticmethod(ootype.new)
- nullptr = staticmethod(ootype.null)
-
- @staticmethod
- def malloc_immortal(T):
- return ootype.new(T)
-
- def _get_NODE(self):
- NODE = ootype.Instance('NODE', ootype.ROOT, {})
- NODE._add_fields({'value': ootype.Signed,
- 'next': NODE})
- return NODE
-
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class BasicTests:
diff --git a/pypy/translator/jvm/typesystem.py b/pypy/translator/jvm/typesystem.py
--- a/pypy/translator/jvm/typesystem.py
+++ b/pypy/translator/jvm/typesystem.py
@@ -181,6 +181,7 @@
jIntegerClass = JvmClassType('java.lang.Integer')
jLongClass = JvmClassType('java.lang.Long')
+jShortClass = JvmClassType('java.lang.Short')
jDoubleClass = JvmClassType('java.lang.Double')
jByteClass = JvmClassType('java.lang.Byte')
jCharClass = JvmClassType('java.lang.Character')
@@ -239,6 +240,7 @@
jDouble = JvmScalarType('D', jDoubleClass, 'doubleValue')
jByte = JvmScalarType('B', jByteClass, 'byteValue')
jChar = JvmScalarType('C', jCharClass, 'charValue')
+jShort = JvmScalarType('S', jShortClass, 'shortValue')
class Generifier(object):
@@ -527,6 +529,7 @@
if desc == 'C': return self._o("i") # Characters
if desc == 'B': return self._o("i") # Bytes
if desc == 'Z': return self._o("i") # Boolean
+ if desc == 'S': return self._o("i") # Short
assert False, "Unknown argtype=%s" % repr(argtype)
raise NotImplementedError
@@ -625,6 +628,7 @@
NOP = Opcode('nop')
I2D = Opcode('i2d')
I2L = Opcode('i2l')
+I2S = Opcode('i2s')
D2I= Opcode('d2i')
#D2L= Opcode('d2l') #PAUL
L2I = Opcode('l2i')
@@ -891,6 +895,7 @@
SYSTEMIDENTITYHASH = Method.s(jSystem, 'identityHashCode', (jObject,), jInt)
SYSTEMGC = Method.s(jSystem, 'gc', (), jVoid)
INTTOSTRINGI = Method.s(jIntegerClass, 'toString', (jInt,), jString)
+SHORTTOSTRINGS = Method.s(jShortClass, 'toString', (jShort,), jString)
LONGTOSTRINGL = Method.s(jLongClass, 'toString', (jLong,), jString)
DOUBLETOSTRINGD = Method.s(jDoubleClass, 'toString', (jDouble,), jString)
CHARTOSTRINGC = Method.s(jCharClass, 'toString', (jChar,), jString)
@@ -922,15 +927,19 @@
CLASSISASSIGNABLEFROM = Method.v(jClass, 'isAssignableFrom', (jClass,), jBool)
STRINGBUILDERAPPEND = Method.v(jStringBuilder, 'append',
(jString,), jStringBuilder)
+PYPYINTBETWEEN = Method.s(jPyPy, 'int_between', (jInt,jInt,jInt), jBool)
PYPYUINTCMP = Method.s(jPyPy, 'uint_cmp', (jInt,jInt,), jInt)
PYPYULONGCMP = Method.s(jPyPy, 'ulong_cmp', (jLong,jLong), jInt)
PYPYUINTMOD = Method.v(jPyPy, 'uint_mod', (jInt, jInt), jInt)
PYPYUINTMUL = Method.v(jPyPy, 'uint_mul', (jInt, jInt), jInt)
PYPYUINTDIV = Method.v(jPyPy, 'uint_div', (jInt, jInt), jInt)
PYPYULONGMOD = Method.v(jPyPy, 'ulong_mod', (jLong, jLong), jLong)
+PYPYUINTTOLONG = Method.s(jPyPy, 'uint_to_long', (jInt,), jLong)
PYPYUINTTODOUBLE = Method.s(jPyPy, 'uint_to_double', (jInt,), jDouble)
PYPYDOUBLETOUINT = Method.s(jPyPy, 'double_to_uint', (jDouble,), jInt)
PYPYDOUBLETOLONG = Method.v(jPyPy, 'double_to_long', (jDouble,), jLong) #PAUL
+PYPYDOUBLETOULONG = Method.s(jPyPy, 'double_to_ulong', (jDouble,), jLong)
+PYPYULONGTODOUBLE = Method.s(jPyPy, 'ulong_to_double', (jLong,), jDouble)
PYPYLONGBITWISENEGATE = Method.v(jPyPy, 'long_bitwise_negate', (jLong,), jLong)
PYPYSTRTOINT = Method.v(jPyPy, 'str_to_int', (jString,), jInt)
PYPYSTRTOUINT = Method.v(jPyPy, 'str_to_uint', (jString,), jInt)
diff --git a/pypy/jit/tl/pypyjit_demo.py b/pypy/jit/tl/pypyjit_demo.py
--- a/pypy/jit/tl/pypyjit_demo.py
+++ b/pypy/jit/tl/pypyjit_demo.py
@@ -1,19 +1,16 @@
try:
- import pypyjit
- pypyjit.set_param(threshold=3, inlining=True)
+ def main(n):
+ def g(n):
+ return range(n)
+ s = 0
+ for i in range(n): # ID: for
+ tmp = g(n)
+ s += tmp[i] # ID: getitem
+ a = 0
+ return s
+ main(10)
- def sqrt(y, n=10000):
- x = y / 2
- while n > 0:
- #assert y > 0 and x > 0
- if y > 0 and x > 0: pass
- n -= 1
- x = (x + y/x) / 2
- return x
-
- print sqrt(1234, 4)
-
except Exception, e:
print "Exception: ", type(e)
print e
diff --git a/pypy/translator/jvm/database.py b/pypy/translator/jvm/database.py
--- a/pypy/translator/jvm/database.py
+++ b/pypy/translator/jvm/database.py
@@ -4,7 +4,7 @@
"""
from cStringIO import StringIO
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython.ootypesystem import ootype, rclass
from pypy.rpython.ootypesystem.module import ll_os
from pypy.translator.jvm import node, methods
@@ -229,9 +229,15 @@
if not ootype.isSubclass(OOTYPE, SELF): continue
mobj = self._function_for_graph(
clsobj, mname, False, mimpl.graph)
- graphs = OOTYPE._lookup_graphs(mname)
- if len(graphs) == 1:
- mobj.is_final = True
+ # XXX: this logic is broken: it might happen that there are
+ # ootype.Instance which contains a meth whose graph is exactly
+ # the same as the meth in the superclass: in this case,
+ # len(graphs) == 1 but we cannot just mark the method as final
+ # (or we can, but we should avoid to emit the method in the
+ # subclass, then)
+ ## graphs = OOTYPE._lookup_graphs(mname)
+ ## if len(graphs) == 1:
+ ## mobj.is_final = True
clsobj.add_method(mobj)
# currently, we always include a special "dump" method for debugging
@@ -359,6 +365,7 @@
ootype.UniChar:jvm.PYPYESCAPEDUNICHAR,
ootype.String:jvm.PYPYESCAPEDSTRING,
ootype.Unicode:jvm.PYPYESCAPEDUNICODE,
+ rffi.SHORT:jvm.SHORTTOSTRINGS,
}
def toString_method_for_ootype(self, OOTYPE):
@@ -406,6 +413,7 @@
ootype.UniChar: jvm.jChar,
ootype.Class: jvm.jClass,
ootype.ROOT: jvm.jObject, # treat like a scalar
+ rffi.SHORT: jvm.jShort,
}
# Dictionary for non-scalar types; in this case, if we see the key, we
diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -6,7 +6,7 @@
from pypy.jit.codewriter import heaptracker
from pypy.rlib.jit import JitDriver, hint, dont_look_inside
from pypy.rlib.rarithmetic import intmask
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rpython.rclass import FieldListAccessor
from pypy.jit.metainterp.warmspot import get_stats, get_translator
from pypy.jit.metainterp import history
diff --git a/pypy/jit/metainterp/test/test_longlong.py b/pypy/jit/metainterp/test/test_longlong.py
--- a/pypy/jit/metainterp/test/test_longlong.py
+++ b/pypy/jit/metainterp/test/test_longlong.py
@@ -1,6 +1,6 @@
import py, sys
from pypy.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin
class WrongResult(Exception):
pass
diff --git a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
--- a/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_pypy_c_new.py
@@ -277,6 +277,7 @@
""")
def test_default_and_kw(self):
+ py.test.skip("Wait until we have saner defaults strat")
def main(n):
def f(i, j=1):
return i + j
@@ -539,7 +540,7 @@
i12 = int_sub_ovf(i3, 1)
guard_no_overflow(descr=<Guard5>)
--TICK--
- jump(p0, p1, p2, i12, p4, descr=<Loop0>)
+ jump(p0, p1, p2, i12, descr=<Loop0>)
""")
def test_exception_inside_loop_2(self):
@@ -585,7 +586,7 @@
--EXC-TICK--
i14 = int_add(i4, 1)
--TICK--
- jump(p0, p1, p2, p3, i14, i5, p6, descr=<Loop0>)
+ jump(p0, p1, p2, p3, i14, i5, descr=<Loop0>)
""")
def test_chain_of_guards(self):
@@ -685,13 +686,13 @@
assert log.result == 500
loop, = log.loops_by_id('import')
assert loop.match_by_id('import', """
- p14 = call(ConstClass(ll_split_chr__GcStruct_listLlT_rpy_stringPtr_Char), p8, 46, -1, descr=<GcPtrCallDescr>)
+ p14 = call(ConstClass(ll_split_chr), p8, 46, -1, descr=<GcPtrCallDescr>)
guard_no_exception(descr=<Guard4>)
guard_nonnull(p14, descr=<Guard5>)
i15 = getfield_gc(p14, descr=<SignedFieldDescr list.length .*>)
i16 = int_is_true(i15)
guard_true(i16, descr=<Guard6>)
- p18 = call(ConstClass(ll_pop_default__dum_nocheckConst_listPtr), p14, descr=<GcPtrCallDescr>)
+ p18 = call(ConstClass(ll_pop_default), p14, descr=<GcPtrCallDescr>)
guard_no_exception(descr=<Guard7>)
i19 = getfield_gc(p14, descr=<SignedFieldDescr list.length .*>)
i20 = int_is_true(i19)
@@ -1009,6 +1010,7 @@
""")
def test_func_defaults(self):
+ py.test.skip("until we fix defaults")
def main(n):
i = 1
while i < n:
@@ -1061,7 +1063,7 @@
i23 = int_lt(0, i21)
guard_true(i23, descr=<Guard5>)
i24 = getfield_gc(p17, descr=<NonGcPtrFieldDescr .*W_ArrayTypei.inst_buffer .*>)
- i25 = getarrayitem_raw(i24, 0, descr=<SignedArrayNoLengthDescr>)
+ i25 = getarrayitem_raw(i24, 0, descr=<.*>)
i27 = int_lt(1, i21)
guard_false(i27, descr=<Guard6>)
i28 = int_add_ovf(i10, i25)
diff --git a/pypy/jit/metainterp/test/test_dlist.py b/pypy/jit/metainterp/test/test_dlist.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_dlist.py
+++ /dev/null
@@ -1,165 +0,0 @@
-
-import py
-from pypy.rlib.jit import JitDriver
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
-py.test.skip("Disabled")
-
-class ListTests:
- def test_basic(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
- def f(n):
- l = [0]
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- x = l[0]
- l[0] = x + 1
- n -= 1
- return l[0]
-
- res = self.meta_interp(f, [10], listops=True)
- assert res == f(10)
- self.check_loops(getarrayitem_gc=0, setarrayitem_gc=1)
-# XXX fix codewriter
-# guard_exception=0,
-# guard_no_exception=1)
-
- def test_list_escapes(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
- def f(n):
- l = [0] * (n + 1)
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- x = l[0]
- l[0] = x + 1
- l[n] = n
- n -= 1
- return l[3]
-
- res = self.meta_interp(f, [10], listops=True)
- assert res == f(10)
- self.check_loops(setarrayitem_gc=2, getarrayitem_gc=0)
-
- def test_list_escapes_but_getitem_goes(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
- def f(n):
- l = [0] * (n + 1)
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- x = l[0]
- l[0] = x + 1
- l[n] = n
- x = l[2]
- y = l[1] + l[2]
- l[1] = x + y
- n -= 1
- return l[3]
-
- res = self.meta_interp(f, [10], listops=True)
- assert res == f(10)
- self.check_loops(setarrayitem_gc=3, getarrayitem_gc=0)
-
- def test_list_of_ptrs(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
- class A(object):
- def __init__(self, x):
- self.x = x
-
- def f(n):
- l = [A(3)]
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- x = l[0].x + 1
- l[0] = A(x)
- n -= 1
- return l[0].x
-
- res = self.meta_interp(f, [10], listops=True)
- assert res == f(10)
- self.check_loops(setarrayitem_gc=1, getarrayitem_gc=0,
- new_with_vtable=1) # A should escape
-
- def test_list_checklength(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
-
- def f(n, a):
- l = [0] * a
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- if len(l) < 3:
- return 42
- l[0] = n
- n -= 1
- return l[0]
-
- res = self.meta_interp(f, [10, 13], listops=True)
- assert res == f(10, 13)
- self.check_loops(setarrayitem_gc=1, arraylen_gc=1)
-
- def test_list_checklength_run(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
-
- def f(n, a):
- l = [0] * a
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- if len(l) > n:
- return 42
- l[0] = n
- n -= 1
- return l[0]
-
- res = self.meta_interp(f, [50, 13], listops=True)
- assert res == 42
- self.check_loops(setarrayitem_gc=1, arraylen_gc=1)
-
- def test_checklength_cannot_go_away(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
-
- def f(n):
- l = [0] * n
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- if len(l) < 3:
- return len(l)
- l = [0] * n
- n -= 1
- return 0
-
- res = self.meta_interp(f, [10], listops=True)
- assert res == 2
- self.check_loops(arraylen_gc=1)
-
- def test_list_indexerror(self):
- # this is an example where IndexError is raised before
- # even getting to the JIT
- py.test.skip("I suspect bug somewhere outside of the JIT")
- myjitdriver = JitDriver(greens = [], reds = ['n', 'l'])
- def f(n):
- l = [0]
- while n > 0:
- myjitdriver.can_enter_jit(n=n, l=l)
- myjitdriver.jit_merge_point(n=n, l=l)
- l[n] = n
- n -= 1
- return l[3]
-
- def g(n):
- try:
- f(n)
- return 0
- except IndexError:
- return 42
-
- res = self.meta_interp(g, [10])
- assert res == 42
- self.check_loops(setitem=2)
-
-class TestLLtype(ListTests, LLJitMixin):
- pass
diff --git a/pypy/tool/jitlogparser/module_finder.py b/pypy/tool/jitlogparser/module_finder.py
--- a/pypy/tool/jitlogparser/module_finder.py
+++ b/pypy/tool/jitlogparser/module_finder.py
@@ -6,7 +6,7 @@
more = [code]
while more:
next = more.pop()
- res[next.co_firstlineno] = next
+ res[(next.co_firstlineno, next.co_name)] = next
more += [co for co in next.co_consts
if isinstance(co, types.CodeType)]
return res
diff --git a/pypy/jit/metainterp/test/test_jitdriver.py b/pypy/jit/metainterp/test/test_jitdriver.py
--- a/pypy/jit/metainterp/test/test_jitdriver.py
+++ b/pypy/jit/metainterp/test/test_jitdriver.py
@@ -1,6 +1,6 @@
"""Tests for multiple JitDrivers."""
from pypy.rlib.jit import JitDriver, unroll_safe
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.warmspot import get_stats
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -2757,7 +2757,7 @@
"""
self.optimize_loop(ops, expected)
- def test_fold_partially_constant_ops(self):
+ def test_fold_partially_constant_add_sub(self):
ops = """
[i0]
i1 = int_sub(i0, 0)
@@ -2791,7 +2791,7 @@
"""
self.optimize_loop(ops, expected)
- def test_fold_partially_constant_ops_ovf(self):
+ def test_fold_partially_constant_add_sub_ovf(self):
ops = """
[i0]
i1 = int_sub_ovf(i0, 0)
@@ -2828,6 +2828,21 @@
"""
self.optimize_loop(ops, expected)
+ def test_fold_partially_constant_shift(self):
+ ops = """
+ [i0]
+ i1 = int_lshift(i0, 0)
+ i2 = int_rshift(i1, 0)
+ i3 = int_eq(i2, i0)
+ guard_true(i3) []
+ jump(i2)
+ """
+ expected = """
+ [i0]
+ jump(i0)
+ """
+ self.optimize_loop(ops, expected)
+
# ----------
class TestLLtype(OptimizeOptTest, LLtypeMixin):
diff --git a/pypy/jit/metainterp/test/test_send.py b/pypy/jit/metainterp/test/test_send.py
--- a/pypy/jit/metainterp/test/test_send.py
+++ b/pypy/jit/metainterp/test/test_send.py
@@ -1,7 +1,7 @@
import py
from pypy.rlib.jit import JitDriver, hint, purefunction
from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class SendTests(object):
diff --git a/pypy/jit/metainterp/test/test_basic.py b/pypy/jit/metainterp/test/test_basic.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_basic.py
+++ /dev/null
@@ -1,2411 +0,0 @@
-import py
-import sys
-from pypy.rlib.jit import JitDriver, we_are_jitted, hint, dont_look_inside
-from pypy.rlib.jit import loop_invariant
-from pypy.rlib.jit import jit_debug, assert_green, AssertGreenFailed
-from pypy.rlib.jit import unroll_safe, current_trace_length
-from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
-from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp import pyjitpl, history
-from pypy.jit.metainterp.warmstate import set_future_value
-from pypy.jit.codewriter.policy import JitPolicy, StopAtXPolicy
-from pypy.jit.codewriter import longlong
-from pypy import conftest
-from pypy.rlib.rarithmetic import ovfcheck
-from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
-from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.ootypesystem import ootype
-from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT
-
-def _get_jitcodes(testself, CPUClass, func, values, type_system,
- supports_longlong=False, **kwds):
- from pypy.jit.codewriter import support, codewriter
-
- class FakeJitCell:
- __compiled_merge_points = []
- def get_compiled_merge_points(self):
- return self.__compiled_merge_points[:]
- def set_compiled_merge_points(self, lst):
- self.__compiled_merge_points = lst
-
- class FakeWarmRunnerState:
- def attach_unoptimized_bridge_from_interp(self, greenkey, newloop):
- pass
-
- def jit_cell_at_key(self, greenkey):
- assert greenkey == []
- return self._cell
- _cell = FakeJitCell()
-
- trace_limit = sys.maxint
- enable_opts = ALL_OPTS_DICT
-
- func._jit_unroll_safe_ = True
- rtyper = support.annotate(func, values, type_system=type_system)
- graphs = rtyper.annotator.translator.graphs
- result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]
-
- class FakeJitDriverSD:
- num_green_args = 0
- portal_graph = graphs[0]
- virtualizable_info = None
- greenfield_info = None
- result_type = result_kind
- portal_runner_ptr = "???"
-
- stats = history.Stats()
- cpu = CPUClass(rtyper, stats, None, False)
- cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
- testself.cw = cw
- policy = JitPolicy()
- policy.set_supports_longlong(supports_longlong)
- cw.find_all_graphs(policy)
- #
- testself.warmrunnerstate = FakeWarmRunnerState()
- testself.warmrunnerstate.cpu = cpu
- FakeJitDriverSD.warmstate = testself.warmrunnerstate
- if hasattr(testself, 'finish_setup_for_interp_operations'):
- testself.finish_setup_for_interp_operations()
- #
- cw.make_jitcodes(verbose=True)
-
-def _run_with_blackhole(testself, args):
- from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
- cw = testself.cw
- blackholeinterpbuilder = BlackholeInterpBuilder(cw)
- blackholeinterp = blackholeinterpbuilder.acquire_interp()
- count_i = count_r = count_f = 0
- for value in args:
- T = lltype.typeOf(value)
- if T == lltype.Signed:
- blackholeinterp.setarg_i(count_i, value)
- count_i += 1
- elif T == llmemory.GCREF:
- blackholeinterp.setarg_r(count_r, value)
- count_r += 1
- elif T == lltype.Float:
- value = longlong.getfloatstorage(value)
- blackholeinterp.setarg_f(count_f, value)
- count_f += 1
- else:
- raise TypeError(T)
- [jitdriver_sd] = cw.callcontrol.jitdrivers_sd
- blackholeinterp.setposition(jitdriver_sd.mainjitcode, 0)
- blackholeinterp.run()
- return blackholeinterp._final_result_anytype()
-
-def _run_with_pyjitpl(testself, args):
-
- class DoneWithThisFrame(Exception):
- pass
-
- class DoneWithThisFrameRef(DoneWithThisFrame):
- def __init__(self, cpu, *args):
- DoneWithThisFrame.__init__(self, *args)
-
- cw = testself.cw
- opt = history.Options(listops=True)
- metainterp_sd = pyjitpl.MetaInterpStaticData(cw.cpu, opt)
- metainterp_sd.finish_setup(cw)
- [jitdriver_sd] = metainterp_sd.jitdrivers_sd
- metainterp = pyjitpl.MetaInterp(metainterp_sd, jitdriver_sd)
- metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrame
- metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef
- metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrame
- testself.metainterp = metainterp
- try:
- metainterp.compile_and_run_once(jitdriver_sd, *args)
- except DoneWithThisFrame, e:
- #if conftest.option.view:
- # metainterp.stats.view()
- return e.args[0]
- else:
- raise Exception("FAILED")
-
-def _run_with_machine_code(testself, args):
- metainterp = testself.metainterp
- num_green_args = metainterp.jitdriver_sd.num_green_args
- loop_tokens = metainterp.get_compiled_merge_points(args[:num_green_args])
- if len(loop_tokens) != 1:
- return NotImplemented
- # a loop was successfully created by _run_with_pyjitpl(); call it
- cpu = metainterp.cpu
- for i in range(len(args) - num_green_args):
- x = args[num_green_args + i]
- typecode = history.getkind(lltype.typeOf(x))
- set_future_value(cpu, i, x, typecode)
- faildescr = cpu.execute_token(loop_tokens[0])
- assert faildescr.__class__.__name__.startswith('DoneWithThisFrameDescr')
- if metainterp.jitdriver_sd.result_type == history.INT:
- return cpu.get_latest_value_int(0)
- elif metainterp.jitdriver_sd.result_type == history.REF:
- return cpu.get_latest_value_ref(0)
- elif metainterp.jitdriver_sd.result_type == history.FLOAT:
- return cpu.get_latest_value_float(0)
- else:
- return None
-
-
-class JitMixin:
- basic = True
- def check_loops(self, expected=None, everywhere=False, **check):
- get_stats().check_loops(expected=expected, everywhere=everywhere,
- **check)
- def check_loop_count(self, count):
- """NB. This is a hack; use check_tree_loop_count() or
- check_enter_count() for the real thing.
- This counts as 1 every bridge in addition to every loop; and it does
- not count at all the entry bridges from interpreter, although they
- are TreeLoops as well."""
- assert get_stats().compiled_count == count
- def check_tree_loop_count(self, count):
- assert len(get_stats().loops) == count
- def check_loop_count_at_most(self, count):
- assert get_stats().compiled_count <= count
- def check_enter_count(self, count):
- assert get_stats().enter_count == count
- def check_enter_count_at_most(self, count):
- assert get_stats().enter_count <= count
- def check_jumps(self, maxcount):
- assert get_stats().exec_jumps <= maxcount
- def check_aborted_count(self, count):
- assert get_stats().aborted_count == count
- def check_aborted_count_at_least(self, count):
- assert get_stats().aborted_count >= count
-
- def meta_interp(self, *args, **kwds):
- kwds['CPUClass'] = self.CPUClass
- kwds['type_system'] = self.type_system
- if "backendopt" not in kwds:
- kwds["backendopt"] = False
- return ll_meta_interp(*args, **kwds)
-
- def interp_operations(self, f, args, **kwds):
- # get the JitCodes for the function f
- _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
- # try to run it with blackhole.py
- result1 = _run_with_blackhole(self, args)
- # try to run it with pyjitpl.py
- result2 = _run_with_pyjitpl(self, args)
- assert result1 == result2
- # try to run it by running the code compiled just before
- result3 = _run_with_machine_code(self, args)
- assert result1 == result3 or result3 == NotImplemented
- #
- if (longlong.supports_longlong and
- isinstance(result1, longlong.r_float_storage)):
- result1 = longlong.getrealfloat(result1)
- return result1
-
- def check_history(self, expected=None, **isns):
- # this can be used after calling meta_interp
- get_stats().check_history(expected, **isns)
-
- def check_operations_history(self, expected=None, **isns):
- # this can be used after interp_operations
- if expected is not None:
- expected = dict(expected)
- expected['jump'] = 1
- self.metainterp.staticdata.stats.check_history(expected, **isns)
-
-
-class LLJitMixin(JitMixin):
- type_system = 'lltype'
- CPUClass = runner.LLtypeCPU
-
- @staticmethod
- def Ptr(T):
- return lltype.Ptr(T)
-
- @staticmethod
- def GcStruct(name, *fields, **kwds):
- S = lltype.GcStruct(name, *fields, **kwds)
- return S
-
- malloc = staticmethod(lltype.malloc)
- nullptr = staticmethod(lltype.nullptr)
-
- @staticmethod
- def malloc_immortal(T):
- return lltype.malloc(T, immortal=True)
-
- def _get_NODE(self):
- NODE = lltype.GcForwardReference()
- NODE.become(lltype.GcStruct('NODE', ('value', lltype.Signed),
- ('next', lltype.Ptr(NODE))))
- return NODE
-
-class OOJitMixin(JitMixin):
- type_system = 'ootype'
- #CPUClass = runner.OOtypeCPU
-
- def setup_class(cls):
- py.test.skip("ootype tests skipped for now")
-
- @staticmethod
- def Ptr(T):
- return T
-
- @staticmethod
- def GcStruct(name, *fields, **kwds):
- if 'hints' in kwds:
- kwds['_hints'] = kwds['hints']
- del kwds['hints']
- I = ootype.Instance(name, ootype.ROOT, dict(fields), **kwds)
- return I
-
- malloc = staticmethod(ootype.new)
- nullptr = staticmethod(ootype.null)
-
- @staticmethod
- def malloc_immortal(T):
- return ootype.new(T)
-
- def _get_NODE(self):
- NODE = ootype.Instance('NODE', ootype.ROOT, {})
- NODE._add_fields({'value': ootype.Signed,
- 'next': NODE})
- return NODE
-
-
-class BasicTests:
-
- def test_basic(self):
- def f(x, y):
- return x + y
- res = self.interp_operations(f, [40, 2])
- assert res == 42
-
- def test_basic_inst(self):
- class A:
- pass
- def f(n):
- a = A()
- a.x = n
- return a.x
- res = self.interp_operations(f, [42])
- assert res == 42
-
- def test_uint_floordiv(self):
- from pypy.rlib.rarithmetic import r_uint
-
- def f(a, b):
- a = r_uint(a)
- b = r_uint(b)
- return a/b
-
- res = self.interp_operations(f, [-4, 3])
- assert res == long(r_uint(-4)) // 3
-
- def test_direct_call(self):
- def g(n):
- return n + 2
- def f(a, b):
- return g(a) + g(b)
- res = self.interp_operations(f, [8, 98])
- assert res == 110
-
- def test_direct_call_with_guard(self):
- def g(n):
- if n < 0:
- return 0
- return n + 2
- def f(a, b):
- return g(a) + g(b)
- res = self.interp_operations(f, [8, 98])
- assert res == 110
-
- def test_loop(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x
- y -= 1
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 42
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1,
- 'int_add': 1, 'int_sub': 1, 'int_gt': 1,
- 'jump': 1})
- if self.basic:
- found = 0
- for op in get_stats().loops[0]._all_operations():
- if op.getopname() == 'guard_true':
- liveboxes = op.getfailargs()
- assert len(liveboxes) == 3
- for box in liveboxes:
- assert isinstance(box, history.BoxInt)
- found += 1
- assert found == 1
-
- def test_loop_invariant_mul1(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x * x
- y -= 1
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 252
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1,
- 'int_add': 1, 'int_sub': 1, 'int_gt': 1,
- 'jump': 1})
-
- def test_loop_invariant_mul_ovf(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- b = y * 2
- res += ovfcheck(x * x) + b
- y -= 1
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 308
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1,
- 'int_add': 2, 'int_sub': 1, 'int_gt': 1,
- 'int_lshift': 1,
- 'jump': 1})
-
- def test_loop_invariant_mul_bridge1(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x * x
- if y<16:
- x += 1
- y -= 1
- return res
- res = self.meta_interp(f, [6, 32])
- assert res == 3427
- self.check_loop_count(3)
-
- def test_loop_invariant_mul_bridge_maintaining1(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x * x
- if y<16:
- res += 1
- y -= 1
- return res
- res = self.meta_interp(f, [6, 32])
- assert res == 1167
- self.check_loop_count(3)
- self.check_loops({'int_add': 3, 'int_lt': 2,
- 'int_sub': 2, 'guard_false': 1,
- 'jump': 2,
- 'int_gt': 1, 'guard_true': 2})
-
-
- def test_loop_invariant_mul_bridge_maintaining2(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- z = x * x
- res += z
- if y<16:
- res += z
- y -= 1
- return res
- res = self.meta_interp(f, [6, 32])
- assert res == 1692
- self.check_loop_count(3)
- self.check_loops({'int_add': 3, 'int_lt': 2,
- 'int_sub': 2, 'guard_false': 1,
- 'jump': 2,
- 'int_gt': 1, 'guard_true': 2})
-
- def test_loop_invariant_mul_bridge_maintaining3(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'm'])
- def f(x, y, m):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res, m=m)
- myjitdriver.jit_merge_point(x=x, y=y, res=res, m=m)
- z = x * x
- res += z
- if y<m:
- res += z
- y -= 1
- return res
- res = self.meta_interp(f, [6, 32, 16])
- assert res == 1692
- self.check_loop_count(3)
- self.check_loops({'int_add': 2, 'int_lt': 1,
- 'int_sub': 2, 'guard_false': 1,
- 'jump': 2, 'int_mul': 1,
- 'int_gt': 2, 'guard_true': 2})
-
- def test_loop_invariant_intbox(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
- class I:
- __slots__ = 'intval'
- _immutable_ = True
- def __init__(self, intval):
- self.intval = intval
- def f(i, y):
- res = 0
- x = I(i)
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x.intval * x.intval
- y -= 1
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 252
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1,
- 'int_add': 1, 'int_sub': 1, 'int_gt': 1,
- 'jump': 1})
-
- def test_loops_are_transient(self):
- import gc, weakref
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x
- if y%2:
- res *= 2
- y -= 1
- return res
- wr_loops = []
- old_init = history.TreeLoop.__init__.im_func
- try:
- def track_init(self, name):
- old_init(self, name)
- wr_loops.append(weakref.ref(self))
- history.TreeLoop.__init__ = track_init
- res = self.meta_interp(f, [6, 15], no_stats=True)
- finally:
- history.TreeLoop.__init__ = old_init
-
- assert res == f(6, 15)
- gc.collect()
-
- #assert not [wr for wr in wr_loops if wr()]
- for loop in [wr for wr in wr_loops if wr()]:
- assert loop().name == 'short preamble'
-
- def test_string(self):
- def f(n):
- bytecode = 'adlfkj' + chr(n)
- if n < len(bytecode):
- return bytecode[n]
- else:
- return "?"
- res = self.interp_operations(f, [1])
- assert res == ord("d") # XXX should be "d"
- res = self.interp_operations(f, [6])
- assert res == 6
- res = self.interp_operations(f, [42])
- assert res == ord("?")
-
- def test_chr2str(self):
- def f(n):
- s = chr(n)
- return s[0]
- res = self.interp_operations(f, [3])
- assert res == 3
-
- def test_unicode(self):
- def f(n):
- bytecode = u'adlfkj' + unichr(n)
- if n < len(bytecode):
- return bytecode[n]
- else:
- return u"?"
- res = self.interp_operations(f, [1])
- assert res == ord(u"d") # XXX should be "d"
- res = self.interp_operations(f, [6])
- assert res == 6
- res = self.interp_operations(f, [42])
- assert res == ord(u"?")
-
- def test_residual_call(self):
- @dont_look_inside
- def externfn(x, y):
- return x * y
- def f(n):
- return externfn(n, n+1)
- res = self.interp_operations(f, [6])
- assert res == 42
- self.check_operations_history(int_add=1, int_mul=0, call=1, guard_no_exception=0)
-
- def test_residual_call_pure(self):
- def externfn(x, y):
- return x * y
- externfn._pure_function_ = True
- def f(n):
- n = hint(n, promote=True)
- return externfn(n, n+1)
- res = self.interp_operations(f, [6])
- assert res == 42
- # CALL_PURE is not recorded in the history if all-constant args
- self.check_operations_history(int_add=0, int_mul=0,
- call=0, call_pure=0)
-
- def test_residual_call_pure_1(self):
- def externfn(x, y):
- return x * y
- externfn._pure_function_ = True
- def f(n):
- return externfn(n, n+1)
- res = self.interp_operations(f, [6])
- assert res == 42
- # CALL_PURE is recorded in the history if not-all-constant args
- self.check_operations_history(int_add=1, int_mul=0,
- call=0, call_pure=1)
-
- def test_residual_call_pure_2(self):
- myjitdriver = JitDriver(greens = [], reds = ['n'])
- def externfn(x):
- return x - 1
- externfn._pure_function_ = True
- def f(n):
- while n > 0:
- myjitdriver.can_enter_jit(n=n)
- myjitdriver.jit_merge_point(n=n)
- n = externfn(n)
- return n
- res = self.meta_interp(f, [7])
- assert res == 0
- # CALL_PURE is recorded in the history, but turned into a CALL
- # by optimizeopt.py
- self.check_loops(int_sub=0, call=1, call_pure=0)
-
- def test_constfold_call_pure(self):
- myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
- def externfn(x):
- return x - 3
- externfn._pure_function_ = True
- def f(n, m):
- while n > 0:
- myjitdriver.can_enter_jit(n=n, m=m)
- myjitdriver.jit_merge_point(n=n, m=m)
- n -= externfn(m)
- return n
- res = self.meta_interp(f, [21, 5])
- assert res == -1
- # the CALL_PURE is constant-folded away by optimizeopt.py
- self.check_loops(int_sub=1, call=0, call_pure=0)
-
- def test_constfold_call_pure_2(self):
- myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
- def externfn(x):
- return x - 3
- externfn._pure_function_ = True
- class V:
- def __init__(self, value):
- self.value = value
- def f(n, m):
- while n > 0:
- myjitdriver.can_enter_jit(n=n, m=m)
- myjitdriver.jit_merge_point(n=n, m=m)
- v = V(m)
- n -= externfn(v.value)
- return n
- res = self.meta_interp(f, [21, 5])
- assert res == -1
- # the CALL_PURE is constant-folded away by optimizeopt.py
- self.check_loops(int_sub=1, call=0, call_pure=0)
-
- def test_pure_function_returning_object(self):
- myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
- class V:
- def __init__(self, x):
- self.x = x
- v1 = V(1)
- v2 = V(2)
- def externfn(x):
- if x:
- return v1
- else:
- return v2
- externfn._pure_function_ = True
- def f(n, m):
- while n > 0:
- myjitdriver.can_enter_jit(n=n, m=m)
- myjitdriver.jit_merge_point(n=n, m=m)
- m = V(m).x
- n -= externfn(m).x + externfn(m + m - m).x
- return n
- res = self.meta_interp(f, [21, 5])
- assert res == -1
- # the CALL_PURE is constant-folded away by optimizeopt.py
- self.check_loops(int_sub=1, call=0, call_pure=0, getfield_gc=0)
-
- def test_constant_across_mp(self):
- myjitdriver = JitDriver(greens = [], reds = ['n'])
- class X(object):
- pass
- def f(n):
- while n > -100:
- myjitdriver.can_enter_jit(n=n)
- myjitdriver.jit_merge_point(n=n)
- x = X()
- x.arg = 5
- if n <= 0: break
- n -= x.arg
- x.arg = 6 # prevents 'x.arg' from being annotated as constant
- return n
- res = self.meta_interp(f, [31])
- assert res == -4
-
- def test_stopatxpolicy(self):
- myjitdriver = JitDriver(greens = [], reds = ['y'])
- def internfn(y):
- return y * 3
- def externfn(y):
- return y % 4
- def f(y):
- while y >= 0:
- myjitdriver.can_enter_jit(y=y)
- myjitdriver.jit_merge_point(y=y)
- if y & 7:
- f = internfn
- else:
- f = externfn
- f(y)
- y -= 1
- return 42
- policy = StopAtXPolicy(externfn)
- res = self.meta_interp(f, [31], policy=policy)
- assert res == 42
- self.check_loops(int_mul=1, int_mod=0)
-
- def test_we_are_jitted(self):
- myjitdriver = JitDriver(greens = [], reds = ['y'])
- def f(y):
- while y >= 0:
- myjitdriver.can_enter_jit(y=y)
- myjitdriver.jit_merge_point(y=y)
- if we_are_jitted():
- x = 1
- else:
- x = 10
- y -= x
- return y
- assert f(55) == -5
- res = self.meta_interp(f, [55])
- assert res == -1
-
- def test_confirm_enter_jit(self):
- def confirm_enter_jit(x, y):
- return x <= 5
- myjitdriver = JitDriver(greens = ['x'], reds = ['y'],
- confirm_enter_jit = confirm_enter_jit)
- def f(x, y):
- while y >= 0:
- myjitdriver.can_enter_jit(x=x, y=y)
- myjitdriver.jit_merge_point(x=x, y=y)
- y -= x
- return y
- #
- res = self.meta_interp(f, [10, 84])
- assert res == -6
- self.check_loop_count(0)
- #
- res = self.meta_interp(f, [3, 19])
- assert res == -2
- self.check_loop_count(1)
-
- def test_can_never_inline(self):
- def can_never_inline(x):
- return x > 50
- myjitdriver = JitDriver(greens = ['x'], reds = ['y'],
- can_never_inline = can_never_inline)
- @dont_look_inside
- def marker():
- pass
- def f(x, y):
- while y >= 0:
- myjitdriver.can_enter_jit(x=x, y=y)
- myjitdriver.jit_merge_point(x=x, y=y)
- x += 1
- if x == 4 or x == 61:
- marker()
- y -= x
- return y
- #
- res = self.meta_interp(f, [3, 6], repeat=7)
- assert res == 6 - 4 - 5
- self.check_history(call=0) # because the trace starts in the middle
- #
- res = self.meta_interp(f, [60, 84], repeat=7)
- assert res == 84 - 61 - 62
- self.check_history(call=1) # because the trace starts immediately
-
- def test_format(self):
- def f(n):
- return len("<%d>" % n)
- res = self.interp_operations(f, [421])
- assert res == 5
-
- def test_switch(self):
- def f(n):
- if n == -5: return 12
- elif n == 2: return 51
- elif n == 7: return 1212
- else: return 42
- res = self.interp_operations(f, [7])
- assert res == 1212
- res = self.interp_operations(f, [12311])
- assert res == 42
-
- def test_r_uint(self):
- from pypy.rlib.rarithmetic import r_uint
- myjitdriver = JitDriver(greens = [], reds = ['y'])
- def f(y):
- y = r_uint(y)
- while y > 0:
- myjitdriver.can_enter_jit(y=y)
- myjitdriver.jit_merge_point(y=y)
- y -= 1
- return y
- res = self.meta_interp(f, [10])
- assert res == 0
-
- def test_uint_operations(self):
- from pypy.rlib.rarithmetic import r_uint
- def f(n):
- return ((r_uint(n) - 123) >> 1) <= r_uint(456)
- res = self.interp_operations(f, [50])
- assert res == False
- self.check_operations_history(int_rshift=0, uint_rshift=1,
- int_le=0, uint_le=1,
- int_sub=1)
-
- def test_uint_condition(self):
- from pypy.rlib.rarithmetic import r_uint
- def f(n):
- if ((r_uint(n) - 123) >> 1) <= r_uint(456):
- return 24
- else:
- return 12
- res = self.interp_operations(f, [50])
- assert res == 12
- self.check_operations_history(int_rshift=0, uint_rshift=1,
- int_le=0, uint_le=1,
- int_sub=1)
-
- def test_int_between(self):
- #
- def check(arg1, arg2, arg3, expect_result, **expect_operations):
- from pypy.rpython.lltypesystem import lltype
- from pypy.rpython.lltypesystem.lloperation import llop
- loc = locals().copy()
- exec py.code.Source("""
- def f(n, m, p):
- arg1 = %(arg1)s
- arg2 = %(arg2)s
- arg3 = %(arg3)s
- return llop.int_between(lltype.Bool, arg1, arg2, arg3)
- """ % locals()).compile() in loc
- res = self.interp_operations(loc['f'], [5, 6, 7])
- assert res == expect_result
- self.check_operations_history(expect_operations)
- #
- check('n', 'm', 'p', True, int_sub=2, uint_lt=1)
- check('n', 'p', 'm', False, int_sub=2, uint_lt=1)
- #
- check('n', 'm', 6, False, int_sub=2, uint_lt=1)
- #
- check('n', 4, 'p', False, int_sub=2, uint_lt=1)
- check('n', 5, 'p', True, int_sub=2, uint_lt=1)
- check('n', 8, 'p', False, int_sub=2, uint_lt=1)
- #
- check('n', 6, 7, True, int_sub=2, uint_lt=1)
- #
- check(-2, 'n', 'p', True, int_sub=2, uint_lt=1)
- check(-2, 'm', 'p', True, int_sub=2, uint_lt=1)
- check(-2, 'p', 'm', False, int_sub=2, uint_lt=1)
- #check(0, 'n', 'p', True, uint_lt=1) xxx implement me
- #check(0, 'm', 'p', True, uint_lt=1)
- #check(0, 'p', 'm', False, uint_lt=1)
- #
- check(2, 'n', 6, True, int_sub=1, uint_lt=1)
- check(2, 'm', 6, False, int_sub=1, uint_lt=1)
- check(2, 'p', 6, False, int_sub=1, uint_lt=1)
- check(5, 'n', 6, True, int_eq=1) # 6 == 5+1
- check(5, 'm', 6, False, int_eq=1) # 6 == 5+1
- #
- check(2, 6, 'm', False, int_sub=1, uint_lt=1)
- check(2, 6, 'p', True, int_sub=1, uint_lt=1)
- #
- check(2, 40, 6, False)
- check(2, 40, 60, True)
-
- def test_getfield(self):
- class A:
- pass
- a1 = A()
- a1.foo = 5
- a2 = A()
- a2.foo = 8
- def f(x):
- if x > 5:
- a = a1
- else:
- a = a2
- return a.foo * x
- res = self.interp_operations(f, [42])
- assert res == 210
- self.check_operations_history(getfield_gc=1)
-
- def test_getfield_immutable(self):
- class A:
- _immutable_ = True
- a1 = A()
- a1.foo = 5
- a2 = A()
- a2.foo = 8
- def f(x):
- if x > 5:
- a = a1
- else:
- a = a2
- return a.foo * x
- res = self.interp_operations(f, [42])
- assert res == 210
- self.check_operations_history(getfield_gc=0)
-
- def test_setfield_bool(self):
- class A:
- def __init__(self):
- self.flag = True
- myjitdriver = JitDriver(greens = [], reds = ['n', 'obj'])
- def f(n):
- obj = A()
- res = False
- while n > 0:
- myjitdriver.can_enter_jit(n=n, obj=obj)
- myjitdriver.jit_merge_point(n=n, obj=obj)
- obj.flag = False
- n -= 1
- return res
- res = self.meta_interp(f, [7])
- assert type(res) == bool
- assert not res
-
- def test_switch_dict(self):
- def f(x):
- if x == 1: return 61
- elif x == 2: return 511
- elif x == 3: return -22
- elif x == 4: return 81
- elif x == 5: return 17
- elif x == 6: return 54
- elif x == 7: return 987
- elif x == 8: return -12
- elif x == 9: return 321
- return -1
- res = self.interp_operations(f, [5])
- assert res == 17
- res = self.interp_operations(f, [15])
- assert res == -1
-
- def test_int_add_ovf(self):
- def f(x, y):
- try:
- return ovfcheck(x + y)
- except OverflowError:
- return -42
- res = self.interp_operations(f, [-100, 2])
- assert res == -98
- res = self.interp_operations(f, [1, sys.maxint])
- assert res == -42
-
- def test_int_sub_ovf(self):
- def f(x, y):
- try:
- return ovfcheck(x - y)
- except OverflowError:
- return -42
- res = self.interp_operations(f, [-100, 2])
- assert res == -102
- res = self.interp_operations(f, [1, -sys.maxint])
- assert res == -42
-
- def test_int_mul_ovf(self):
- def f(x, y):
- try:
- return ovfcheck(x * y)
- except OverflowError:
- return -42
- res = self.interp_operations(f, [-100, 2])
- assert res == -200
- res = self.interp_operations(f, [-3, sys.maxint//2])
- assert res == -42
-
- def test_mod_ovf(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'y'])
- def f(n, x, y):
- while n > 0:
- myjitdriver.can_enter_jit(x=x, y=y, n=n)
- myjitdriver.jit_merge_point(x=x, y=y, n=n)
- n -= ovfcheck(x % y)
- return n
- res = self.meta_interp(f, [20, 1, 2])
- assert res == 0
- self.check_loops(call=0)
-
- def test_abs(self):
- myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
- def f(i):
- t = 0
- while i < 10:
- myjitdriver.can_enter_jit(i=i, t=t)
- myjitdriver.jit_merge_point(i=i, t=t)
- t += abs(i)
- i += 1
- return t
- res = self.meta_interp(f, [-5])
- assert res == 5+4+3+2+1+0+1+2+3+4+5+6+7+8+9
-
- def test_float(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
- def f(x, y):
- x = float(x)
- y = float(y)
- res = 0.0
- while y > 0.0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- res += x
- y -= 1.0
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 42.0
- self.check_loop_count(1)
- self.check_loops({'guard_true': 1,
- 'float_add': 1, 'float_sub': 1, 'float_gt': 1,
- 'jump': 1})
-
- def test_print(self):
- myjitdriver = JitDriver(greens = [], reds = ['n'])
- def f(n):
- while n > 0:
- myjitdriver.can_enter_jit(n=n)
- myjitdriver.jit_merge_point(n=n)
- print n
- n -= 1
- return n
- res = self.meta_interp(f, [7])
- assert res == 0
-
- def test_bridge_from_interpreter(self):
- mydriver = JitDriver(reds = ['n'], greens = [])
-
- def f(n):
- while n > 0:
- mydriver.can_enter_jit(n=n)
- mydriver.jit_merge_point(n=n)
- n -= 1
-
- self.meta_interp(f, [20], repeat=7)
- self.check_tree_loop_count(2) # the loop and the entry path
- # we get:
- # ENTER - compile the new loop and the entry bridge
- # ENTER - compile the leaving path
- self.check_enter_count(2)
-
- def test_bridge_from_interpreter_2(self):
- # one case for backend - computing of framesize on guard failure
- mydriver = JitDriver(reds = ['n'], greens = [])
- glob = [1]
-
- def f(n):
- while n > 0:
- mydriver.can_enter_jit(n=n)
- mydriver.jit_merge_point(n=n)
- if n == 17 and glob[0]:
- glob[0] = 0
- x = n + 1
- y = n + 2
- z = n + 3
- k = n + 4
- n -= 1
- n += x + y + z + k
- n -= x + y + z + k
- n -= 1
-
- self.meta_interp(f, [20], repeat=7)
-
- def test_bridge_from_interpreter_3(self):
- # one case for backend - computing of framesize on guard failure
- mydriver = JitDriver(reds = ['n', 'x', 'y', 'z', 'k'], greens = [])
- class Global:
- pass
- glob = Global()
-
- def f(n):
- glob.x = 1
- x = 0
- y = 0
- z = 0
- k = 0
- while n > 0:
- mydriver.can_enter_jit(n=n, x=x, y=y, z=z, k=k)
- mydriver.jit_merge_point(n=n, x=x, y=y, z=z, k=k)
- x += 10
- y += 3
- z -= 15
- k += 4
- if n == 17 and glob.x:
- glob.x = 0
- x += n + 1
- y += n + 2
- z += n + 3
- k += n + 4
- n -= 1
- n -= 1
- return x + 2*y + 3*z + 5*k + 13*n
-
- res = self.meta_interp(f, [20], repeat=7)
- assert res == f(20)
-
- def test_bridge_from_interpreter_4(self):
- jitdriver = JitDriver(reds = ['n', 'k'], greens = [])
-
- def f(n, k):
- while n > 0:
- jitdriver.can_enter_jit(n=n, k=k)
- jitdriver.jit_merge_point(n=n, k=k)
- if k:
- n -= 2
- else:
- n -= 1
- return n + k
-
- from pypy.rpython.test.test_llinterp import get_interpreter, clear_tcache
- from pypy.jit.metainterp.warmspot import WarmRunnerDesc
-
- interp, graph = get_interpreter(f, [0, 0], backendopt=False,
- inline_threshold=0, type_system=self.type_system)
- clear_tcache()
- translator = interp.typer.annotator.translator
- translator.config.translation.gc = "boehm"
- warmrunnerdesc = WarmRunnerDesc(translator,
- CPUClass=self.CPUClass)
- state = warmrunnerdesc.jitdrivers_sd[0].warmstate
- state.set_param_threshold(3) # for tests
- state.set_param_trace_eagerness(0) # for tests
- warmrunnerdesc.finish()
- for n, k in [(20, 0), (20, 1)]:
- interp.eval_graph(graph, [n, k])
-
- def test_bridge_leaving_interpreter_5(self):
- mydriver = JitDriver(reds = ['n', 'x'], greens = [])
- class Global:
- pass
- glob = Global()
-
- def f(n):
- x = 0
- glob.x = 1
- while n > 0:
- mydriver.can_enter_jit(n=n, x=x)
- mydriver.jit_merge_point(n=n, x=x)
- glob.x += 1
- x += 3
- n -= 1
- glob.x += 100
- return glob.x + x
- res = self.meta_interp(f, [20], repeat=7)
- assert res == f(20)
-
- def test_instantiate_classes(self):
- class Base: pass
- class A(Base): foo = 72
- class B(Base): foo = 8
- def f(n):
- if n > 5:
- cls = A
- else:
- cls = B
- return cls().foo
- res = self.interp_operations(f, [3])
- assert res == 8
- res = self.interp_operations(f, [13])
- assert res == 72
-
- def test_instantiate_does_not_call(self):
- mydriver = JitDriver(reds = ['n', 'x'], greens = [])
- class Base: pass
- class A(Base): foo = 72
- class B(Base): foo = 8
-
- def f(n):
- x = 0
- while n > 0:
- mydriver.can_enter_jit(n=n, x=x)
- mydriver.jit_merge_point(n=n, x=x)
- if n % 2 == 0:
- cls = A
- else:
- cls = B
- inst = cls()
- x += inst.foo
- n -= 1
- return x
- res = self.meta_interp(f, [20], enable_opts='')
- assert res == f(20)
- self.check_loops(call=0)
-
- def test_zerodivisionerror(self):
- # test the case of exception-raising operation that is not delegated
- # to the backend at all: ZeroDivisionError
- #
- def f(n):
- assert n >= 0
- try:
- return ovfcheck(5 % n)
- except ZeroDivisionError:
- return -666
- except OverflowError:
- return -777
- res = self.interp_operations(f, [0])
- assert res == -666
- #
- def f(n):
- assert n >= 0
- try:
- return ovfcheck(6 // n)
- except ZeroDivisionError:
- return -667
- except OverflowError:
- return -778
- res = self.interp_operations(f, [0])
- assert res == -667
-
- def test_div_overflow(self):
- import sys
- from pypy.rpython.lltypesystem.lloperation import llop
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
- def f(x, y):
- res = 0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- try:
- res += llop.int_floordiv_ovf(lltype.Signed,
- -sys.maxint-1, x)
- x += 5
- except OverflowError:
- res += 100
- y -= 1
- return res
- res = self.meta_interp(f, [-41, 16])
- assert res == ((-sys.maxint-1) // (-41) +
- (-sys.maxint-1) // (-36) +
- (-sys.maxint-1) // (-31) +
- (-sys.maxint-1) // (-26) +
- (-sys.maxint-1) // (-21) +
- (-sys.maxint-1) // (-16) +
- (-sys.maxint-1) // (-11) +
- (-sys.maxint-1) // (-6) +
- 100 * 8)
-
- def test_isinstance(self):
- class A:
- pass
- class B(A):
- pass
- def fn(n):
- if n:
- obj = A()
- else:
- obj = B()
- return isinstance(obj, B)
- res = self.interp_operations(fn, [0])
- assert res
- self.check_operations_history(guard_class=1)
- res = self.interp_operations(fn, [1])
- assert not res
-
- def test_isinstance_2(self):
- driver = JitDriver(greens = [], reds = ['n', 'sum', 'x'])
- class A:
- pass
- class B(A):
- pass
- class C(B):
- pass
-
- def main():
- return f(5, B()) * 10 + f(5, C()) + f(5, A()) * 100
-
- def f(n, x):
- sum = 0
- while n > 0:
- driver.can_enter_jit(x=x, n=n, sum=sum)
- driver.jit_merge_point(x=x, n=n, sum=sum)
- if isinstance(x, B):
- sum += 1
- n -= 1
- return sum
-
- res = self.meta_interp(main, [])
- assert res == 55
-
- def test_assert_isinstance(self):
- class A:
- pass
- class B(A):
- pass
- def fn(n):
- # this should only be called with n != 0
- if n:
- obj = B()
- obj.a = n
- else:
- obj = A()
- obj.a = 17
- assert isinstance(obj, B)
- return obj.a
- res = self.interp_operations(fn, [1])
- assert res == 1
- self.check_operations_history(guard_class=0)
- if self.type_system == 'ootype':
- self.check_operations_history(instanceof=0)
-
- def test_r_dict(self):
- from pypy.rlib.objectmodel import r_dict
- class FooError(Exception):
- pass
- def myeq(n, m):
- return n == m
- def myhash(n):
- if n < 0:
- raise FooError
- return -n
- def f(n):
- d = r_dict(myeq, myhash)
- for i in range(10):
- d[i] = i*i
- try:
- return d[n]
- except FooError:
- return 99
- res = self.interp_operations(f, [5])
- assert res == f(5)
-
- def test_free_object(self):
- import weakref
- from pypy.rlib import rgc
- from pypy.rpython.lltypesystem.lloperation import llop
- myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
- class X(object):
- pass
- def main(n, x):
- while n > 0:
- myjitdriver.can_enter_jit(n=n, x=x)
- myjitdriver.jit_merge_point(n=n, x=x)
- n -= x.foo
- def g(n):
- x = X()
- x.foo = 2
- main(n, x)
- x.foo = 5
- return weakref.ref(x)
- def f(n):
- r = g(n)
- rgc.collect(); rgc.collect(); rgc.collect()
- return r() is None
- #
- assert f(30) == 1
- res = self.meta_interp(f, [30], no_stats=True)
- assert res == 1
-
- def test_pass_around(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
-
- def call():
- pass
-
- def f(n, x):
- while n > 0:
- myjitdriver.can_enter_jit(n=n, x=x)
- myjitdriver.jit_merge_point(n=n, x=x)
- if n % 2:
- call()
- if n == 8:
- return x
- x = 3
- else:
- x = 5
- n -= 1
- return 0
-
- self.meta_interp(f, [40, 0])
-
- def test_const_inputargs(self):
- myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'x'])
- def f(n, x):
- m = 0x7FFFFFFF
- while n > 0:
- myjitdriver.can_enter_jit(m=m, n=n, x=x)
- myjitdriver.jit_merge_point(m=m, n=n, x=x)
- x = 42
- n -= 1
- m = m >> 1
- return x
-
- res = self.meta_interp(f, [50, 1], enable_opts='')
- assert res == 42
-
- def test_set_param(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
- def g(n):
- x = 0
- while n > 0:
- myjitdriver.can_enter_jit(n=n, x=x)
- myjitdriver.jit_merge_point(n=n, x=x)
- n -= 1
- x += n
- return x
- def f(n, threshold):
- myjitdriver.set_param('threshold', threshold)
- return g(n)
-
- res = self.meta_interp(f, [10, 3])
- assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
- self.check_tree_loop_count(2)
-
- res = self.meta_interp(f, [10, 13])
- assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
- self.check_tree_loop_count(0)
-
- def test_dont_look_inside(self):
- @dont_look_inside
- def g(a, b):
- return a + b
- def f(a, b):
- return g(a, b)
- res = self.interp_operations(f, [3, 5])
- assert res == 8
- self.check_operations_history(int_add=0, call=1)
-
- def test_listcomp(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'lst'])
- def f(x, y):
- lst = [0, 0, 0]
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, lst=lst)
- myjitdriver.jit_merge_point(x=x, y=y, lst=lst)
- lst = [i+x for i in lst if i >=0]
- y -= 1
- return lst[0]
- res = self.meta_interp(f, [6, 7], listcomp=True, backendopt=True, listops=True)
- # XXX: the loop looks inefficient
- assert res == 42
-
- def test_tuple_immutable(self):
- def new(a, b):
- return a, b
- def f(a, b):
- tup = new(a, b)
- return tup[1]
- res = self.interp_operations(f, [3, 5])
- assert res == 5
- self.check_operations_history(setfield_gc=2, getfield_gc_pure=1)
-
- def test_oosend_look_inside_only_one(self):
- class A:
- pass
- class B(A):
- def g(self):
- return 123
- class C(A):
- @dont_look_inside
- def g(self):
- return 456
- def f(n):
- if n > 3:
- x = B()
- else:
- x = C()
- return x.g() + x.g()
- res = self.interp_operations(f, [10])
- assert res == 123 * 2
- res = self.interp_operations(f, [-10])
- assert res == 456 * 2
-
- def test_residual_external_call(self):
- import math
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
- def f(x, y):
- x = float(x)
- res = 0.0
- while y > 0:
- myjitdriver.can_enter_jit(x=x, y=y, res=res)
- myjitdriver.jit_merge_point(x=x, y=y, res=res)
- # this is an external call that the default policy ignores
- rpart, ipart = math.modf(x)
- res += ipart
- y -= 1
- return res
- res = self.meta_interp(f, [6, 7])
- assert res == 42
- self.check_loop_count(1)
- self.check_loops(call=1)
-
- def test_merge_guardclass_guardvalue(self):
- from pypy.rlib.objectmodel import instantiate
- myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
-
- class A(object):
- def g(self, x):
- return x - 5
- class B(A):
- def g(self, y):
- return y - 3
-
- a1 = A()
- a2 = A()
- b = B()
- def f(x):
- l = [a1] * 100 + [a2] * 100 + [b] * 100
- while x > 0:
- myjitdriver.can_enter_jit(x=x, l=l)
- myjitdriver.jit_merge_point(x=x, l=l)
- a = l[x]
- x = a.g(x)
- hint(a, promote=True)
- return x
- res = self.meta_interp(f, [299], listops=True)
- assert res == f(299)
- self.check_loops(guard_class=0, guard_value=2)
- self.check_loops(guard_class=0, guard_value=5, everywhere=True)
-
- def test_merge_guardnonnull_guardclass(self):
- from pypy.rlib.objectmodel import instantiate
- myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
-
- class A(object):
- def g(self, x):
- return x - 3
- class B(A):
- def g(self, y):
- return y - 5
-
- a1 = A()
- b1 = B()
- def f(x):
- l = [None] * 100 + [b1] * 100 + [a1] * 100
- while x > 0:
- myjitdriver.can_enter_jit(x=x, l=l)
- myjitdriver.jit_merge_point(x=x, l=l)
- a = l[x]
- if a:
- x = a.g(x)
- else:
- x -= 7
- return x
- res = self.meta_interp(f, [299], listops=True)
- assert res == f(299)
- self.check_loops(guard_class=0, guard_nonnull=0,
- guard_nonnull_class=2, guard_isnull=0)
- self.check_loops(guard_class=0, guard_nonnull=0,
- guard_nonnull_class=4, guard_isnull=1,
- everywhere=True)
-
- def test_merge_guardnonnull_guardvalue(self):
- from pypy.rlib.objectmodel import instantiate
- myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
-
- class A(object):
- pass
- class B(A):
- pass
-
- a1 = A()
- b1 = B()
- def f(x):
- l = [b1] * 100 + [None] * 100 + [a1] * 100
- while x > 0:
- myjitdriver.can_enter_jit(x=x, l=l)
- myjitdriver.jit_merge_point(x=x, l=l)
- a = l[x]
- if a:
- x -= 5
- else:
- x -= 7
- hint(a, promote=True)
- return x
- res = self.meta_interp(f, [299], listops=True)
- assert res == f(299)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=1,
- guard_nonnull_class=0, guard_isnull=1)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=3,
- guard_nonnull_class=0, guard_isnull=2,
- everywhere=True)
-
- def test_merge_guardnonnull_guardvalue_2(self):
- from pypy.rlib.objectmodel import instantiate
- myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
-
- class A(object):
- pass
- class B(A):
- pass
-
- a1 = A()
- b1 = B()
- def f(x):
- l = [None] * 100 + [b1] * 100 + [a1] * 100
- while x > 0:
- myjitdriver.can_enter_jit(x=x, l=l)
- myjitdriver.jit_merge_point(x=x, l=l)
- a = l[x]
- if a:
- x -= 5
- else:
- x -= 7
- hint(a, promote=True)
- return x
- res = self.meta_interp(f, [299], listops=True)
- assert res == f(299)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=2,
- guard_nonnull_class=0, guard_isnull=0)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=4,
- guard_nonnull_class=0, guard_isnull=1,
- everywhere=True)
-
- def test_merge_guardnonnull_guardclass_guardvalue(self):
- from pypy.rlib.objectmodel import instantiate
- myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
-
- class A(object):
- def g(self, x):
- return x - 3
- class B(A):
- def g(self, y):
- return y - 5
-
- a1 = A()
- a2 = A()
- b1 = B()
- def f(x):
- l = [a2] * 100 + [None] * 100 + [b1] * 100 + [a1] * 100
- while x > 0:
- myjitdriver.can_enter_jit(x=x, l=l)
- myjitdriver.jit_merge_point(x=x, l=l)
- a = l[x]
- if a:
- x = a.g(x)
- else:
- x -= 7
- hint(a, promote=True)
- return x
- res = self.meta_interp(f, [399], listops=True)
- assert res == f(399)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=2,
- guard_nonnull_class=0, guard_isnull=0)
- self.check_loops(guard_class=0, guard_nonnull=0, guard_value=5,
- guard_nonnull_class=0, guard_isnull=1,
- everywhere=True)
-
- def test_residual_call_doesnt_lose_info(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'l'])
-
- class A(object):
- pass
-
- globall = [""]
- @dont_look_inside
- def g(x):
- globall[0] = str(x)
- return x
-
- def f(x):
- y = A()
- y.v = x
- l = [0]
- while y.v > 0:
- myjitdriver.can_enter_jit(x=x, y=y, l=l)
- myjitdriver.jit_merge_point(x=x, y=y, l=l)
- l[0] = y.v
- lc = l[0]
- y.v = g(y.v) - y.v/y.v + lc/l[0] - 1
- return y.v
- res = self.meta_interp(f, [20], listops=True)
- self.check_loops(getfield_gc=0, getarrayitem_gc=0)
- self.check_loops(getfield_gc=1, getarrayitem_gc=0, everywhere=True)
-
- def test_guard_isnull_nonnull(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
- class A(object):
- pass
-
- @dont_look_inside
- def create(x):
- if x >= -40:
- return A()
- return None
-
- def f(x):
- res = 0
- while x > 0:
- myjitdriver.can_enter_jit(x=x, res=res)
- myjitdriver.jit_merge_point(x=x, res=res)
- obj = create(x-1)
- if obj is not None:
- res += 1
- obj2 = create(x-1000)
- if obj2 is None:
- res += 1
- x -= 1
- return res
- res = self.meta_interp(f, [21])
- assert res == 42
- self.check_loops(guard_nonnull=1, guard_isnull=1)
-
- def test_loop_invariant1(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
- class A(object):
- pass
- a = A()
- a.current_a = A()
- a.current_a.x = 1
- @loop_invariant
- def f():
- return a.current_a
-
- def g(x):
- res = 0
- while x > 0:
- myjitdriver.can_enter_jit(x=x, res=res)
- myjitdriver.jit_merge_point(x=x, res=res)
- res += f().x
- res += f().x
- res += f().x
- x -= 1
- a.current_a = A()
- a.current_a.x = 2
- return res
- res = self.meta_interp(g, [21])
- assert res == 3 * 21
- self.check_loops(call=0)
- self.check_loops(call=1, everywhere=True)
-
- def test_bug_optimizeopt_mutates_ops(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'const', 'a'])
- class A(object):
- pass
- class B(A):
- pass
-
- glob = A()
- glob.a = None
- def f(x):
- res = 0
- a = A()
- a.x = 0
- glob.a = A()
- const = 2
- while x > 0:
- myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const)
- myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const)
- if type(glob.a) is B:
- res += 1
- if a is None:
- a = A()
- a.x = x
- glob.a = B()
- const = 2
- else:
- const = hint(const, promote=True)
- x -= const
- res += a.x
- a = None
- glob.a = A()
- const = 1
- return res
- res = self.meta_interp(f, [21])
- assert res == f(21)
-
- def test_getitem_indexerror(self):
- lst = [10, 4, 9, 16]
- def f(n):
- try:
- return lst[n]
- except IndexError:
- return -2
- res = self.interp_operations(f, [2])
- assert res == 9
- res = self.interp_operations(f, [4])
- assert res == -2
- res = self.interp_operations(f, [-4])
- assert res == 10
- res = self.interp_operations(f, [-5])
- assert res == -2
-
- def test_guard_always_changing_value(self):
- myjitdriver = JitDriver(greens = [], reds = ['x'])
- class A:
- pass
- def f(x):
- while x > 0:
- myjitdriver.can_enter_jit(x=x)
- myjitdriver.jit_merge_point(x=x)
- a = A()
- hint(a, promote=True)
- x -= 1
- self.meta_interp(f, [50])
- self.check_loop_count(1)
- # this checks that the logic triggered by make_a_counter_per_value()
- # works and prevents generating tons of bridges
-
- def test_swap_values(self):
- def f(x, y):
- if x > 5:
- x, y = y, x
- return x - y
- res = self.interp_operations(f, [10, 2])
- assert res == -8
- res = self.interp_operations(f, [3, 2])
- assert res == 1
-
- def test_raw_malloc_and_access(self):
- from pypy.rpython.lltypesystem import rffi
-
- TP = rffi.CArray(lltype.Signed)
-
- def f(n):
- a = lltype.malloc(TP, n, flavor='raw')
- a[0] = n
- res = a[0]
- lltype.free(a, flavor='raw')
- return res
-
- res = self.interp_operations(f, [10])
- assert res == 10
-
- def test_raw_malloc_and_access_float(self):
- from pypy.rpython.lltypesystem import rffi
-
- TP = rffi.CArray(lltype.Float)
-
- def f(n, f):
- a = lltype.malloc(TP, n, flavor='raw')
- a[0] = f
- res = a[0]
- lltype.free(a, flavor='raw')
- return res
-
- res = self.interp_operations(f, [10, 3.5])
- assert res == 3.5
-
- def test_jit_debug(self):
- myjitdriver = JitDriver(greens = [], reds = ['x'])
- class A:
- pass
- def f(x):
- while x > 0:
- myjitdriver.can_enter_jit(x=x)
- myjitdriver.jit_merge_point(x=x)
- jit_debug("hi there:", x)
- jit_debug("foobar")
- x -= 1
- return x
- res = self.meta_interp(f, [8])
- assert res == 0
- self.check_loops(jit_debug=2)
-
- def test_assert_green(self):
- def f(x, promote):
- if promote:
- x = hint(x, promote=True)
- assert_green(x)
- return x
- res = self.interp_operations(f, [8, 1])
- assert res == 8
- py.test.raises(AssertGreenFailed, self.interp_operations, f, [8, 0])
-
- def test_multiple_specialied_versions1(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
- class Base:
- def __init__(self, val):
- self.val = val
- class A(Base):
- def binop(self, other):
- return A(self.val + other.val)
- class B(Base):
- def binop(self, other):
- return B(self.val * other.val)
- def f(x, y):
- res = x
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, res=res)
- res = res.binop(x)
- y -= 1
- return res
- def g(x, y):
- a1 = f(A(x), y)
- a2 = f(A(x), y)
- b1 = f(B(x), y)
- b2 = f(B(x), y)
- assert a1.val == a2.val
- assert b1.val == b2.val
- return a1.val + b1.val
- res = self.meta_interp(g, [6, 7])
- assert res == 6*8 + 6**8
- self.check_loop_count(5)
- self.check_loops({'guard_true': 2,
- 'int_add': 1, 'int_mul': 1, 'int_sub': 2,
- 'int_gt': 2, 'jump': 2})
-
- def test_multiple_specialied_versions_array(self):
- myjitdriver = JitDriver(greens = [], reds = ['idx', 'y', 'x', 'res',
- 'array'])
- class Base:
- def __init__(self, val):
- self.val = val
- class A(Base):
- def binop(self, other):
- return A(self.val + other.val)
- class B(Base):
- def binop(self, other):
- return B(self.val - other.val)
- def f(x, y):
- res = x
- array = [1, 2, 3]
- array[1] = 7
- idx = 0
- while y > 0:
- myjitdriver.can_enter_jit(idx=idx, y=y, x=x, res=res,
- array=array)
- myjitdriver.jit_merge_point(idx=idx, y=y, x=x, res=res,
- array=array)
- res = res.binop(x)
- res.val += array[idx] + array[1]
- if y < 7:
- idx = 2
- y -= 1
- return res
- def g(x, y):
- a1 = f(A(x), y)
- a2 = f(A(x), y)
- b1 = f(B(x), y)
- b2 = f(B(x), y)
- assert a1.val == a2.val
- assert b1.val == b2.val
- return a1.val + b1.val
- res = self.meta_interp(g, [6, 14])
- assert res == g(6, 14)
- self.check_loop_count(9)
- self.check_loops(getarrayitem_gc=6, everywhere=True)
-
- def test_multiple_specialied_versions_bridge(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
- class Base:
- def __init__(self, val):
- self.val = val
- def getval(self):
- return self.val
- class A(Base):
- def binop(self, other):
- return A(self.getval() + other.getval())
- class B(Base):
- def binop(self, other):
- return B(self.getval() * other.getval())
- def f(x, y, z):
- res = x
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
- res = res.binop(x)
- y -= 1
- if y < 7:
- x = z
- return res
- def g(x, y):
- a1 = f(A(x), y, A(x))
- a2 = f(A(x), y, A(x))
- assert a1.val == a2.val
- b1 = f(B(x), y, B(x))
- b2 = f(B(x), y, B(x))
- assert b1.val == b2.val
- c1 = f(B(x), y, A(x))
- c2 = f(B(x), y, A(x))
- assert c1.val == c2.val
- d1 = f(A(x), y, B(x))
- d2 = f(A(x), y, B(x))
- assert d1.val == d2.val
- return a1.val + b1.val + c1.val + d1.val
- res = self.meta_interp(g, [3, 14])
- assert res == g(3, 14)
-
- def test_failing_inlined_guard(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
- class Base:
- def __init__(self, val):
- self.val = val
- def getval(self):
- return self.val
- class A(Base):
- def binop(self, other):
- return A(self.getval() + other.getval())
- class B(Base):
- def binop(self, other):
- return B(self.getval() * other.getval())
- def f(x, y, z):
- res = x
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
- res = res.binop(x)
- y -= 1
- if y < 8:
- x = z
- return res
- def g(x, y):
- c1 = f(A(x), y, B(x))
- c2 = f(A(x), y, B(x))
- assert c1.val == c2.val
- return c1.val
- res = self.meta_interp(g, [3, 16])
- assert res == g(3, 16)
-
- def test_inlined_guard_in_short_preamble(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
- class A:
- def __init__(self, val):
- self.val = val
- def getval(self):
- return self.val
- def binop(self, other):
- return A(self.getval() + other.getval())
- def f(x, y, z):
- res = x
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
- res = res.binop(x)
- y -= 1
- if y < 7:
- x = z
- return res
- def g(x, y):
- a1 = f(A(x), y, A(x))
- a2 = f(A(x), y, A(x))
- assert a1.val == a2.val
- return a1.val
- res = self.meta_interp(g, [3, 14])
- assert res == g(3, 14)
-
- def test_specialied_bridge(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
- class A:
- def __init__(self, val):
- self.val = val
- def binop(self, other):
- return A(self.val + other.val)
- def f(x, y):
- res = A(0)
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, res=res)
- res = res.binop(A(y))
- if y<7:
- res = x
- y -= 1
- return res
- def g(x, y):
- a1 = f(A(x), y)
- a2 = f(A(x), y)
- assert a1.val == a2.val
- return a1.val
- res = self.meta_interp(g, [6, 14])
- assert res == g(6, 14)
-
- def test_specialied_bridge_const(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'const', 'x', 'res'])
- class A:
- def __init__(self, val):
- self.val = val
- def binop(self, other):
- return A(self.val + other.val)
- def f(x, y):
- res = A(0)
- const = 7
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, res=res, const=const)
- myjitdriver.jit_merge_point(y=y, x=x, res=res, const=const)
- const = hint(const, promote=True)
- res = res.binop(A(const))
- if y<7:
- res = x
- y -= 1
- return res
- def g(x, y):
- a1 = f(A(x), y)
- a2 = f(A(x), y)
- assert a1.val == a2.val
- return a1.val
- res = self.meta_interp(g, [6, 14])
- assert res == g(6, 14)
-
- def test_multiple_specialied_zigzag(self):
- myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
- class Base:
- def __init__(self, val):
- self.val = val
- class A(Base):
- def binop(self, other):
- return A(self.val + other.val)
- def switch(self):
- return B(self.val)
- class B(Base):
- def binop(self, other):
- return B(self.val * other.val)
- def switch(self):
- return A(self.val)
- def f(x, y):
- res = x
- while y > 0:
- myjitdriver.can_enter_jit(y=y, x=x, res=res)
- myjitdriver.jit_merge_point(y=y, x=x, res=res)
- if y % 4 == 0:
- res = res.switch()
- res = res.binop(x)
- y -= 1
- return res
- def g(x, y):
- a1 = f(A(x), y)
- a2 = f(A(x), y)
- b1 = f(B(x), y)
- b2 = f(B(x), y)
- assert a1.val == a2.val
- assert b1.val == b2.val
- return a1.val + b1.val
- res = self.meta_interp(g, [3, 23])
- assert res == 7068153
- self.check_loop_count(6)
- self.check_loops(guard_true=4, guard_class=0, int_add=2, int_mul=2,
- guard_false=2)
-
- def test_dont_trace_every_iteration(self):
- myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'i', 'sa'])
-
- def main(a, b):
- i = sa = 0
- #while i < 200:
- while i < 200:
- myjitdriver.can_enter_jit(a=a, b=b, i=i, sa=sa)
- myjitdriver.jit_merge_point(a=a, b=b, i=i, sa=sa)
- if a > 0: pass
- if b < 2: pass
- sa += a % b
- i += 1
- return sa
- def g():
- return main(10, 20) + main(-10, -20)
- res = self.meta_interp(g, [])
- assert res == g()
- self.check_enter_count(2)
-
- def test_current_trace_length(self):
- myjitdriver = JitDriver(greens = ['g'], reds = ['x'])
- @dont_look_inside
- def residual():
- print "hi there"
- @unroll_safe
- def loop(g):
- y = 0
- while y < g:
- residual()
- y += 1
- def f(x, g):
- n = 0
- while x > 0:
- myjitdriver.can_enter_jit(x=x, g=g)
- myjitdriver.jit_merge_point(x=x, g=g)
- loop(g)
- x -= 1
- n = current_trace_length()
- return n
- res = self.meta_interp(f, [5, 8])
- assert 14 < res < 42
- res = self.meta_interp(f, [5, 2])
- assert 4 < res < 14
-
- def test_compute_identity_hash(self):
- from pypy.rlib.objectmodel import compute_identity_hash
- class A(object):
- pass
- def f():
- a = A()
- return compute_identity_hash(a) == compute_identity_hash(a)
- res = self.interp_operations(f, [])
- assert res
- # a "did not crash" kind of test
-
- def test_compute_unique_id(self):
- from pypy.rlib.objectmodel import compute_unique_id
- class A(object):
- pass
- def f():
- a1 = A()
- a2 = A()
- return (compute_unique_id(a1) == compute_unique_id(a1) and
- compute_unique_id(a1) != compute_unique_id(a2))
- res = self.interp_operations(f, [])
- assert res
-
- def test_wrap_around_add(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
- class A:
- pass
- def f(x):
- n = 0
- while x > 0:
- myjitdriver.can_enter_jit(x=x, n=n)
- myjitdriver.jit_merge_point(x=x, n=n)
- x += 1
- n += 1
- return n
- res = self.meta_interp(f, [sys.maxint-10])
- assert res == 11
- self.check_tree_loop_count(2)
-
- def test_wrap_around_mul(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
- class A:
- pass
- def f(x):
- n = 0
- while x > 0:
- myjitdriver.can_enter_jit(x=x, n=n)
- myjitdriver.jit_merge_point(x=x, n=n)
- x *= 2
- n += 1
- return n
- res = self.meta_interp(f, [sys.maxint>>10])
- assert res == 11
- self.check_tree_loop_count(2)
-
- def test_wrap_around_sub(self):
- myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
- class A:
- pass
- def f(x):
- n = 0
- while x < 0:
- myjitdriver.can_enter_jit(x=x, n=n)
- myjitdriver.jit_merge_point(x=x, n=n)
- x -= 1
- n += 1
- return n
- res = self.meta_interp(f, [10-sys.maxint])
- assert res == 12
- self.check_tree_loop_count(2)
-
-
-
-class TestOOtype(BasicTests, OOJitMixin):
-
- def test_oohash(self):
- def f(n):
- s = ootype.oostring(n, -1)
- return s.ll_hash()
- res = self.interp_operations(f, [5])
- assert res == ootype.oostring(5, -1).ll_hash()
-
- def test_identityhash(self):
- A = ootype.Instance("A", ootype.ROOT)
- def f():
- obj1 = ootype.new(A)
- obj2 = ootype.new(A)
- return ootype.identityhash(obj1) == ootype.identityhash(obj2)
- assert not f()
- res = self.interp_operations(f, [])
- assert not res
-
- def test_oois(self):
- A = ootype.Instance("A", ootype.ROOT)
- def f(n):
- obj1 = ootype.new(A)
- if n:
- obj2 = obj1
- else:
- obj2 = ootype.new(A)
- return obj1 is obj2
- res = self.interp_operations(f, [0])
- assert not res
- res = self.interp_operations(f, [1])
- assert res
-
- def test_oostring_instance(self):
- A = ootype.Instance("A", ootype.ROOT)
- B = ootype.Instance("B", ootype.ROOT)
- def f(n):
- obj1 = ootype.new(A)
- obj2 = ootype.new(B)
- s1 = ootype.oostring(obj1, -1)
- s2 = ootype.oostring(obj2, -1)
- ch1 = s1.ll_stritem_nonneg(1)
- ch2 = s2.ll_stritem_nonneg(1)
- return ord(ch1) + ord(ch2)
- res = self.interp_operations(f, [0])
- assert res == ord('A') + ord('B')
-
- def test_subclassof(self):
- A = ootype.Instance("A", ootype.ROOT)
- B = ootype.Instance("B", A)
- clsA = ootype.runtimeClass(A)
- clsB = ootype.runtimeClass(B)
- myjitdriver = JitDriver(greens = [], reds = ['n', 'flag', 'res'])
-
- def getcls(flag):
- if flag:
- return clsA
- else:
- return clsB
-
- def f(flag, n):
- res = True
- while n > -100:
- myjitdriver.can_enter_jit(n=n, flag=flag, res=res)
- myjitdriver.jit_merge_point(n=n, flag=flag, res=res)
- cls = getcls(flag)
- n -= 1
- res = ootype.subclassof(cls, clsB)
- return res
-
- res = self.meta_interp(f, [1, 100],
- policy=StopAtXPolicy(getcls),
- enable_opts='')
- assert not res
-
- res = self.meta_interp(f, [0, 100],
- policy=StopAtXPolicy(getcls),
- enable_opts='')
- assert res
-
-class BaseLLtypeTests(BasicTests):
-
- def test_identityhash(self):
- A = lltype.GcStruct("A")
- def f():
- obj1 = lltype.malloc(A)
- obj2 = lltype.malloc(A)
- return lltype.identityhash(obj1) == lltype.identityhash(obj2)
- assert not f()
- res = self.interp_operations(f, [])
- assert not res
-
- def test_oops_on_nongc(self):
- from pypy.rpython.lltypesystem import lltype
-
- TP = lltype.Struct('x')
- def f(i1, i2):
- p1 = prebuilt[i1]
- p2 = prebuilt[i2]
- a = p1 is p2
- b = p1 is not p2
- c = bool(p1)
- d = not bool(p2)
- return 1000*a + 100*b + 10*c + d
- prebuilt = [lltype.malloc(TP, flavor='raw', immortal=True)] * 2
- expected = f(0, 1)
- assert self.interp_operations(f, [0, 1]) == expected
-
- def test_casts(self):
- py.test.skip("xxx fix or kill")
- if not self.basic:
- py.test.skip("test written in a style that "
- "means it's frontend only")
- from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-
- TP = lltype.GcStruct('S1')
- def f(p):
- n = lltype.cast_ptr_to_int(p)
- return n
- x = lltype.malloc(TP)
- xref = lltype.cast_opaque_ptr(llmemory.GCREF, x)
- res = self.interp_operations(f, [xref])
- y = llmemory.cast_ptr_to_adr(x)
- y = llmemory.cast_adr_to_int(y)
- assert rffi.get_real_int(res) == rffi.get_real_int(y)
- #
- TP = lltype.Struct('S2')
- prebuilt = [lltype.malloc(TP, immortal=True),
- lltype.malloc(TP, immortal=True)]
- def f(x):
- p = prebuilt[x]
- n = lltype.cast_ptr_to_int(p)
- return n
- res = self.interp_operations(f, [1])
- y = llmemory.cast_ptr_to_adr(prebuilt[1])
- y = llmemory.cast_adr_to_int(y)
- assert rffi.get_real_int(res) == rffi.get_real_int(y)
-
- def test_collapsing_ptr_eq(self):
- S = lltype.GcStruct('S')
- p = lltype.malloc(S)
- driver = JitDriver(greens = [], reds = ['n', 'x'])
-
- def f(n, x):
- while n > 0:
- driver.can_enter_jit(n=n, x=x)
- driver.jit_merge_point(n=n, x=x)
- if x:
- n -= 1
- n -= 1
-
- def main():
- f(10, p)
- f(10, lltype.nullptr(S))
-
- self.meta_interp(main, [])
-
- def test_enable_opts(self):
- jitdriver = JitDriver(greens = [], reds = ['a'])
-
- class A(object):
- def __init__(self, i):
- self.i = i
-
- def f():
- a = A(0)
-
- while a.i < 10:
- jitdriver.jit_merge_point(a=a)
- jitdriver.can_enter_jit(a=a)
- a = A(a.i + 1)
-
- self.meta_interp(f, [])
- self.check_loops(new_with_vtable=0)
- self.meta_interp(f, [], enable_opts='')
- self.check_loops(new_with_vtable=1)
-
-class TestLLtype(BaseLLtypeTests, LLJitMixin):
- pass
diff --git a/pypy/jit/metainterp/test/support.py b/pypy/jit/metainterp/test/support.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/test/support.py
@@ -0,0 +1,261 @@
+
+import py, sys
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
+from pypy.jit.backend.llgraph import runner
+from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
+from pypy.jit.metainterp.optimizeopt import ALL_OPTS_DICT
+from pypy.jit.metainterp import pyjitpl, history
+from pypy.jit.metainterp.warmstate import set_future_value
+from pypy.jit.codewriter.policy import JitPolicy
+from pypy.jit.codewriter import longlong
+
+def _get_jitcodes(testself, CPUClass, func, values, type_system,
+ supports_longlong=False, **kwds):
+ from pypy.jit.codewriter import support, codewriter
+
+ class FakeJitCell:
+ __compiled_merge_points = []
+ def get_compiled_merge_points(self):
+ return self.__compiled_merge_points[:]
+ def set_compiled_merge_points(self, lst):
+ self.__compiled_merge_points = lst
+
+ class FakeWarmRunnerState:
+ def attach_unoptimized_bridge_from_interp(self, greenkey, newloop):
+ pass
+
+ def jit_cell_at_key(self, greenkey):
+ assert greenkey == []
+ return self._cell
+ _cell = FakeJitCell()
+
+ trace_limit = sys.maxint
+ enable_opts = ALL_OPTS_DICT
+
+ func._jit_unroll_safe_ = True
+ rtyper = support.annotate(func, values, type_system=type_system)
+ graphs = rtyper.annotator.translator.graphs
+ result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]
+
+ class FakeJitDriverSD:
+ num_green_args = 0
+ portal_graph = graphs[0]
+ virtualizable_info = None
+ greenfield_info = None
+ result_type = result_kind
+ portal_runner_ptr = "???"
+
+ stats = history.Stats()
+ cpu = CPUClass(rtyper, stats, None, False)
+ cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
+ testself.cw = cw
+ policy = JitPolicy()
+ policy.set_supports_longlong(supports_longlong)
+ cw.find_all_graphs(policy)
+ #
+ testself.warmrunnerstate = FakeWarmRunnerState()
+ testself.warmrunnerstate.cpu = cpu
+ FakeJitDriverSD.warmstate = testself.warmrunnerstate
+ if hasattr(testself, 'finish_setup_for_interp_operations'):
+ testself.finish_setup_for_interp_operations()
+ #
+ cw.make_jitcodes(verbose=True)
+
+def _run_with_blackhole(testself, args):
+ from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
+ cw = testself.cw
+ blackholeinterpbuilder = BlackholeInterpBuilder(cw)
+ blackholeinterp = blackholeinterpbuilder.acquire_interp()
+ count_i = count_r = count_f = 0
+ for value in args:
+ T = lltype.typeOf(value)
+ if T == lltype.Signed:
+ blackholeinterp.setarg_i(count_i, value)
+ count_i += 1
+ elif T == llmemory.GCREF:
+ blackholeinterp.setarg_r(count_r, value)
+ count_r += 1
+ elif T == lltype.Float:
+ value = longlong.getfloatstorage(value)
+ blackholeinterp.setarg_f(count_f, value)
+ count_f += 1
+ else:
+ raise TypeError(T)
+ [jitdriver_sd] = cw.callcontrol.jitdrivers_sd
+ blackholeinterp.setposition(jitdriver_sd.mainjitcode, 0)
+ blackholeinterp.run()
+ return blackholeinterp._final_result_anytype()
+
+def _run_with_pyjitpl(testself, args):
+
+ class DoneWithThisFrame(Exception):
+ pass
+
+ class DoneWithThisFrameRef(DoneWithThisFrame):
+ def __init__(self, cpu, *args):
+ DoneWithThisFrame.__init__(self, *args)
+
+ cw = testself.cw
+ opt = history.Options(listops=True)
+ metainterp_sd = pyjitpl.MetaInterpStaticData(cw.cpu, opt)
+ metainterp_sd.finish_setup(cw)
+ [jitdriver_sd] = metainterp_sd.jitdrivers_sd
+ metainterp = pyjitpl.MetaInterp(metainterp_sd, jitdriver_sd)
+ metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrame
+ metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef
+ metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrame
+ testself.metainterp = metainterp
+ try:
+ metainterp.compile_and_run_once(jitdriver_sd, *args)
+ except DoneWithThisFrame, e:
+ #if conftest.option.view:
+ # metainterp.stats.view()
+ return e.args[0]
+ else:
+ raise Exception("FAILED")
+
+def _run_with_machine_code(testself, args):
+ metainterp = testself.metainterp
+ num_green_args = metainterp.jitdriver_sd.num_green_args
+ loop_tokens = metainterp.get_compiled_merge_points(args[:num_green_args])
+ if len(loop_tokens) != 1:
+ return NotImplemented
+ # a loop was successfully created by _run_with_pyjitpl(); call it
+ cpu = metainterp.cpu
+ for i in range(len(args) - num_green_args):
+ x = args[num_green_args + i]
+ typecode = history.getkind(lltype.typeOf(x))
+ set_future_value(cpu, i, x, typecode)
+ faildescr = cpu.execute_token(loop_tokens[0])
+ assert faildescr.__class__.__name__.startswith('DoneWithThisFrameDescr')
+ if metainterp.jitdriver_sd.result_type == history.INT:
+ return cpu.get_latest_value_int(0)
+ elif metainterp.jitdriver_sd.result_type == history.REF:
+ return cpu.get_latest_value_ref(0)
+ elif metainterp.jitdriver_sd.result_type == history.FLOAT:
+ return cpu.get_latest_value_float(0)
+ else:
+ return None
+
+
+class JitMixin:
+ basic = True
+ def check_loops(self, expected=None, everywhere=False, **check):
+ get_stats().check_loops(expected=expected, everywhere=everywhere,
+ **check)
+ def check_loop_count(self, count):
+ """NB. This is a hack; use check_tree_loop_count() or
+ check_enter_count() for the real thing.
+ This counts as 1 every bridge in addition to every loop; and it does
+ not count at all the entry bridges from interpreter, although they
+ are TreeLoops as well."""
+ assert get_stats().compiled_count == count
+ def check_tree_loop_count(self, count):
+ assert len(get_stats().loops) == count
+ def check_loop_count_at_most(self, count):
+ assert get_stats().compiled_count <= count
+ def check_enter_count(self, count):
+ assert get_stats().enter_count == count
+ def check_enter_count_at_most(self, count):
+ assert get_stats().enter_count <= count
+ def check_jumps(self, maxcount):
+ assert get_stats().exec_jumps <= maxcount
+ def check_aborted_count(self, count):
+ assert get_stats().aborted_count == count
+ def check_aborted_count_at_least(self, count):
+ assert get_stats().aborted_count >= count
+
+ def meta_interp(self, *args, **kwds):
+ kwds['CPUClass'] = self.CPUClass
+ kwds['type_system'] = self.type_system
+ if "backendopt" not in kwds:
+ kwds["backendopt"] = False
+ return ll_meta_interp(*args, **kwds)
+
+ def interp_operations(self, f, args, **kwds):
+ # get the JitCodes for the function f
+ _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
+ # try to run it with blackhole.py
+ result1 = _run_with_blackhole(self, args)
+ # try to run it with pyjitpl.py
+ result2 = _run_with_pyjitpl(self, args)
+ assert result1 == result2
+ # try to run it by running the code compiled just before
+ result3 = _run_with_machine_code(self, args)
+ assert result1 == result3 or result3 == NotImplemented
+ #
+ if (longlong.supports_longlong and
+ isinstance(result1, longlong.r_float_storage)):
+ result1 = longlong.getrealfloat(result1)
+ return result1
+
+ def check_history(self, expected=None, **isns):
+ # this can be used after calling meta_interp
+ get_stats().check_history(expected, **isns)
+
+ def check_operations_history(self, expected=None, **isns):
+ # this can be used after interp_operations
+ if expected is not None:
+ expected = dict(expected)
+ expected['jump'] = 1
+ self.metainterp.staticdata.stats.check_history(expected, **isns)
+
+
+class LLJitMixin(JitMixin):
+ type_system = 'lltype'
+ CPUClass = runner.LLtypeCPU
+
+ @staticmethod
+ def Ptr(T):
+ return lltype.Ptr(T)
+
+ @staticmethod
+ def GcStruct(name, *fields, **kwds):
+ S = lltype.GcStruct(name, *fields, **kwds)
+ return S
+
+ malloc = staticmethod(lltype.malloc)
+ nullptr = staticmethod(lltype.nullptr)
+
+ @staticmethod
+ def malloc_immortal(T):
+ return lltype.malloc(T, immortal=True)
+
+ def _get_NODE(self):
+ NODE = lltype.GcForwardReference()
+ NODE.become(lltype.GcStruct('NODE', ('value', lltype.Signed),
+ ('next', lltype.Ptr(NODE))))
+ return NODE
+
+class OOJitMixin(JitMixin):
+ type_system = 'ootype'
+ #CPUClass = runner.OOtypeCPU
+
+ def setup_class(cls):
+ py.test.skip("ootype tests skipped for now")
+
+ @staticmethod
+ def Ptr(T):
+ return T
+
+ @staticmethod
+ def GcStruct(name, *fields, **kwds):
+ if 'hints' in kwds:
+ kwds['_hints'] = kwds['hints']
+ del kwds['hints']
+ I = ootype.Instance(name, ootype.ROOT, dict(fields), **kwds)
+ return I
+
+ malloc = staticmethod(ootype.new)
+ nullptr = staticmethod(ootype.null)
+
+ @staticmethod
+ def malloc_immortal(T):
+ return ootype.new(T)
+
+ def _get_NODE(self):
+ NODE = ootype.Instance('NODE', ootype.ROOT, {})
+ NODE._add_fields({'value': ootype.Signed,
+ 'next': NODE})
+ return NODE
diff --git a/pypy/jit/backend/cli/test/test_basic.py b/pypy/jit/backend/cli/test/test_basic.py
--- a/pypy/jit/backend/cli/test/test_basic.py
+++ b/pypy/jit/backend/cli/test/test_basic.py
@@ -1,14 +1,14 @@
import py
from pypy.jit.backend.cli.runner import CliCPU
-from pypy.jit.metainterp.test import test_basic
+from pypy.jit.metainterp.test import support, test_ajit
-class CliJitMixin(test_basic.OOJitMixin):
+class CliJitMixin(suport.OOJitMixin):
CPUClass = CliCPU
def setup_class(cls):
from pypy.translator.cli.support import PythonNet
PythonNet.System # possibly raises Skip
-class TestBasic(CliJitMixin, test_basic.TestOOtype):
+class TestBasic(CliJitMixin, test_ajit.TestOOtype):
# for the individual tests see
# ====> ../../../metainterp/test/test_basic.py
diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -20,8 +20,7 @@
separate_module_files=[cdir.join('src', 'll_math.c')],
export_symbols=['_pypy_math_acosh', '_pypy_math_asinh',
'_pypy_math_atanh',
- '_pypy_math_expm1', '_pypy_math_log1p',
- '_pypy_math_isinf', '_pypy_math_isnan'],
+ '_pypy_math_expm1', '_pypy_math_log1p'],
)
math_prefix = '_pypy_math_'
else:
@@ -57,8 +56,6 @@
math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
math_hypot = llexternal(underscore + 'hypot',
[rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
-math_isinf = math_llexternal('isinf', [rffi.DOUBLE], rffi.INT)
-math_isnan = math_llexternal('isnan', [rffi.DOUBLE], rffi.INT)
# ____________________________________________________________
#
@@ -91,13 +88,13 @@
#
# Custom implementations
- at jit.purefunction
def ll_math_isnan(y):
- return bool(math_isnan(y))
+ # By not calling into the extenal function the JIT can inline this. Floats
+ # are awesome.
+ return y != y
- at jit.purefunction
def ll_math_isinf(y):
- return bool(math_isinf(y))
+ return y != 0 and y * .5 == y
ll_math_copysign = math_copysign
diff --git a/pypy/jit/metainterp/test/test_dict.py b/pypy/jit/metainterp/test/test_dict.py
--- a/pypy/jit/metainterp/test/test_dict.py
+++ b/pypy/jit/metainterp/test/test_dict.py
@@ -1,5 +1,5 @@
import py
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rlib.jit import JitDriver
from pypy.rlib import objectmodel
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -1,3 +1,5 @@
+from __future__ import with_statement
+
import re
from pypy.rpython.lltypesystem import rffi, lltype
@@ -509,7 +511,7 @@
"oct(x)"),
UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
"hex(x)"),
- NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
+ NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
"x[y:z] <==> x[y.__index__():z.__index__()]"),
IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
wrap_binaryfunc, "+"),
diff --git a/pypy/jit/metainterp/test/test_jitprof.py b/pypy/jit/metainterp/test/test_jitprof.py
--- a/pypy/jit/metainterp/test/test_jitprof.py
+++ b/pypy/jit/metainterp/test/test_jitprof.py
@@ -1,7 +1,7 @@
from pypy.jit.metainterp.warmspot import ll_meta_interp
from pypy.rlib.jit import JitDriver, dont_look_inside, purefunction
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.jit.metainterp import pyjitpl
from pypy.jit.metainterp.jitprof import *
diff --git a/pypy/jit/tl/pypyjit_child.py b/pypy/jit/tl/pypyjit_child.py
--- a/pypy/jit/tl/pypyjit_child.py
+++ b/pypy/jit/tl/pypyjit_child.py
@@ -2,7 +2,6 @@
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp import warmspot
from pypy.module.pypyjit.policy import PyPyJitPolicy
-from pypy.rlib.jit import OPTIMIZER_FULL, OPTIMIZER_NO_UNROLL
def run_child(glob, loc):
@@ -34,6 +33,5 @@
option.view = True
warmspot.jittify_and_run(interp, graph, [], policy=policy,
listops=True, CPUClass=CPUClass,
- backendopt=True, inline=True,
- optimizer=OPTIMIZER_FULL)
+ backendopt=True, inline=True)
diff --git a/pypy/translator/goal/translate.py b/pypy/translator/goal/translate.py
--- a/pypy/translator/goal/translate.py
+++ b/pypy/translator/goal/translate.py
@@ -285,6 +285,15 @@
elif drv.exe_name is None and '__name__' in targetspec_dic:
drv.exe_name = targetspec_dic['__name__'] + '-%(backend)s'
+ # Double check to ensure we are not overwriting the current interpreter
+ try:
+ exe_name = str(drv.compute_exe_name())
+ assert not os.path.samefile(exe_name, sys.executable), (
+ 'Output file %r is the currently running '
+ 'interpreter (use --output=...)'% exe_name)
+ except OSError:
+ pass
+
goals = translateconfig.goals
try:
drv.proceed(goals)
diff --git a/pypy/jit/backend/x86/test/test_basic.py b/pypy/jit/backend/x86/test/test_basic.py
--- a/pypy/jit/backend/x86/test/test_basic.py
+++ b/pypy/jit/backend/x86/test/test_basic.py
@@ -1,18 +1,18 @@
import py
from pypy.jit.backend.detect_cpu import getcpuclass
from pypy.jit.metainterp.warmspot import ll_meta_interp
-from pypy.jit.metainterp.test import test_basic
+from pypy.jit.metainterp.test import support, test_ajit
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.rlib.jit import JitDriver
-class Jit386Mixin(test_basic.LLJitMixin):
+class Jit386Mixin(support.LLJitMixin):
type_system = 'lltype'
CPUClass = getcpuclass()
def check_jumps(self, maxcount):
pass
-class TestBasic(Jit386Mixin, test_basic.BaseLLtypeTests):
+class TestBasic(Jit386Mixin, test_ajit.BaseLLtypeTests):
# for the individual tests see
# ====> ../../../metainterp/test/test_basic.py
def test_bug(self):
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -154,6 +154,24 @@
self.emit_operation(op)
+ def optimize_INT_LSHIFT(self, op):
+ v1 = self.getvalue(op.getarg(0))
+ v2 = self.getvalue(op.getarg(1))
+
+ if v2.is_constant() and v2.box.getint() == 0:
+ self.make_equal_to(op.result, v1)
+ else:
+ self.emit_operation(op)
+
+ def optimize_INT_RSHIFT(self, op):
+ v1 = self.getvalue(op.getarg(0))
+ v2 = self.getvalue(op.getarg(1))
+
+ if v2.is_constant() and v2.box.getint() == 0:
+ self.make_equal_to(op.result, v1)
+ else:
+ self.emit_operation(op)
+
def optimize_CALL_PURE(self, op):
arg_consts = []
for i in range(op.numargs()):
diff --git a/pypy/jit/metainterp/test/test_del.py b/pypy/jit/metainterp/test/test_del.py
--- a/pypy/jit/metainterp/test/test_del.py
+++ b/pypy/jit/metainterp/test/test_del.py
@@ -1,6 +1,6 @@
import py
from pypy.rlib.jit import JitDriver
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class DelTests:
diff --git a/pypy/tool/jitlogparser/test/test_parser.py b/pypy/tool/jitlogparser/test/test_parser.py
--- a/pypy/tool/jitlogparser/test/test_parser.py
+++ b/pypy/tool/jitlogparser/test/test_parser.py
@@ -114,11 +114,11 @@
fname = str(py.path.local(__file__).join('..', 'x.py'))
ops = parse('''
[i0, i1]
- debug_merge_point("<code object f, file '%(fname)s', line 5> #9 LOAD_FAST", 0)
- debug_merge_point("<code object f, file '%(fname)s', line 5> #12 LOAD_CONST", 0)
- debug_merge_point("<code object f, file '%(fname)s', line 5> #22 LOAD_CONST", 0)
- debug_merge_point("<code object f, file '%(fname)s', line 5> #28 LOAD_CONST", 0)
- debug_merge_point("<code object f, file '%(fname)s', line 5> #6 SETUP_LOOP", 0)
+ debug_merge_point("<code object g, file '%(fname)s', line 5> #9 LOAD_FAST", 0)
+ debug_merge_point("<code object g, file '%(fname)s', line 5> #12 LOAD_CONST", 0)
+ debug_merge_point("<code object g, file '%(fname)s', line 5> #22 LOAD_CONST", 0)
+ debug_merge_point("<code object g, file '%(fname)s', line 5> #28 LOAD_CONST", 0)
+ debug_merge_point("<code object g, file '%(fname)s', line 5> #6 SETUP_LOOP", 0)
''' % locals())
res = Function.from_operations(ops.operations, LoopStorage())
assert res.linerange == (7, 9)
diff --git a/pypy/jit/metainterp/test/test_fficall.py b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -5,7 +5,7 @@
from pypy.rlib.libffi import ArgChain
from pypy.rlib.test.test_libffi import TestLibffiCall as _TestLibffiCall
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin
class TestFfiCall(LLJitMixin, _TestLibffiCall):
diff --git a/pypy/translator/jvm/test/test_list.py b/pypy/translator/jvm/test/test_list.py
--- a/pypy/translator/jvm/test/test_list.py
+++ b/pypy/translator/jvm/test/test_list.py
@@ -6,7 +6,10 @@
def test_recursive(self):
py.test.skip("JVM doesn't support recursive lists")
- def test_getitem_exc(self):
+ def test_getitem_exc_1(self):
+ py.test.skip('fixme!')
+
+ def test_getitem_exc_2(self):
py.test.skip('fixme!')
def test_r_short_list(self):
diff --git a/pypy/translator/jvm/opcodes.py b/pypy/translator/jvm/opcodes.py
--- a/pypy/translator/jvm/opcodes.py
+++ b/pypy/translator/jvm/opcodes.py
@@ -106,6 +106,10 @@
'debug_catch_exception': Ignore,
'debug_reraise_traceback': Ignore,
'debug_print_traceback': Ignore,
+ 'debug_start': Ignore,
+ 'debug_stop': Ignore,
+ 'debug_print': Ignore,
+ 'keepalive': Ignore,
# __________ numeric operations __________
@@ -144,6 +148,7 @@
'int_xor_ovf': jvm.IXOR,
'int_floordiv_ovf_zer': jvm.IFLOORDIVZEROVF,
'int_mod_ovf_zer': _check_zer(jvm.IREMOVF),
+ 'int_between': jvm.PYPYINTBETWEEN,
'uint_invert': 'bitwise_negate',
@@ -185,8 +190,8 @@
'llong_mod_zer': _check_zer(jvm.LREM),
'llong_and': jvm.LAND,
'llong_or': jvm.LOR,
- 'llong_lshift': [PushAllArgs, jvm.L2I, jvm.LSHL, StoreResult],
- 'llong_rshift': [PushAllArgs, jvm.L2I, jvm.LSHR, StoreResult],
+ 'llong_lshift': [PushAllArgs, jvm.LSHL, StoreResult],
+ 'llong_rshift': [PushAllArgs, jvm.LSHR, StoreResult],
'llong_xor': jvm.LXOR,
'llong_floordiv_ovf': jvm.LFLOORDIVOVF,
'llong_floordiv_ovf_zer': jvm.LFLOORDIVZEROVF,
@@ -202,9 +207,11 @@
'ullong_truediv': None, # TODO
'ullong_floordiv': jvm.LDIV, # valid?
'ullong_mod': jvm.PYPYULONGMOD,
- 'ullong_lshift': [PushAllArgs, jvm.L2I, jvm.LSHL, StoreResult],
- 'ullong_rshift': [PushAllArgs, jvm.L2I, jvm.LUSHR, StoreResult],
+ 'ullong_lshift': [PushAllArgs, jvm.LSHL, StoreResult],
+ 'ullong_rshift': [PushAllArgs, jvm.LUSHR, StoreResult],
'ullong_mod_zer': jvm.PYPYULONGMOD,
+ 'ullong_or': jvm.LOR,
+ 'ullong_and': jvm.LAND,
# when casting from bool we want that every truth value is casted
# to 1: we can't simply DoNothing, because the CLI stack could
@@ -227,5 +234,8 @@
'cast_float_to_uint': jvm.PYPYDOUBLETOUINT,
'truncate_longlong_to_int': jvm.L2I,
'cast_longlong_to_float': jvm.L2D,
+ 'cast_float_to_ulonglong': jvm.PYPYDOUBLETOULONG,
+ 'cast_ulonglong_to_float': jvm.PYPYULONGTODOUBLE,
'cast_primitive': [PushAllArgs, CastPrimitive, StoreResult],
+ 'force_cast': [PushAllArgs, CastPrimitive, StoreResult],
})
diff --git a/pypy/translator/jvm/src/pypy/StatResult.java b/pypy/translator/jvm/src/pypy/StatResult.java
--- a/pypy/translator/jvm/src/pypy/StatResult.java
+++ b/pypy/translator/jvm/src/pypy/StatResult.java
@@ -8,7 +8,7 @@
*
* <p>The actual stat() function is defined in PyPy.java.
*/
-class StatResult {
+public class StatResult {
public int item0, item3, item4, item5;
public long item1, item2, item6;
public double item7, item8, item9;
diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py
--- a/pypy/jit/metainterp/test/test_float.py
+++ b/pypy/jit/metainterp/test/test_float.py
@@ -1,5 +1,5 @@
import math
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class FloatTests:
diff --git a/pypy/jit/tl/tla/test_tla.py b/pypy/jit/tl/tla/test_tla.py
--- a/pypy/jit/tl/tla/test_tla.py
+++ b/pypy/jit/tl/tla/test_tla.py
@@ -155,7 +155,7 @@
# ____________________________________________________________
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin
class TestLLtype(LLJitMixin):
def test_loop(self):
diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -717,6 +717,7 @@
def test_random_function(BuilderClass=OperationBuilder):
r = Random()
cpu = get_cpu()
+ cpu.setup_once()
if pytest.config.option.repeat == -1:
while 1:
check_random_function(cpu, BuilderClass, r)
diff --git a/pypy/jit/metainterp/test/test_loop_unroll.py b/pypy/jit/metainterp/test/test_loop_unroll.py
--- a/pypy/jit/metainterp/test/test_loop_unroll.py
+++ b/pypy/jit/metainterp/test/test_loop_unroll.py
@@ -1,7 +1,7 @@
import py
from pypy.rlib.jit import JitDriver
from pypy.jit.metainterp.test import test_loop
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES
class LoopUnrollTest(test_loop.LoopTest):
diff --git a/pypy/tool/jitlogparser/storage.py b/pypy/tool/jitlogparser/storage.py
--- a/pypy/tool/jitlogparser/storage.py
+++ b/pypy/tool/jitlogparser/storage.py
@@ -30,18 +30,18 @@
self.codes[fname] = res
return res
- def disassemble_code(self, fname, startlineno):
+ def disassemble_code(self, fname, startlineno, name):
try:
if py.path.local(fname).check(file=False):
return None # cannot find source file
except py.error.EACCES:
return None # cannot open the file
- key = (fname, startlineno)
+ key = (fname, startlineno, name)
try:
return self.disassembled_codes[key]
except KeyError:
codeobjs = self.load_code(fname)
- if startlineno not in codeobjs:
+ if (startlineno, name) not in codeobjs:
# cannot find the code obj at this line: this can happen for
# various reasons, e.g. because the .py files changed since
# the log was produced, or because the co_firstlineno
@@ -49,7 +49,7 @@
# produced by gateway.applevel(), such as the ones found in
# nanos.py)
return None
- code = codeobjs[startlineno]
+ code = codeobjs[(startlineno, name)]
res = dis(code)
self.disassembled_codes[key] = res
return res
diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py
--- a/pypy/jit/metainterp/test/test_recursive.py
+++ b/pypy/jit/metainterp/test/test_recursive.py
@@ -3,7 +3,7 @@
from pypy.rlib.jit import unroll_safe, dont_look_inside
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.debug import fatalerror
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.rpython.annlowlevel import hlstr
from pypy.jit.metainterp.warmspot import get_stats
diff --git a/pypy/translator/jvm/test/test_extreme.py b/pypy/translator/jvm/test/test_extreme.py
--- a/pypy/translator/jvm/test/test_extreme.py
+++ b/pypy/translator/jvm/test/test_extreme.py
@@ -1,5 +1,8 @@
+import py
from pypy.translator.jvm.test.runtest import JvmTest
from pypy.translator.oosupport.test_template.extreme import BaseTestExtreme
class TestExtreme(BaseTestExtreme, JvmTest):
- pass
+
+ def test_runtimeerror_due_to_stack_overflow(self):
+ py.test.skip('hotspot bug')
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -1645,7 +1645,7 @@
darwin64='')
print >> output, "%s:" % _globalname('pypy_asm_stackwalk')
- print >> output, """\
+ s = """\
/* See description in asmgcroot.py */
.cfi_startproc
movq\t%rdi, %rdx\t/* 1st argument, which is the callback */
@@ -1691,6 +1691,12 @@
ret
.cfi_endproc
"""
+ if self.format == 'darwin64':
+ # obscure. gcc there seems not to support .cfi_...
+ # hack it out...
+ s = re.sub(r'([.]cfi_[^/\n]+)([/\n])',
+ r'/* \1 disabled on darwin */\2', s)
+ print >> output, s
_variant(elf64='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk',
darwin64='')
else:
diff --git a/pypy/translator/jvm/test/test_builtin.py b/pypy/translator/jvm/test/test_builtin.py
--- a/pypy/translator/jvm/test/test_builtin.py
+++ b/pypy/translator/jvm/test/test_builtin.py
@@ -37,6 +37,15 @@
def test_cast_primitive(self):
py.test.skip('fixme!')
+ def test_os_fstat(self):
+ import os, stat
+ def fn():
+ fd = os.open(__file__, os.O_RDONLY, 0)
+ st = os.fstat(fd)
+ os.close(fd)
+ return st.st_mode
+ res = self.interpret(fn, [])
+ assert stat.S_ISREG(res)
class TestJvmTime(JvmTest, BaseTestTime):
diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py
--- a/pypy/jit/metainterp/test/test_loop.py
+++ b/pypy/jit/metainterp/test/test_loop.py
@@ -2,7 +2,7 @@
from pypy.rlib.jit import JitDriver
from pypy.rlib.objectmodel import compute_hash
from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp import history
diff --git a/pypy/jit/metainterp/test/test_immutable.py b/pypy/jit/metainterp/test/test_immutable.py
--- a/pypy/jit/metainterp/test/test_immutable.py
+++ b/pypy/jit/metainterp/test/test_immutable.py
@@ -1,4 +1,4 @@
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class ImmutableFieldsTests:
diff --git a/lib_pypy/_ctypes/builtin.py b/lib_pypy/_ctypes/builtin.py
--- a/lib_pypy/_ctypes/builtin.py
+++ b/lib_pypy/_ctypes/builtin.py
@@ -1,6 +1,9 @@
import _rawffi, sys
-import threading
+try:
+ from thread import _local as local
+except ImportError:
+ local = object # no threads
class ConvMode:
encoding = 'ascii'
@@ -28,7 +31,7 @@
arg = cobj._get_buffer_value()
return _rawffi.wcharp2rawunicode(arg, lgt)
-class ErrorObject(threading.local):
+class ErrorObject(local):
def __init__(self):
self.errno = 0
self.winerror = 0
diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -107,7 +107,8 @@
self.bytecode_no = int(bytecode_no)
self.operations = operations
self.storage = storage
- self.code = storage.disassemble_code(self.filename, self.startlineno)
+ self.code = storage.disassemble_code(self.filename, self.startlineno,
+ self.name)
def repr(self):
if self.filename is None:
diff --git a/pypy/jit/tl/spli/test/test_jit.py b/pypy/jit/tl/spli/test/test_jit.py
--- a/pypy/jit/tl/spli/test/test_jit.py
+++ b/pypy/jit/tl/spli/test/test_jit.py
@@ -1,6 +1,6 @@
import py
-from pypy.jit.metainterp.test.test_basic import JitMixin
+from pypy.jit.metainterp.test.support import JitMixin
from pypy.jit.tl.spli import interpreter, objects, serializer
from pypy.jit.metainterp.typesystem import LLTypeHelper, OOTypeHelper
from pypy.jit.backend.llgraph import runner
diff --git a/pypy/jit/metainterp/test/test_memmgr.py b/pypy/jit/metainterp/test/test_memmgr.py
--- a/pypy/jit/metainterp/test/test_memmgr.py
+++ b/pypy/jit/metainterp/test/test_memmgr.py
@@ -12,7 +12,7 @@
import py
from pypy.jit.metainterp.memmgr import MemoryManager
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.rlib.jit import JitDriver, dont_look_inside
diff --git a/pypy/translator/jvm/src/pypy/ll_os.java b/pypy/translator/jvm/src/pypy/ll_os.java
--- a/pypy/translator/jvm/src/pypy/ll_os.java
+++ b/pypy/translator/jvm/src/pypy/ll_os.java
@@ -14,10 +14,22 @@
abstract class FileWrapper
{
+ private final String name;
+
+ public FileWrapper(String name)
+ {
+ this.name = name;
+ }
+
public abstract void write(String buffer);
public abstract String read(int count);
public abstract void close();
public abstract RandomAccessFile getFile();
+
+ public String getName()
+ {
+ return this.name;
+ }
}
class PrintStreamWrapper extends FileWrapper
@@ -25,8 +37,9 @@
private final PrintStream stream;
private final ll_os os;
- public PrintStreamWrapper(PrintStream stream, ll_os os)
+ public PrintStreamWrapper(String name, PrintStream stream, ll_os os)
{
+ super(name);
this.stream = stream;
this.os = os;
}
@@ -58,8 +71,9 @@
private final InputStream stream;
private final ll_os os;
- public InputStreamWrapper(InputStream stream, ll_os os)
+ public InputStreamWrapper(String name, InputStream stream, ll_os os)
{
+ super(name);
this.stream = stream;
this.os = os;
}
@@ -102,11 +116,13 @@
private final boolean canWrite;
private final ll_os os;
- public RandomAccessFileWrapper(RandomAccessFile file,
+ public RandomAccessFileWrapper(String name,
+ RandomAccessFile file,
boolean canRead,
boolean canWrite,
ll_os os)
{
+ super(name);
this.file = file;
this.canRead = canRead;
this.canWrite = canWrite;
@@ -228,9 +244,9 @@
public ll_os(Interlink interlink) {
this.interlink = interlink;
- FileDescriptors.put(0, new InputStreamWrapper(System.in, this));
- FileDescriptors.put(1, new PrintStreamWrapper(System.out, this));
- FileDescriptors.put(2, new PrintStreamWrapper(System.err, this));
+ FileDescriptors.put(0, new InputStreamWrapper("<stdin>", System.in, this));
+ FileDescriptors.put(1, new PrintStreamWrapper("<stdout>", System.out, this));
+ FileDescriptors.put(2, new PrintStreamWrapper("<stderr>", System.err, this));
fdcount = 2;
}
@@ -339,7 +355,7 @@
// XXX: we ignore O_CREAT
RandomAccessFile file = open_file(name, javaMode, flags);
RandomAccessFileWrapper wrapper =
- new RandomAccessFileWrapper(file, canRead, canWrite, this);
+ new RandomAccessFileWrapper(name, file, canRead, canWrite, this);
fdcount++;
FileDescriptors.put(fdcount, wrapper);
@@ -418,6 +434,12 @@
return ll_os_stat(path); // XXX
}
+ public StatResult ll_os_fstat(int fd)
+ {
+ String name = getfd(fd).getName();
+ return ll_os_stat(name);
+ }
+
public String ll_os_strerror(int errno)
{
String msg = ErrorMessages.remove(errno);
diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py
--- a/pypy/jit/metainterp/test/test_virtual.py
+++ b/pypy/jit/metainterp/test/test_virtual.py
@@ -2,7 +2,7 @@
from pypy.rlib.jit import JitDriver, hint
from pypy.rlib.objectmodel import compute_unique_id
from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rpython.lltypesystem import lltype, rclass
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.ootypesystem import ootype
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -250,7 +250,6 @@
# this is the ticker check generated in PyFrame.handle_operation_error
exc_ticker_check = """
ticker2 = getfield_raw(ticker_address, descr=<SignedFieldDescr pypysig_long_struct.c_value .*>)
- setfield_gc(_, _, descr=<GcPtrFieldDescr pypy.interpreter.pyframe.PyFrame.inst_w_f_trace .*>)
ticker_cond1 = int_lt(ticker2, 0)
guard_false(ticker_cond1, descr=...)
"""
@@ -266,7 +265,7 @@
if exp_v2 == '_':
return True
if self.is_const(v1) or self.is_const(exp_v2):
- return v1 == exp_v2
+ return v1[:-1].startswith(exp_v2[:-1])
if v1 not in self.alpha_map:
self.alpha_map[v1] = exp_v2
return self.alpha_map[v1] == exp_v2
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -22,14 +22,20 @@
return func.code
class Defaults(object):
- _immutable_fields_ = ["items[*]"]
+ _immutable_fields_ = ["items[*]", "promote"]
- def __init__(self, items):
+ def __init__(self, items, promote=False):
self.items = items
+ self.promote = promote
def getitems(self):
- ## XXX! we would like: return jit.hint(self, promote=True).items
- ## XXX! but it gives horrible performance in some cases
+ # an idea - we want to promote only items that we know won't change
+ # too often. this is the case for builtin functions and functions
+ # with known constant defaults. Otherwise we don't want to promote
+ # this so lambda a=a won't create a new trace each time it's
+ # encountered
+ if self.promote:
+ return jit.hint(self, promote=True).items
return self.items
def getitem(self, idx):
@@ -46,14 +52,15 @@
can_change_code = True
def __init__(self, space, code, w_globals=None, defs_w=[], closure=None,
- forcename=None):
+ forcename=None, promote_defs=False):
self.space = space
self.name = forcename or code.co_name
self.w_doc = None # lazily read from code.getdocstring()
self.code = code # Code instance
self.w_func_globals = w_globals # the globals dictionary
self.closure = closure # normally, list of Cell instances or None
- self.defs = Defaults(defs_w) # wrapper around list of w_default's
+ self.defs = Defaults(defs_w, promote=promote_defs)
+ # wrapper around list of w_default's
self.w_func_dict = None # filled out below if needed
self.w_module = None
@@ -622,7 +629,8 @@
def __init__(self, func):
assert isinstance(func, Function)
Function.__init__(self, func.space, func.code, func.w_func_globals,
- func.defs.getitems(), func.closure, func.name)
+ func.defs.getitems(), func.closure, func.name,
+ promote_defs=True)
self.w_doc = func.w_doc
self.w_func_dict = func.w_func_dict
self.w_module = func.w_module
diff --git a/pypy/jit/metainterp/test/test_warmspot.py b/pypy/jit/metainterp/test/test_warmspot.py
--- a/pypy/jit/metainterp/test/test_warmspot.py
+++ b/pypy/jit/metainterp/test/test_warmspot.py
@@ -6,7 +6,7 @@
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.history import BoxInt
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES
diff --git a/pypy/module/pypyjit/test/test_pypy_c.py b/pypy/module/pypyjit/test/test_pypy_c.py
--- a/pypy/module/pypyjit/test/test_pypy_c.py
+++ b/pypy/module/pypyjit/test/test_pypy_c.py
@@ -198,44 +198,6 @@
print
print '@' * 79
- def test_f1(self):
- self.run_source('''
- def main(n):
- "Arbitrary test function."
- i = 0
- x = 1
- while i<n:
- j = 0 #ZERO
- while j<=i:
- j = j + 1
- x = x + (i&j)
- i = i + 1
- return x
- ''', 220,
- ([2117], 1083876708))
-
- def test_factorial(self):
- self.run_source('''
- def main(n):
- r = 1
- while n > 1:
- r *= n
- n -= 1
- return r
- ''', 28,
- ([5], 120),
- ([25], 15511210043330985984000000L))
-
- def test_factorialrec(self):
- self.run_source('''
- def main(n):
- if n > 1:
- return n * main(n-1)
- else:
- return 1
- ''', 0,
- ([5], 120),
- ([25], 15511210043330985984000000L))
def test_richards(self):
self.run_source('''
@@ -247,529 +209,6 @@
''' % (sys.path,), 7200,
([], 42))
- def test_simple_call(self):
- self.run_source('''
- OFFSET = 0
- def f(i):
- return i + 1 + OFFSET
- def main(n):
- i = 0
- while i < n+OFFSET:
- i = f(f(i))
- return i
- ''', 98,
- ([20], 20),
- ([31], 32))
- ops = self.get_by_bytecode("LOAD_GLOBAL", True)
- assert len(ops) == 5
- assert ops[0].get_opnames() == ["guard_value",
- "getfield_gc", "guard_value",
- "getfield_gc", "guard_isnull",
- "getfield_gc", "guard_nonnull_class"]
- # the second getfield on the same globals is quicker
- assert ops[1].get_opnames() == ["getfield_gc", "guard_nonnull_class"]
- assert not ops[2] # second LOAD_GLOBAL of the same name folded away
- # LOAD_GLOBAL of the same name but in different function partially
- # folded away
- # XXX could be improved
- assert ops[3].get_opnames() == ["guard_value",
- "getfield_gc", "guard_isnull"]
- assert not ops[4]
- ops = self.get_by_bytecode("CALL_FUNCTION", True)
- assert len(ops) == 2
- for i, bytecode in enumerate(ops):
- if i == 0:
- assert "call(getexecutioncontext)" in str(bytecode)
- else:
- assert not bytecode.get_opnames("call")
- assert not bytecode.get_opnames("new")
- assert len(bytecode.get_opnames("guard")) <= 10
-
- ops = self.get_by_bytecode("LOAD_GLOBAL")
- assert len(ops) == 5
- for bytecode in ops:
- assert not bytecode
-
- ops = self.get_by_bytecode("CALL_FUNCTION")
- assert len(ops) == 2
- for bytecode in ops:
- assert len(bytecode) <= 1
-
-
- def test_method_call(self):
- self.run_source('''
- class A(object):
- def __init__(self, a):
- self.a = a
- def f(self, i):
- return self.a + i
- def main(n):
- i = 0
- a = A(1)
- while i < n:
- x = a.f(i)
- i = a.f(x)
- return i
- ''', 93,
- ([20], 20),
- ([31], 32))
- ops = self.get_by_bytecode("LOOKUP_METHOD", True)
- assert len(ops) == 2
- assert not ops[0].get_opnames("call")
- assert not ops[0].get_opnames("new")
- assert len(ops[0].get_opnames("guard")) <= 3
- assert not ops[1] # second LOOKUP_METHOD folded away
-
- ops = self.get_by_bytecode("LOOKUP_METHOD")
- assert not ops[0] # first LOOKUP_METHOD folded away
- assert not ops[1] # second LOOKUP_METHOD folded away
-
- ops = self.get_by_bytecode("CALL_METHOD", True)
- assert len(ops) == 2
- for i, bytecode in enumerate(ops):
- if i == 0:
- assert "call(getexecutioncontext)" in str(bytecode)
- else:
- assert not bytecode.get_opnames("call")
- assert not bytecode.get_opnames("new")
- assert len(bytecode.get_opnames("guard")) <= 6
- assert len(ops[1]) < len(ops[0])
-
- ops = self.get_by_bytecode("CALL_METHOD")
- assert len(ops) == 2
- assert len(ops[0]) <= 1
- assert len(ops[1]) <= 1
-
- ops = self.get_by_bytecode("LOAD_ATTR", True)
- assert len(ops) == 2
- # With mapdict, we get fast access to (so far) the 5 first
- # attributes, which means it is done with only the following
- # operations. (For the other attributes there is additionally
- # a getarrayitem_gc.)
- assert ops[0].get_opnames() == ["getfield_gc",
- "guard_nonnull_class"]
- assert not ops[1] # second LOAD_ATTR folded away
-
- ops = self.get_by_bytecode("LOAD_ATTR")
- assert not ops[0] # first LOAD_ATTR folded away
- assert not ops[1] # second LOAD_ATTR folded away
-
- def test_static_classmethod_call(self):
- self.run_source('''
- class A(object):
- @classmethod
- def f(cls, i):
- return i + (cls is A) + 1
-
- @staticmethod
- def g(i):
- return i - 1
-
- def main(n):
- i = 0
- a = A()
- while i < n:
- x = a.f(i)
- i = a.g(x)
- return i
- ''', 106,
- ([20], 20),
- ([31], 31))
- ops = self.get_by_bytecode("LOOKUP_METHOD")
- assert len(ops) == 2
- assert not ops[0].get_opnames("call")
- assert not ops[0].get_opnames("new")
- assert len(ops[0].get_opnames("guard")) <= 2
- assert len(ops[0].get_opnames("getfield")) <= 4
- assert not ops[1] # second LOOKUP_METHOD folded away
-
- def test_default_and_kw(self):
- self.run_source('''
- def f(i, j=1):
- return i + j
- def main(n):
- i = 0
- while i < n:
- i = f(f(i), j=1)
- return i
- ''', 100,
- ([20], 20),
- ([31], 32))
- ops = self.get_by_bytecode("CALL_FUNCTION")
- assert len(ops) == 2
- for i, bytecode in enumerate(ops):
- assert not bytecode.get_opnames("call")
- assert not bytecode.get_opnames("new")
- assert len(ops[0].get_opnames("guard")) <= 14
- assert len(ops[1].get_opnames("guard")) <= 3
-
- ops = self.get_by_bytecode("CALL_FUNCTION", True)
- assert len(ops) == 2
- for i, bytecode in enumerate(ops):
- if i == 0:
- assert "call(getexecutioncontext)" in str(bytecode)
- else:
- assert not bytecode.get_opnames("call")
- assert not bytecode.get_opnames("new")
- assert len(ops[0].get_opnames("guard")) <= 14
- assert len(ops[1].get_opnames("guard")) <= 3
-
- def test_kwargs(self):
- self.run_source('''
- d = {}
-
- def g(**args):
- return len(args)
-
- def main(x):
- s = 0
- d = {}
- for i in range(x):
- s += g(**d)
- d[str(i)] = i
- if i % 100 == 99:
- d = {}
- return s
- ''', 100000, ([100], 4950),
- ([1000], 49500),
- ([10000], 495000),
- ([100000], 4950000))
- assert len(self.rawloops) + len(self.rawentrybridges) == 4
- op, = self.get_by_bytecode("CALL_FUNCTION_KW")
- # XXX a bit too many guards, but better than before
- assert len(op.get_opnames("guard")) <= 12
-
- def test_stararg_virtual(self):
- self.run_source('''
- d = {}
-
- def g(*args):
- return len(args)
- def h(a, b, c):
- return c
-
- def main(x):
- s = 0
- for i in range(x):
- l = [i, x, 2]
- s += g(*l)
- s += h(*l)
- s += g(i, x, 2)
- for i in range(x):
- l = [x, 2]
- s += g(i, *l)
- s += h(i, *l)
- return s
- ''', 100000, ([100], 1300),
- ([1000], 13000),
- ([10000], 130000),
- ([100000], 1300000))
- assert len(self.loops) == 2
- ops = self.get_by_bytecode("CALL_FUNCTION_VAR")
- assert len(ops) == 4
- for op in ops:
- assert len(op.get_opnames("new")) == 0
- assert len(op.get_opnames("call_may_force")) == 0
-
- ops = self.get_by_bytecode("CALL_FUNCTION")
- for op in ops:
- assert len(op.get_opnames("new")) == 0
- assert len(op.get_opnames("call_may_force")) == 0
-
- def test_stararg(self):
- self.run_source('''
- d = {}
-
- def g(*args):
- return args[-1]
- def h(*args):
- return len(args)
-
- def main(x):
- s = 0
- l = []
- i = 0
- while i < x:
- l.append(1)
- s += g(*l)
- i = h(*l)
- return s
- ''', 100000, ([100], 100),
- ([1000], 1000),
- ([2000], 2000),
- ([4000], 4000))
- assert len(self.loops) == 1
- ops = self.get_by_bytecode("CALL_FUNCTION_VAR")
- for op in ops:
- assert len(op.get_opnames("new_with_vtable")) == 0
- assert len(op.get_opnames("call_may_force")) == 0
-
- def test_virtual_instance(self):
- self.run_source('''
- class A(object):
- pass
- def main(n):
- i = 0
- while i < n:
- a = A()
- assert isinstance(a, A)
- assert not isinstance(a, int)
- a.x = 2
- i = i + a.x
- return i
- ''', 69,
- ([20], 20),
- ([31], 32))
-
- callA, callisinstance1, callisinstance2 = (
- self.get_by_bytecode("CALL_FUNCTION"))
- assert not callA.get_opnames("call")
- assert not callA.get_opnames("new")
- assert len(callA.get_opnames("guard")) <= 2
- assert not callisinstance1.get_opnames("call")
- assert not callisinstance1.get_opnames("new")
- assert len(callisinstance1.get_opnames("guard")) <= 2
- # calling isinstance on a builtin type gives zero guards
- # because the version_tag of a builtin type is immutable
- assert not len(callisinstance1.get_opnames("guard"))
-
-
- bytecode, = self.get_by_bytecode("STORE_ATTR")
- assert bytecode.get_opnames() == []
-
- def test_load_attr(self):
- self.run_source('''
- class A(object):
- pass
- a = A()
- a.x = 2
- def main(n):
- i = 0
- while i < n:
- i = i + a.x
- return i
- ''', 41,
- ([20], 20),
- ([31], 32))
-
- load, = self.get_by_bytecode("LOAD_ATTR")
- # 1 guard_value for the class
- # 1 guard_value for the version_tag
- # 1 guard_value for the structure
- # 1 guard_nonnull_class for the result since it is used later
- assert len(load.get_opnames("guard")) <= 4
-
- def test_mixed_type_loop(self):
- self.run_source('''
- class A(object):
- pass
- def main(n):
- i = 0.0
- j = 2
- while i < n:
- i = j + i
- return i, type(i) is float
- ''', 35,
- ([20], (20, True)),
- ([31], (32, True)))
-
- bytecode, = self.get_by_bytecode("BINARY_ADD")
- assert not bytecode.get_opnames("call")
- assert not bytecode.get_opnames("new")
- assert len(bytecode.get_opnames("guard")) <= 2
-
- def test_call_builtin_function(self):
- self.run_source('''
- class A(object):
- pass
- def main(n):
- i = 2
- l = []
- while i < n:
- i += 1
- l.append(i)
- return i, len(l)
- ''', 39,
- ([20], (20, 18)),
- ([31], (31, 29)))
-
- bytecode, = self.get_by_bytecode("CALL_METHOD")
- assert len(bytecode.get_opnames("new_with_vtable")) == 1 # the forcing of the int
- assert len(bytecode.get_opnames("call")) == 1 # the call to append
- assert len(bytecode.get_opnames("guard")) == 1 # guard for guard_no_exception after the call
- bytecode, = self.get_by_bytecode("CALL_METHOD", True)
- assert len(bytecode.get_opnames("guard")) == 2 # guard for profiling disabledness + guard_no_exception after the call
-
- def test_range_iter(self):
- self.run_source('''
- def g(n):
- return range(n)
-
- def main(n):
- s = 0
- for i in range(n):
- s += g(n)[i]
- return s
- ''', 143, ([1000], 1000 * 999 / 2))
- bytecode, = self.get_by_bytecode("BINARY_SUBSCR", True)
- assert bytecode.get_opnames("guard") == [
- "guard_false", # check that the index is >= 0
- "guard_false", # check that the index is lower than the current length
- ]
- bytecode, _ = self.get_by_bytecode("FOR_ITER", True) # second bytecode is the end of the loop
- assert bytecode.get_opnames("guard") == [
- "guard_value",
- "guard_class", # check the class of the iterator
- "guard_nonnull", # check that the iterator is not finished
- "guard_isnull", # check that the range list is not forced
- "guard_false", # check that the index is lower than the current length
- ]
-
- bytecode, = self.get_by_bytecode("BINARY_SUBSCR")
- assert bytecode.get_opnames("guard") == [
- "guard_false", # check that the index is >= 0
- "guard_false", # check that the index is lower than the current length
- ]
- bytecode, _ = self.get_by_bytecode("FOR_ITER") # second bytecode is the end of the loop
- assert bytecode.get_opnames("guard") == [
- "guard_false", # check that the index is lower than the current length
- ]
-
- def test_exception_inside_loop_1(self):
- self.run_source('''
- def main(n):
- while n:
- try:
- raise ValueError
- except ValueError:
- pass
- n -= 1
- return n
- ''', 33,
- ([30], 0))
-
- bytecode, = self.get_by_bytecode("SETUP_EXCEPT")
- #assert not bytecode.get_opnames("new") -- currently, we have
- # new_with_vtable(pypy.interpreter.pyopcode.ExceptBlock)
- bytecode, = self.get_by_bytecode("RAISE_VARARGS")
- assert not bytecode.get_opnames("new")
- bytecode, = self.get_by_bytecode("COMPARE_OP")
- assert not bytecode.get_opnames()
-
- def test_exception_inside_loop_2(self):
- self.run_source('''
- def g(n):
- raise ValueError(n)
- def f(n):
- g(n)
- def main(n):
- while n:
- try:
- f(n)
- except ValueError:
- pass
- n -= 1
- return n
- ''', 51,
- ([30], 0))
-
- bytecode, = self.get_by_bytecode("RAISE_VARARGS")
- assert not bytecode.get_opnames("new")
- bytecode, = self.get_by_bytecode("COMPARE_OP")
- assert len(bytecode.get_opnames()) <= 2 # oois, guard_true
-
- def test_chain_of_guards(self):
- self.run_source('''
- class A(object):
- def method_x(self):
- return 3
-
- l = ["x", "y"]
-
- def main(arg):
- sum = 0
- a = A()
- i = 0
- while i < 2000:
- name = l[arg]
- sum += getattr(a, 'method_' + name)()
- i += 1
- return sum
- ''', 3000, ([0], 2000*3))
- assert len(self.loops) == 1
-
- def test_getattr_with_dynamic_attribute(self):
- self.run_source('''
- class A(object):
- pass
-
- l = ["x", "y"]
-
- def main(arg):
- sum = 0
- a = A()
- a.a1 = 0
- a.a2 = 0
- a.a3 = 0
- a.a4 = 0
- a.a5 = 0 # workaround, because the first five attributes need a promotion
- a.x = 1
- a.y = 2
- i = 0
- while i < 2000:
- name = l[i % 2]
- sum += getattr(a, name)
- i += 1
- return sum
- ''', 3000, ([0], 3000))
- assert len(self.loops) == 1
-
- def test_blockstack_virtualizable(self):
- self.run_source('''
- from pypyjit import residual_call
-
- def main():
- i = 0
- while i < 100:
- try:
- residual_call(len, [])
- except:
- pass
- i += 1
- return i
- ''', 1000, ([], 100))
- bytecode, = self.get_by_bytecode("CALL_FUNCTION")
- # we allocate virtual ref and frame, we don't want block
- assert len(bytecode.get_opnames('new_with_vtable')) == 2
-
- def test_import_in_function(self):
- self.run_source('''
- def main():
- i = 0
- while i < 100:
- from sys import version
- i += 1
- return i
- ''', 100, ([], 100))
- bytecode, = self.get_by_bytecode('IMPORT_NAME')
- bytecode2, = self.get_by_bytecode('IMPORT_FROM')
- assert len(bytecode.get_opnames('call')) == 2 # split_chr and list_pop
- assert len(bytecode2.get_opnames('call')) == 0
-
- def test_arraycopy_disappears(self):
- self.run_source('''
- def main():
- i = 0
- while i < 100:
- t = (1, 2, 3, i + 1)
- t2 = t[:]
- del t
- i = t2[3]
- del t2
- return i
- ''', 40, ([], 100))
- bytecode, = self.get_by_bytecode('BINARY_SUBSCR')
- assert len(bytecode.get_opnames('new_array')) == 0
def test_overflow_checking(self):
startvalue = sys.maxint - 2147483647
@@ -783,269 +222,6 @@
total += f(i, 5)
return total
''' % startvalue, 170, ([], startvalue + 4999450000L))
-
- def test_boolrewrite_invers(self):
- for a, b, res, ops in (('2000', '2000', 20001000, 51),
- ( '500', '500', 15001500, 81),
- ( '300', '600', 16001700, 83),
- ( 'a', 'b', 16001700, 89),
- ( 'a', 'a', 13001700, 85)):
-
- self.run_source('''
- def main():
- sa = 0
- a = 300
- b = 600
- for i in range(1000):
- if i < %s: sa += 1
- else: sa += 2
- if i >= %s: sa += 10000
- else: sa += 20000
- return sa
- '''%(a, b), ops, ([], res))
-
- def test_boolrewrite_reflex(self):
- for a, b, res, ops in (('2000', '2000', 10001000, 51),
- ( '500', '500', 15001500, 81),
- ( '300', '600', 14001700, 83),
- ( 'a', 'b', 14001700, 89),
- ( 'a', 'a', 17001700, 85)):
-
- self.run_source('''
- def main():
- sa = 0
- a = 300
- b = 600
- for i in range(1000):
- if i < %s: sa += 1
- else: sa += 2
- if %s > i: sa += 10000
- else: sa += 20000
- return sa
- '''%(a, b), ops, ([], res))
-
-
- def test_boolrewrite_correct_invers(self):
- def opval(i, op, a):
- if eval('%d %s %d' % (i, op, a)): return 1
- return 2
-
- ops = ('<', '>', '<=', '>=', '==', '!=')
- for op1 in ops:
- for op2 in ops:
- for a,b in ((500, 500), (300, 600)):
- res = 0
- res += opval(a-1, op1, a) * (a)
- res += opval( a, op1, a)
- res += opval(a+1, op1, a) * (1000 - a - 1)
- res += opval(b-1, op2, b) * 10000 * (b)
- res += opval( b, op2, b) * 10000
- res += opval(b+1, op2, b) * 10000 * (1000 - b - 1)
-
- self.run_source('''
- def main():
- sa = 0
- for i in range(1000):
- if i %s %d: sa += 1
- else: sa += 2
- if i %s %d: sa += 10000
- else: sa += 20000
- return sa
- '''%(op1, a, op2, b), 83, ([], res))
-
- self.run_source('''
- def main():
- sa = 0
- i = 0.0
- while i < 250.0:
- if i %s %f: sa += 1
- else: sa += 2
- if i %s %f: sa += 10000
- else: sa += 20000
- i += 0.25
- return sa
- '''%(op1, float(a)/4.0, op2, float(b)/4.0), 156, ([], res))
-
-
- def test_boolrewrite_correct_reflex(self):
- def opval(i, op, a):
- if eval('%d %s %d' % (i, op, a)): return 1
- return 2
-
- ops = ('<', '>', '<=', '>=', '==', '!=')
- for op1 in ops:
- for op2 in ops:
- for a,b in ((500, 500), (300, 600)):
- res = 0
- res += opval(a-1, op1, a) * (a)
- res += opval( a, op1, a)
- res += opval(a+1, op1, a) * (1000 - a - 1)
- res += opval(b, op2, b-1) * 10000 * (b)
- res += opval(b, op2, b) * 10000
- res += opval(b, op2, b+1) * 10000 * (1000 - b - 1)
-
- self.run_source('''
- def main():
- sa = 0
- for i in range(1000):
- if i %s %d: sa += 1
- else: sa += 2
- if %d %s i: sa += 10000
- else: sa += 20000
- return sa
- '''%(op1, a, b, op2), 83, ([], res))
-
- self.run_source('''
- def main():
- sa = 0
- i = 0.0
- while i < 250.0:
- if i %s %f: sa += 1
- else: sa += 2
- if %f %s i: sa += 10000
- else: sa += 20000
- i += 0.25
- return sa
- '''%(op1, float(a)/4.0, float(b)/4.0, op2), 156, ([], res))
-
- def test_boolrewrite_ptr(self):
- # XXX this test is way too imprecise in what it is actually testing
- # it should count the number of guards instead
- compares = ('a == b', 'b == a', 'a != b', 'b != a', 'a == c', 'c != b')
- for e1 in compares:
- for e2 in compares:
- a, b, c = 1, 2, 3
- if eval(e1): res = 752 * 1
- else: res = 752 * 2
- if eval(e2): res += 752 * 10000
- else: res += 752 * 20000
- a = b
- if eval(e1): res += 248 * 1
- else: res += 248 * 2
- if eval(e2): res += 248 * 10000
- else: res += 248 * 20000
-
-
- if 'c' in e1 or 'c' in e2:
- n = 337
- else:
- n = 215
-
- print
- print 'Test:', e1, e2, n, res
- self.run_source('''
- class tst(object):
- pass
- def main():
- a = tst()
- b = tst()
- c = tst()
- sa = 0
- for i in range(1000):
- if %s: sa += 1
- else: sa += 2
- if %s: sa += 10000
- else: sa += 20000
- if i > 750: a = b
- return sa
- '''%(e1, e2), n, ([], res))
-
- def test_array_sum(self):
- for tc, maxops in zip('bhilBHILfd', (38,) * 6 + (40, 40, 41, 38)):
- res = 19352859
- if tc == 'L':
- res = long(res)
- elif tc in 'fd':
- res = float(res)
- elif tc == 'I' and sys.maxint == 2147483647:
- res = long(res)
- # note: in CPython we always get longs here, even on 64-bits
-
- self.run_source('''
- from array import array
-
- def main():
- img = array("%s", range(127) * 5) * 484
- l, i = 0, 0
- while i < 640 * 480:
- l += img[i]
- i += 1
- return l
- ''' % tc, maxops, ([], res))
-
- def test_array_sum_char(self):
- self.run_source('''
- from array import array
-
- def main():
- img = array("c", "Hello") * 130 * 480
- l, i = 0, 0
- while i < 640 * 480:
- l += ord(img[i])
- i += 1
- return l
- ''', 60, ([], 30720000))
-
- def test_array_sum_unicode(self):
- self.run_source('''
- from array import array
-
- def main():
- img = array("u", u"Hello") * 130 * 480
- l, i = 0, 0
- while i < 640 * 480:
- if img[i] == u"l":
- l += 1
- i += 1
- return l
- ''', 65, ([], 122880))
-
- def test_array_intimg(self):
- # XXX this test is way too imprecise in what it is actually testing
- # it should count the number of guards instead
- for tc, maxops in zip('ilILd', (67, 67, 70, 70, 61)):
- print
- print '='*65
- print '='*20, 'running test for tc=%r' % (tc,), '='*20
- res = 73574560
- if tc == 'L':
- res = long(res)
- elif tc in 'fd':
- res = float(res)
- elif tc == 'I' and sys.maxint == 2147483647:
- res = long(res)
- # note: in CPython we always get longs here, even on 64-bits
-
- self.run_source('''
- from array import array
-
- def main(tc):
- img = array(tc, range(3)) * (350 * 480)
- intimg = array(tc, (0,)) * (640 * 480)
- l, i = 0, 640
- while i < 640 * 480:
- l = l + img[i]
- intimg[i] = (intimg[i-640] + l)
- i += 1
- return intimg[i - 1]
- ''', maxops, ([tc], res))
-
- def test_unpackiterable(self):
- self.run_source('''
- from array import array
-
- def main():
- i = 0
- t = array('l', (1, 2))
- while i < 2000:
- a, b = t
- i += 1
- return 3
-
- ''', 100, ([], 3))
- bytecode, = self.get_by_bytecode("UNPACK_SEQUENCE")
- # we allocate virtual ref and frame, we don't want block
- assert len(bytecode.get_opnames('call_may_force')) == 0
def test_intbound_simple(self):
diff --git a/pypy/jit/metainterp/test/test_blackhole.py b/pypy/jit/metainterp/test/test_blackhole.py
--- a/pypy/jit/metainterp/test/test_blackhole.py
+++ b/pypy/jit/metainterp/test/test_blackhole.py
@@ -1,6 +1,6 @@
import py
from pypy.rlib.jit import JitDriver
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
from pypy.jit.metainterp.blackhole import BlackholeInterpreter
from pypy.jit.metainterp.blackhole import convert_and_run_from_pyjitpl
diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py
--- a/pypy/jit/metainterp/test/test_virtualref.py
+++ b/pypy/jit/metainterp/test/test_virtualref.py
@@ -3,7 +3,7 @@
from pypy.rlib.jit import JitDriver, dont_look_inside, vref_None
from pypy.rlib.jit import virtual_ref, virtual_ref_finish
from pypy.rlib.objectmodel import compute_unique_id
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.virtualref import VirtualRefInfo
diff --git a/pypy/rpython/lltypesystem/module/test/test_ll_math.py b/pypy/rpython/lltypesystem/module/test/test_ll_math.py
--- a/pypy/rpython/lltypesystem/module/test/test_ll_math.py
+++ b/pypy/rpython/lltypesystem/module/test/test_ll_math.py
@@ -11,6 +11,7 @@
nan = inf / inf
assert not ll_math.ll_math_isinf(0)
assert ll_math.ll_math_isinf(inf)
+ assert ll_math.ll_math_isinf(-inf)
assert not ll_math.ll_math_isinf(nan)
def test_isnan(self):
diff --git a/pypy/jit/metainterp/test/test_string.py b/pypy/jit/metainterp/test/test_string.py
--- a/pypy/jit/metainterp/test/test_string.py
+++ b/pypy/jit/metainterp/test/test_string.py
@@ -2,7 +2,7 @@
from pypy.rlib.jit import JitDriver, dont_look_inside, we_are_jitted
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.rpython.ootypesystem import ootype
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
class StringTests:
diff --git a/pypy/jit/metainterp/test/test_tlc.py b/pypy/jit/metainterp/test/test_tlc.py
--- a/pypy/jit/metainterp/test/test_tlc.py
+++ b/pypy/jit/metainterp/test/test_tlc.py
@@ -3,7 +3,7 @@
from pypy.jit.tl import tlc
-from pypy.jit.metainterp.test.test_basic import OOJitMixin, LLJitMixin
+from pypy.jit.metainterp.test.support import OOJitMixin, LLJitMixin
class TLCTests:
diff --git a/pypy/jit/metainterp/test/test_greenfield.py b/pypy/jit/metainterp/test/test_greenfield.py
--- a/pypy/jit/metainterp/test/test_greenfield.py
+++ b/pypy/jit/metainterp/test/test_greenfield.py
@@ -1,4 +1,4 @@
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rlib.jit import JitDriver
diff --git a/pypy/translator/c/src/ll_math.h b/pypy/translator/c/src/ll_math.h
--- a/pypy/translator/c/src/ll_math.h
+++ b/pypy/translator/c/src/ll_math.h
@@ -1,9 +1,6 @@
/* Definitions of some C99 math library functions, for those platforms
that don't implement these functions already. */
-int _pypy_math_isinf(double x);
-int _pypy_math_isnan(double x);
-
double _pypy_math_acosh(double x);
double _pypy_math_asinh(double x);
double _pypy_math_atanh(double x);
diff --git a/pypy/jit/backend/x86/test/test_zrpy_gc.py b/pypy/jit/backend/x86/test/test_zrpy_gc.py
--- a/pypy/jit/backend/x86/test/test_zrpy_gc.py
+++ b/pypy/jit/backend/x86/test/test_zrpy_gc.py
@@ -5,7 +5,7 @@
soon as possible (at least in a simple case).
"""
-import weakref, random
+import weakref
import py, os
from pypy.annotation import policy as annpolicy
from pypy.rlib import rgc
diff --git a/pypy/jit/metainterp/test/test_slist.py b/pypy/jit/metainterp/test/test_slist.py
--- a/pypy/jit/metainterp/test/test_slist.py
+++ b/pypy/jit/metainterp/test/test_slist.py
@@ -1,5 +1,5 @@
import py
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rlib.jit import JitDriver
class ListTests(object):
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -754,6 +754,8 @@
("{x for x in z}", "set comprehension"),
("{x : x for x in z}", "dict comprehension"),
("'str'", "literal"),
+ ("u'str'", "literal"),
+ ("b'bytes'", "literal"),
("()", "()"),
("23", "literal"),
("{}", "literal"),
diff --git a/pypy/translator/jvm/metavm.py b/pypy/translator/jvm/metavm.py
--- a/pypy/translator/jvm/metavm.py
+++ b/pypy/translator/jvm/metavm.py
@@ -1,4 +1,5 @@
from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.lltypesystem import rffi
from pypy.translator.oosupport.metavm import MicroInstruction
from pypy.translator.jvm.typesystem import JvmScalarType, JvmClassType
import pypy.translator.jvm.typesystem as jvm
@@ -94,14 +95,20 @@
(ootype.SignedLongLong, ootype.Signed): jvm.L2I,
(ootype.UnsignedLongLong, ootype.Unsigned): jvm.L2I,
(ootype.UnsignedLongLong, ootype.Signed): jvm.L2I,
+ (ootype.Signed, rffi.SHORT): jvm.I2S,
+ (ootype.Unsigned, ootype.SignedLongLong): jvm.PYPYUINTTOLONG,
(ootype.UnsignedLongLong, ootype.SignedLongLong): None,
(ootype.SignedLongLong, ootype.UnsignedLongLong): None,
+ (ootype.Signed, ootype.Unsigned): None,
+ (ootype.Unsigned, ootype.Signed): None,
}
class _CastPrimitive(MicroInstruction):
def render(self, generator, op):
FROM = op.args[0].concretetype
TO = op.result.concretetype
+ if TO == FROM:
+ return
opcode = CASTS[(FROM, TO)]
if opcode:
generator.emit(opcode)
diff --git a/pypy/jit/tl/pypyjit.py b/pypy/jit/tl/pypyjit.py
--- a/pypy/jit/tl/pypyjit.py
+++ b/pypy/jit/tl/pypyjit.py
@@ -101,7 +101,7 @@
# first annotate, rtype, and backendoptimize PyPy
try:
- interp, graph = get_interpreter(entry_point, [], backendopt=True,
+ interp, graph = get_interpreter(entry_point, [], backendopt=False,
config=config,
type_system=config.translation.type_system,
policy=PyPyAnnotatorPolicy(space))
diff --git a/pypy/translator/c/src/ll_math.c b/pypy/translator/c/src/ll_math.c
--- a/pypy/translator/c/src/ll_math.c
+++ b/pypy/translator/c/src/ll_math.c
@@ -22,18 +22,6 @@
#endif
#define PyPy_NAN (HUGE_VAL * 0.)
-int
-_pypy_math_isinf(double x)
-{
- return PyPy_IS_INFINITY(x);
-}
-
-int
-_pypy_math_isnan(double x)
-{
- return PyPy_IS_NAN(x);
-}
-
/* The following copyright notice applies to the original
implementations of acosh, asinh and atanh. */
diff --git a/pypy/jit/metainterp/test/test_exception.py b/pypy/jit/metainterp/test/test_exception.py
--- a/pypy/jit/metainterp/test/test_exception.py
+++ b/pypy/jit/metainterp/test/test_exception.py
@@ -1,5 +1,5 @@
import py, sys
-from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
from pypy.rlib.jit import JitDriver, dont_look_inside
from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask
from pypy.jit.codewriter.policy import StopAtXPolicy
diff --git a/pypy/translator/jvm/src/pypy/PyPy.java b/pypy/translator/jvm/src/pypy/PyPy.java
--- a/pypy/translator/jvm/src/pypy/PyPy.java
+++ b/pypy/translator/jvm/src/pypy/PyPy.java
@@ -38,6 +38,10 @@
public final static int INT_MIN = Integer.MIN_VALUE;
public final static double ULONG_MAX = 18446744073709551616.0;
+ public static boolean int_between(int a, int b, int c) {
+ return a <= b && b < c;
+ }
+
/**
* Compares two unsigned integers (value1 and value2) and returns
* a value greater than, equal to, or less than zero if value 1 is
@@ -163,6 +167,13 @@
return ULONG_MAX + value;
}
}
+
+ public static long double_to_ulong(double value) {
+ if (value < 0)
+ return (long)(ULONG_MAX + value);
+ else
+ return (long)value;
+ }
public static int double_to_uint(double value) {
if (value <= Integer.MAX_VALUE)
@@ -1175,6 +1186,18 @@
return Math.tanh(x);
}
+ public double ll_math_copysign(double x, double y) {
+ return Math.copySign(x, y);
+ }
+
+ public boolean ll_math_isnan(double x) {
+ return Double.isNaN(x);
+ }
+
+ public boolean ll_math_isinf(double x) {
+ return Double.isInfinite(x);
+ }
+
private double check(double v) {
if (Double.isNaN(v))
interlink.throwValueError();
@@ -1187,9 +1210,42 @@
return Character.toLowerCase(c);
}
+ public int locale_tolower(int chr)
+ {
+ return Character.toLowerCase(chr);
+ }
+
+ public int locale_isupper(int chr)
+ {
+ return boolean2int(Character.isUpperCase(chr));
+ }
+
+ public int locale_islower(int chr)
+ {
+ return boolean2int(Character.isLowerCase(chr));
+ }
+
+ public int locale_isalpha(int chr)
+ {
+ return boolean2int(Character.isLetter(chr));
+ }
+
+ public int locale_isalnum(int chr)
+ {
+ return boolean2int(Character.isLetterOrDigit(chr));
+ }
+
+
// ----------------------------------------------------------------------
// Self Test
+ public static int boolean2int(boolean b)
+ {
+ if (b)
+ return 1;
+ return 0;
+ }
+
public static int __counter = 0, __failures = 0;
public static void ensure(boolean f) {
if (f) {
diff --git a/pypy/jit/metainterp/test/test_tl.py b/pypy/jit/metainterp/test/test_tl.py
--- a/pypy/jit/metainterp/test/test_tl.py
+++ b/pypy/jit/metainterp/test/test_tl.py
@@ -1,6 +1,6 @@
import py
from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.jit.metainterp.test.test_basic import OOJitMixin, LLJitMixin
+from pypy.jit.metainterp.test.support import OOJitMixin, LLJitMixin
class ToyLanguageTests:
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -39,7 +39,7 @@
translation_modules = default_modules.copy()
translation_modules.update(dict.fromkeys(
["fcntl", "rctime", "select", "signal", "_rawffi", "zlib",
- "struct", "md5", "cStringIO", "array"]))
+ "struct", "_md5", "cStringIO", "array"]))
working_oo_modules = default_modules.copy()
working_oo_modules.update(dict.fromkeys(
More information about the Pypy-commit
mailing list