Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> Branch: py3.6 Changeset: r96747:0ffff10dd2bc Date: 2019-06-05 11:31 +0200 http://bitbucket.org/pypy/pypy/changeset/0ffff10dd2bc/
Log: merge default diff too long, truncating to 2000 out of 7324 lines diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -410,7 +410,17 @@ def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -418,7 +428,11 @@ assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -2535,3 +2535,29 @@ x.p = p x.cyclic = x del p, x + +def test_arithmetic_in_cdef(): + for a in [0, 11, 15]: + ffi = FFI() + ffi.cdef(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + lib = ffi.verify(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + # the verify() crashes if the values in the enum are different from + # the values we computed ourselves from the cdef() diff --git a/extra_tests/cffi_tests/cffi0/test_zintegration.py b/extra_tests/cffi_tests/cffi0/test_zintegration.py --- a/extra_tests/cffi_tests/cffi0/test_zintegration.py +++ b/extra_tests/cffi_tests/cffi0/test_zintegration.py @@ -2,11 +2,13 @@ import py, os, sys, shutil import subprocess from extra_tests.cffi_tests.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -2339,3 +2339,24 @@ typedef int foo_t; struct foo_s { void (*x)(foo_t); }; """) py.test.raises(TypeError, ffi.new, "struct foo_s *") + +def test_from_buffer_struct(): + ffi = FFI() + ffi.cdef("""struct foo_s { int a, b; };""") + lib = verify(ffi, "test_from_buffer_struct_p", """ + struct foo_s { int a, b; }; + """) + p = ffi.new("struct foo_s *", [-219239, 58974983]) + q = ffi.from_buffer("struct foo_s[]", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s[]") + assert len(q) == 1 + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p + q = ffi.from_buffer("struct foo_s *", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s *") + assert q.a == p.a + assert q.b == p.b + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -64,8 +64,8 @@ output = popen.stdout.read() err = popen.wait() if err: - raise OSError("popen failed with exit code %r: %r" % ( - err, args)) + raise OSError(("popen failed with exit code %r: %r\n\n%s" % ( + err, args, output)).rstrip()) print(output.rstrip()) return output diff --git a/extra_tests/cffi_tests/embedding/test_performance.py b/extra_tests/cffi_tests/embedding/test_performance.py --- a/extra_tests/cffi_tests/embedding/test_performance.py +++ b/extra_tests/cffi_tests/embedding/test_performance.py @@ -3,8 +3,8 @@ from extra_tests.cffi_tests.embedding.test_basic import EmbeddingTests if sys.platform == 'win32': - import py - py.test.skip("written with POSIX functions") + import pytest + pytestmark = pytest.mark.skip("written with POSIX functions") class TestPerformance(EmbeddingTests): diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.12.3 +Version: 1.13.0 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -5,8 +5,8 @@ from .error import CDefError, FFIError, VerificationError, VerificationMissing from .error import PkgConfigError -__version__ = "1.12.3" -__version_info__ = (1, 12, 3) +__version__ = "1.13.0" +__version_info__ = (1, 13, 0) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h --- a/lib_pypy/cffi/_embedding.h +++ b/lib_pypy/cffi/_embedding.h @@ -145,6 +145,7 @@ int result; PyGILState_STATE state; PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; state = PyGILState_Ensure(); @@ -169,7 +170,7 @@ global_dict = PyDict_New(); if (global_dict == NULL) goto error; - PyObject *builtins = PyEval_GetBuiltins(); + builtins = PyEval_GetBuiltins(); if (builtins == NULL) goto error; if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) @@ -223,7 +224,7 @@ if (f != NULL && f != Py_None) { PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME - "\ncompiled with cffi version: 1.12.3" + "\ncompiled with cffi version: 1.13.0" "\n_cffi_backend module: ", f); modules = PyImport_GetModuleDict(); mod = PyDict_GetItemString(modules, "_cffi_backend"); diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -858,19 +858,39 @@ "the actual array length in this context" % exprnode.coord.line) # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '+'): - return (self._parse_constant(exprnode.left) + - self._parse_constant(exprnode.right)) - # - if (isinstance(exprnode, pycparser.c_ast.BinaryOp) and - exprnode.op == '-'): - return (self._parse_constant(exprnode.left) - - self._parse_constant(exprnode.right)) + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right # raise FFIError(":%d: unsupported expression: expected a " "simple numeric constant" % exprnode.coord.line) + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + def _build_enum_type(self, explicit_name, decls): if decls is not None: partial = False diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -38,3 +38,7 @@ .. branch: fix-vmprof-memory-tracking Fix a bug that prevent memory-tracking in vmprof working on PyPy. + +.. branch: optimizeopt-cleanup + +Cleanup optimizeopt diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -3,7 +3,7 @@ from rpython.rlib import rdynload, clibffi from rpython.rtyper.lltypesystem import rffi -VERSION = "1.12.3" +VERSION = "1.13.0" FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI try: diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py --- a/pypy/module/_cffi_backend/cdataobj.py +++ b/pypy/module/_cffi_backend/cdataobj.py @@ -670,11 +670,14 @@ return self.length def _repr_extra(self): - if self.w_keepalive is not None: - name = self.space.type(self.w_keepalive).name + from pypy.module._cffi_backend import ctypearray + if self.w_keepalive is None: + return "buffer RELEASED" + obj_tp_name = self.space.type(self.w_keepalive).name + if isinstance(self.ctype, ctypearray.W_CTypeArray): + return "buffer len %d from '%s' object" % (self.length, obj_tp_name) else: - name = "(released)" - return "buffer len %d from '%s' object" % (self.length, name) + return "buffer from '%s' object" % (obj_tp_name,) def enter_exit(self, exit_now): # for now, limited effect on PyPy diff --git a/pypy/module/_cffi_backend/func.py b/pypy/module/_cffi_backend/func.py --- a/pypy/module/_cffi_backend/func.py +++ b/pypy/module/_cffi_backend/func.py @@ -112,9 +112,10 @@ @unwrap_spec(w_ctype=ctypeobj.W_CType, require_writable=int) def from_buffer(space, w_ctype, w_x, require_writable=0): - from pypy.module._cffi_backend import ctypearray - if not isinstance(w_ctype, ctypearray.W_CTypeArray): - raise oefmt(space.w_TypeError, "expected an array ctype, got '%s'", + from pypy.module._cffi_backend import ctypeptr, ctypearray + if not isinstance(w_ctype, ctypeptr.W_CTypePtrOrArray): + raise oefmt(space.w_TypeError, + "expected a poiunter or array ctype, got '%s'", w_ctype.name) if space.isinstance_w(w_x, space.w_unicode): raise oefmt(space.w_TypeError, @@ -135,33 +136,36 @@ "raw address on PyPy", w_x) # buffersize = buf.getlength() - arraylength = w_ctype.length - if arraylength >= 0: - # it's an array with a fixed length; make sure that the - # buffer contains enough bytes. - if buffersize < w_ctype.size: - raise oefmt(space.w_ValueError, - "buffer is too small (%d bytes) for '%s' (%d bytes)", - buffersize, w_ctype.name, w_ctype.size) + if not isinstance(w_ctype, ctypearray.W_CTypeArray): + arraylength = buffersize # number of bytes, not used so far else: - # it's an open 'array[]' - itemsize = w_ctype.ctitem.size - if itemsize == 1: - # fast path, performance only - arraylength = buffersize - elif itemsize > 0: - # give it as many items as fit the buffer. Ignore a - # partial last element. - arraylength = buffersize / itemsize + arraylength = w_ctype.length + if arraylength >= 0: + # it's an array with a fixed length; make sure that the + # buffer contains enough bytes. + if buffersize < w_ctype.size: + raise oefmt(space.w_ValueError, + "buffer is too small (%d bytes) for '%s' (%d bytes)", + buffersize, w_ctype.name, w_ctype.size) else: - # it's an array 'empty[]'. Unsupported obscure case: - # the problem is that setting the length of the result - # to anything large (like SSIZE_T_MAX) is dangerous, - # because if someone tries to loop over it, it will - # turn effectively into an infinite loop. - raise oefmt(space.w_ZeroDivisionError, - "from_buffer('%s', ..): the actual length of the array " - "cannot be computed", w_ctype.name) + # it's an open 'array[]' + itemsize = w_ctype.ctitem.size + if itemsize == 1: + # fast path, performance only + arraylength = buffersize + elif itemsize > 0: + # give it as many items as fit the buffer. Ignore a + # partial last element. + arraylength = buffersize / itemsize + else: + # it's an array 'empty[]'. Unsupported obscure case: + # the problem is that setting the length of the result + # to anything large (like SSIZE_T_MAX) is dangerous, + # because if someone tries to loop over it, it will + # turn effectively into an infinite loop. + raise oefmt(space.w_ZeroDivisionError, + "from_buffer('%s', ..): the actual length of the array " + "cannot be computed", w_ctype.name) # return cdataobj.W_CDataFromBuffer(space, _cdata, arraylength, w_ctype, buf, w_x) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1,7 +1,7 @@ # ____________________________________________________________ import sys -assert __version__ == "1.12.3", ("This test_c.py file is for testing a version" +assert __version__ == "1.13.0", ("This test_c.py file is for testing a version" " of cffi that differs from the one that we" " get from 'import _cffi_backend'") if sys.version_info < (3,): @@ -3830,7 +3830,9 @@ BIntP = new_pointer_type(BInt) BIntA = new_array_type(BIntP, None) lst = [-12345678, 87654321, 489148] - bytestring = buffer(newp(BIntA, lst))[:] + b'XYZ' + bytestring = bytearray(buffer(newp(BIntA, lst))[:] + b'XYZ') + lst2 = lst + [42, -999999999] + bytestring2 = bytearray(buffer(newp(BIntA, lst2))[:] + b'XYZ') # p1 = from_buffer(BIntA, bytestring) # int[] assert typeof(p1) is BIntA @@ -3844,7 +3846,19 @@ p1[-1] # py.test.raises(TypeError, from_buffer, BInt, bytestring) - py.test.raises(TypeError, from_buffer, BIntP, bytestring) + # + p2 = from_buffer(BIntP, bytestring) # int * + assert p2 == p1 or 'PY_DOT_PY' in globals() + # note: on py.py ^^^, bytearray buffers are not emulated well enough + assert typeof(p2) is BIntP + assert p2[0] == lst[0] + assert p2[1] == lst[1] + assert p2[2] == lst[2] + # hopefully does not crash, but doesn't raise an exception: + p2[3] + p2[-1] + # not enough data even for one, but this is not enforced: + from_buffer(BIntP, b"") # BIntA2 = new_array_type(BIntP, 2) p2 = from_buffer(BIntA2, bytestring) # int[2] @@ -3856,7 +3870,7 @@ p2[2] with pytest.raises(IndexError): p2[-1] - assert p2 == p1 + assert p2 == p1 or 'PY_DOT_PY' in globals() # BIntA4 = new_array_type(BIntP, 4) # int[4]: too big py.test.raises(ValueError, from_buffer, BIntA4, bytestring) @@ -3866,13 +3880,37 @@ ('a2', BInt, -1)]) BStructP = new_pointer_type(BStruct) BStructA = new_array_type(BStructP, None) - p1 = from_buffer(BStructA, bytestring) # struct[] - assert len(p1) == 1 + p1 = from_buffer(BStructA, bytestring2) # struct[] + assert len(p1) == 2 assert typeof(p1) is BStructA - assert p1[0].a1 == lst[0] - assert p1[0].a2 == lst[1] + assert p1[0].a1 == lst2[0] + assert p1[0].a2 == lst2[1] + assert p1[1].a1 == lst2[2] + assert p1[1].a2 == lst2[3] with pytest.raises(IndexError): - p1[1] + p1[2] + with pytest.raises(IndexError): + p1[-1] + assert repr(p1) == "<cdata 'foo[]' buffer len 2 from 'bytearray' object>" + # + p2 = from_buffer(BStructP, bytestring2) # 'struct *' + assert p2 == p1 or 'PY_DOT_PY' in globals() + assert typeof(p2) is BStructP + assert p2.a1 == lst2[0] + assert p2.a2 == lst2[1] + assert p2[0].a1 == lst2[0] + assert p2[0].a2 == lst2[1] + assert p2[1].a1 == lst2[2] + assert p2[1].a2 == lst2[3] + # does not crash: + p2[2] + p2[-1] + # not enough data even for one, but this is not enforced: + from_buffer(BStructP, b"") + from_buffer(BStructP, b"1234567") + # + release(p1) + assert repr(p1) == "<cdata 'foo[]' buffer RELEASED>" # BEmptyStruct = new_struct_type("empty") complete_struct_or_union(BEmptyStruct, [], Ellipsis, 0) @@ -3886,7 +3924,37 @@ p1 = from_buffer(BEmptyStructA5, bytestring) # struct empty[5] assert typeof(p1) is BEmptyStructA5 assert len(p1) == 5 - assert cast(BIntP, p1) == from_buffer(BIntA, bytestring) + assert (cast(BIntP, p1) == from_buffer(BIntA, bytestring) + or 'PY_DOT_PY' in globals()) + # + BVarStruct = new_struct_type("varfoo") + BVarStructP = new_pointer_type(BVarStruct) + complete_struct_or_union(BVarStruct, [('a1', BInt, -1), + ('va', BIntA, -1)]) + with pytest.raises(TypeError): + from_buffer(BVarStruct, bytestring) + pv = from_buffer(BVarStructP, bytestring) # varfoo * + assert pv.a1 == lst[0] + assert pv.va[0] == lst[1] + assert pv.va[1] == lst[2] + assert sizeof(pv[0]) == 1 * size_of_int() + with pytest.raises(TypeError): + len(pv.va) + # hopefully does not crash, but doesn't raise an exception: + pv.va[2] + pv.va[-1] + # not enough data even for one, but this is not enforced: + from_buffer(BVarStructP, b"") + assert repr(pv) == "<cdata 'varfoo *' buffer from 'bytearray' object>" + assert repr(pv[0]).startswith("<cdata 'varfoo &' ") + # + release(pv) + assert repr(pv) == "<cdata 'varfoo *' buffer RELEASED>" + assert repr(pv[0]).startswith("<cdata 'varfoo &' ") + # + pv = from_buffer(BVarStructP, bytestring) # make a fresh one + with pytest.raises(ValueError): + release(pv[0]) def test_memmove(): Short = new_primitive_type("short") @@ -4312,8 +4380,10 @@ BCharA = new_array_type(BCharP, None) p = from_buffer(BCharA, a) assert p[2] == b"z" + assert repr(p) == "<cdata 'char[]' buffer len 3 from 'bytearray' object>" release(p) assert p[2] == b"z" # true so far, but might change to raise RuntimeError + assert repr(p) == "<cdata 'char[]' buffer RELEASED>" release(p) # no effect def test_explicit_release_from_buffer_contextmgr(): @@ -4325,6 +4395,7 @@ with p: assert p[2] == b"z" assert p[2] == b"z" # true so far, but might change to raise RuntimeError + assert repr(p) == "<cdata 'char[]' buffer RELEASED>" release(p) # no effect def test_explicit_release_bytearray_on_cpython(): diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -2,6 +2,8 @@ import sys +import sys + from rpython.rlib.objectmodel import ( compute_hash, compute_unique_id, import_from_mixin, always_inline, enforceargs, newlist_hint, specialize, we_are_translated) diff --git a/rpython/doc/jit/optimizer.rst b/rpython/doc/jit/optimizer.rst --- a/rpython/doc/jit/optimizer.rst +++ b/rpython/doc/jit/optimizer.rst @@ -13,7 +13,7 @@ Before some optimizations are explained in more detail, it is essential to understand how traces look like. -The optimizer comes with a test suit. It contains many trace +The optimizer comes with a test suite. It contains many trace examples and you might want to take a look at it (in `rpython/jit/metainterp/optimizeopt/test/*.py`). The allowed operations can be found in `rpython/jit/metainterp/resoperation.py`. @@ -21,7 +21,7 @@ [p0,i0,i1] label(p0, i0, i1) - i2 = getarray_item_raw(p0, i0, descr=<Array Signed>) + i2 = getarrayitem_raw(p0, i0, descr=<Array Signed>) i3 = int_add(i1,i2) i4 = int_add(i0,1) i5 = int_le(i4, 100) # lower-or-equal @@ -32,7 +32,7 @@ to compare the Python code that constructed the trace:: from array import array - a = array('i',range(101)) + a = array('i', range(101)) sum = 0; i = 0 while i <= 100: # can be seen as label sum += a[i] @@ -131,20 +131,16 @@ Whenever such an operation is encountered (e.g. ``y = x & 0``), no operation is emitted. Instead the variable y is made equal to 0 -(= ``make_equal_to(op.result, 0)``). The variables found in a trace are -instances of Box classes that can be found in -`rpython/jit/metainterp/history.py`. `OptValue` wraps those variables again -and maps the boxes to the optimization values in the optimizer. When a -value is made equal, the two variable's boxes are made to point to the same -`OptValue` instance. +(= ``make_constant_int(op, 0)``). The variables found in a trace are instances +of classes that can be found in `rpython/jit/metainterp/history.py`. When a +value is made equal to another, its box is made to point to the other one. -**NOTE: this OptValue organization is currently being refactored in a branch.** Pure optimization ----------------- -Is interwoven into the basic optimizer. It saves operations, results, -arguments to be known to have pure semantics. +The 'pure' optimizations interwoven into the basic optimizer. It saves +operations, results, arguments to be known to have pure semantics. "Pure" here means the same as the ``jit.elidable`` decorator: free of "observable" side effects and referentially transparent diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -3,23 +3,22 @@ from rpython.rtyper.annlowlevel import ( cast_instance_to_gcref, cast_gcref_to_instance) from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints +from rpython.rlib.debug import ( + debug_start, debug_stop, debug_print, have_debug_prints) from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rlib import rstack from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside from rpython.rlib.rjitlog import rjitlog as jl -from rpython.rlib.objectmodel import compute_unique_id -from rpython.conftest import option -from rpython.jit.metainterp.resoperation import ResOperation, rop,\ - get_deep_immutable_oplist, OpHelpers, InputArgInt, InputArgRef,\ - InputArgFloat -from rpython.jit.metainterp.history import (TreeLoop, Const, JitCellToken, +from rpython.jit.metainterp.resoperation import ( + ResOperation, rop, get_deep_immutable_oplist, OpHelpers, InputArgInt, + InputArgRef, InputArgFloat) +from rpython.jit.metainterp.history import (TreeLoop, JitCellToken, TargetToken, AbstractFailDescr, ConstInt) from rpython.jit.metainterp import history, jitexc from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.jit.metainterp.resume import (PENDINGFIELDSP, - ResumeDataDirectReader, AccumInfo) +from rpython.jit.metainterp.resume import ( + PENDINGFIELDSP, ResumeDataDirectReader) from rpython.jit.metainterp.resumecode import NUMBERING from rpython.jit.metainterp.support import adr2int from rpython.jit.codewriter import longlong @@ -30,6 +29,9 @@ raise SwitchToBlackhole(Counters.ABORT_BRIDGE) class CompileData(object): + """ An object that accumulates all of the necessary info for + the optimization phase, but does not actually have any other state + """ memo = None log_noopt = True @@ -37,10 +39,28 @@ for arg in self.trace.inputargs: arg.set_forwarded(None) -class LoopCompileData(CompileData): - """ An object that accumulates all of the necessary info for - the optimization phase, but does not actually have any other state + def optimize_trace(self, metainterp_sd, jitdriver_sd, memo): + """Optimize loop.operations to remove internal overheadish operations. + """ + from rpython.jit.metainterp.optimizeopt import build_opt_chain + # mark that a new trace has been started + log = metainterp_sd.jitlog.log_trace(jl.MARK_TRACE, metainterp_sd, None) + log.write_trace(self.trace) + if self.log_noopt: + metainterp_sd.logger_noopt.log_loop_from_trace(self.trace, memo=memo) + self.box_names_memo = memo + optimizations = build_opt_chain(self.enable_opts) + debug_start("jit-optimize") + try: + return self.optimize(metainterp_sd, jitdriver_sd, optimizations) + finally: + self.forget_optimization_info() + debug_stop("jit-optimize") + + +class PreambleCompileData(CompileData): + """ This is the case of label() ops label() """ def __init__(self, trace, runtime_boxes, call_pure_results=None, @@ -51,19 +71,12 @@ assert runtime_boxes is not None self.runtime_boxes = runtime_boxes - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): - from rpython.jit.metainterp.optimizeopt.unroll import (UnrollOptimizer, - Optimizer) - - if unroll: - opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) - return opt.optimize_preamble(self.trace, - self.runtime_boxes, - self.call_pure_results, - self.box_names_memo) - else: - opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations) - return opt.propagate_all_forward(self.trace, self.call_pure_results) + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): + from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer + opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) + return opt.optimize_preamble( + self.trace, self.runtime_boxes, self.call_pure_results, + self.box_names_memo) class SimpleCompileData(CompileData): """ This represents label() ops jump with no extra info associated with @@ -76,26 +89,19 @@ self.call_pure_results = call_pure_results self.enable_opts = enable_opts - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer - from rpython.jit.metainterp.optimizeopt.bridgeopt import deserialize_optimizer_knowledge - - #assert not unroll opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations) - traceiter = self.trace.get_iter() - if self.resumestorage: - frontend_inputargs = self.trace.inputargs - deserialize_optimizer_knowledge(opt, self.resumestorage, - frontend_inputargs, - traceiter.inputargs) - return opt.propagate_all_forward(traceiter, self.call_pure_results) + return opt.optimize_loop( + self.trace, self.resumestorage, self.call_pure_results) class BridgeCompileData(CompileData): """ This represents ops() with a jump at the end that goes to some loop, we need to deal with virtual state and inlining of short preamble """ - def __init__(self, trace, runtime_boxes, resumestorage=None, call_pure_results=None, - enable_opts=None, inline_short_preamble=False): + def __init__(self, trace, runtime_boxes, resumestorage=None, + call_pure_results=None, enable_opts=None, + inline_short_preamble=False): self.trace = trace self.runtime_boxes = runtime_boxes self.call_pure_results = call_pure_results @@ -103,7 +109,7 @@ self.inline_short_preamble = inline_short_preamble self.resumestorage = resumestorage - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) @@ -115,29 +121,26 @@ class UnrolledLoopData(CompileData): """ This represents label() ops jump with extra info that's from the - run of LoopCompileData. Jump goes to the same label + run of PreambleCompileData. Jump goes to the same label """ log_noopt = False def __init__(self, trace, celltoken, state, - call_pure_results=None, enable_opts=None, - inline_short_preamble=True): + call_pure_results=None, enable_opts=None): self.trace = trace self.celltoken = celltoken self.enable_opts = enable_opts self.state = state self.call_pure_results = call_pure_results - self.inline_short_preamble = inline_short_preamble - def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll): + def optimize(self, metainterp_sd, jitdriver_sd, optimizations): from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer - - assert unroll # we should not be here if it's disabled opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations) - return opt.optimize_peeled_loop(self.trace, self.celltoken, self.state, - self.call_pure_results, self.inline_short_preamble) + return opt.optimize_peeled_loop( + self.trace, self.celltoken, self.state, self.call_pure_results) def show_procedures(metainterp_sd, procedure=None, error=None): + from rpython.conftest import option # debugging if option and (option.view or option.viewloops): if error: @@ -173,19 +176,14 @@ original_jitcell_token = loop.original_jitcell_token assert original_jitcell_token is not None if metainterp_sd.warmrunnerdesc is not None: # for tests - assert original_jitcell_token.generation > 0 # has been registered with memmgr + assert original_jitcell_token.generation > 0 # has been registered with memmgr wref = weakref.ref(original_jitcell_token) clt = original_jitcell_token.compiled_loop_token clt.loop_token_wref = wref for op in loop.operations: descr = op.getdescr() - # not sure what descr.index is about if isinstance(descr, ResumeDescr): descr.rd_loop_token = clt # stick it there - #n = descr.index - #if n >= 0: # we also record the resumedescr number - # original_jitcell_token.compiled_loop_token.record_faildescr_index(n) - # pass if isinstance(descr, JitCellToken): # for a CALL_ASSEMBLER: record it as a potential jump. if descr is not original_jitcell_token: @@ -215,11 +213,8 @@ # ____________________________________________________________ - def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts, cut_at): - from rpython.jit.metainterp.optimizeopt import optimize_trace - jitdriver_sd = metainterp.jitdriver_sd metainterp_sd = metainterp.staticdata jitcell_token = make_jitcell_token(jitdriver_sd) @@ -227,8 +222,8 @@ data = SimpleCompileData(trace, call_pure_results=call_pure_results, enable_opts=enable_opts) try: - loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd, - data, metainterp.box_names_memo) + loop_info, ops = data.optimize_trace( + metainterp_sd, jitdriver_sd, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() trace.cut_at(cut_at) @@ -253,12 +248,10 @@ return target_token def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, - full_preamble_needed=True, try_disabling_unroll=False): + use_unroll=True): """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace - metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd history = metainterp.history @@ -269,28 +262,21 @@ faildescr=None, entry_bridge=False) # enable_opts = jitdriver_sd.warmstate.enable_opts - if try_disabling_unroll: - if 'unroll' not in enable_opts: - return None - enable_opts = enable_opts.copy() - del enable_opts['unroll'] - jitcell_token = make_jitcell_token(jitdriver_sd) cut_at = history.get_trace_position() history.record(rop.JUMP, jumpargs, None, descr=jitcell_token) if start != (0, 0, 0): trace = trace.cut_trace_from(start, inputargs) - if 'unroll' not in enable_opts or not metainterp.cpu.supports_guard_gc_type: + if not use_unroll: return compile_simple_loop(metainterp, greenkey, trace, jumpargs, enable_opts, cut_at) call_pure_results = metainterp.call_pure_results - preamble_data = LoopCompileData(trace, jumpargs, + preamble_data = PreambleCompileData(trace, jumpargs, call_pure_results=call_pure_results, enable_opts=enable_opts) try: - start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd, - preamble_data, - metainterp.box_names_memo) + start_state, preamble_ops = preamble_data.optimize_trace( + metainterp_sd, jitdriver_sd, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -305,9 +291,8 @@ call_pure_results=call_pure_results, enable_opts=enable_opts) try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) + loop_info, loop_ops = loop_data.optimize_trace( + metainterp_sd, jitdriver_sd, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() history.cut(cut_at) @@ -354,8 +339,6 @@ """Try to compile a new procedure by closing the current history back to the first operation. """ - from rpython.jit.metainterp.optimizeopt import optimize_trace - trace = metainterp.history.trace.cut_trace_from(start, inputargs) metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd @@ -375,29 +358,14 @@ call_pure_results=call_pure_results, enable_opts=enable_opts) try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) + loop_info, loop_ops = loop_data.optimize_trace( + metainterp_sd, jitdriver_sd, metainterp.box_names_memo) except InvalidLoop: - # Fall back on jumping directly to preamble + metainterp_sd.jitlog.trace_aborted() history.cut(cut) - history.record(rop.JUMP, jumpargs[:], None, descr=loop_jitcell_token) - loop_data = UnrolledLoopData(trace, loop_jitcell_token, start_state, - call_pure_results=call_pure_results, - enable_opts=enable_opts, - inline_short_preamble=False) - try: - loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, - loop_data, - metainterp.box_names_memo) - except InvalidLoop: - metainterp_sd.jitlog.trace_aborted() - history.cut(cut) - return None + return None label_op = loop_info.label_op - if label_op is None: - assert False, "unreachable code" # hint for some strange tests label_token = label_op.getdescr() assert isinstance(label_token, TargetToken) if label_token.short_preamble: @@ -405,9 +373,8 @@ label_token.short_preamble, metainterp.box_names_memo) loop = partial_trace loop.original_jitcell_token = loop_jitcell_token - loop.operations = (loop.operations + loop_info.extra_same_as + - [loop_info.label_op] - + loop_ops) + loop.operations = ( + loop.operations + loop_info.extra_same_as + [label_op] + loop_ops) quasi_immutable_deps = {} if loop_info.quasi_immutable_deps: @@ -419,8 +386,6 @@ target_token = loop.operations[-1].getdescr() resumekey.compile_and_attach(metainterp, loop, inputargs) - - record_loop_or_bridge(metainterp_sd, loop) return target_token def get_box_replacement(op, allow_none=False): @@ -828,6 +793,7 @@ self, inputargs, new_loop.operations, new_loop.original_jitcell_token, metainterp.box_names_memo) + record_loop_or_bridge(metainterp.staticdata, new_loop) def make_a_counter_per_value(self, guard_value_op, index): assert guard_value_op.getopnum() == rop.GUARD_VALUE @@ -1038,18 +1004,16 @@ jitdriver_sd.warmstate.attach_procedure_to_interp( self.original_greenkey, jitcell_token) metainterp_sd.stats.add_jitcell_token(jitcell_token) + record_loop_or_bridge(metainterp_sd, new_loop) def get_resumestorage(self): return None -def compile_trace(metainterp, resumekey, runtime_boxes): +def compile_trace(metainterp, resumekey, runtime_boxes, ends_with_jump=False): """Try to compile a new bridge leading from the beginning of the history to some existing place. """ - - from rpython.jit.metainterp.optimizeopt import optimize_trace - # The history contains new operations to attach as the code for the # failure of 'resumekey.guard_op'. # @@ -1058,11 +1022,6 @@ metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd - # - jd_name = jitdriver_sd.jitdriver.name - metainterp_sd.jitlog.start_new_trace(metainterp_sd, - faildescr=resumekey, entry_bridge=False, jd_name=jd_name) - # if isinstance(resumekey, ResumeAtPositionDescr): inline_short_preamble = False else: @@ -1071,11 +1030,15 @@ trace = metainterp.history.trace jitdriver_sd = metainterp.jitdriver_sd enable_opts = jitdriver_sd.warmstate.enable_opts - call_pure_results = metainterp.call_pure_results resumestorage = resumekey.get_resumestorage() - if metainterp.history.ends_with_jump: + trace.tracing_done() + metainterp_sd.jitlog.start_new_trace(metainterp_sd, + faildescr=resumekey, entry_bridge=False, + jd_name=jitdriver_sd.jitdriver.name) + + if ends_with_jump: data = BridgeCompileData(trace, runtime_boxes, resumestorage, call_pure_results=call_pure_results, enable_opts=enable_opts, @@ -1085,12 +1048,10 @@ call_pure_results=call_pure_results, enable_opts=enable_opts) try: - info, newops = optimize_trace(metainterp_sd, jitdriver_sd, - data, metainterp.box_names_memo) + info, newops = data.optimize_trace( + metainterp_sd, jitdriver_sd, metainterp.box_names_memo) except InvalidLoop: metainterp_sd.jitlog.trace_aborted() - #pdb.post_mortem(sys.exc_info()[2]) - debug_print("compile_new_bridge: got an InvalidLoop") # XXX I am fairly convinced that optimize_bridge cannot actually raise # InvalidLoop debug_print('InvalidLoop in compile_new_bridge') @@ -1104,7 +1065,6 @@ new_trace.inputargs = info.inputargs target_token = new_trace.operations[-1].getdescr() resumekey.compile_and_attach(metainterp, new_trace, inputargs) - record_loop_or_bridge(metainterp_sd, new_trace) return target_token new_trace.inputargs = info.renamed_inputargs metainterp.retrace_needed(new_trace, info) diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -689,7 +689,6 @@ class History(object): - ends_with_jump = False trace = None def __init__(self): diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py --- a/rpython/jit/metainterp/opencoder.py +++ b/rpython/jit/metainterp/opencoder.py @@ -7,12 +7,13 @@ """ from rpython.jit.metainterp.history import ( - ConstInt, Const, ConstFloat, ConstPtr, new_ref_dict) + ConstInt, Const, ConstFloat, ConstPtr, new_ref_dict, SwitchToBlackhole) from rpython.jit.metainterp.resoperation import AbstractResOp, AbstractInputArg,\ ResOperation, oparity, rop, opwithdescr, GuardResOp, IntOp, FloatOp, RefOp,\ opclasses from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.objectmodel import we_are_translated, specialize +from rpython.rlib.jit import Counters from rpython.rtyper.lltypesystem import rffi, lltype, llmemory TAGINT, TAGCONSTPTR, TAGCONSTOTHER, TAGBOX = range(4) @@ -301,7 +302,8 @@ def tracing_done(self): from rpython.rlib.debug import debug_start, debug_stop, debug_print - assert not self.tag_overflow + if self.tag_overflow: + raise SwitchToBlackhole(Counters.ABORT_TOO_LONG) self._bigints_dict = {} self._refs_dict = new_ref_dict() diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py --- a/rpython/jit/metainterp/optimizeopt/__init__.py +++ b/rpython/jit/metainterp/optimizeopt/__init__.py @@ -1,4 +1,3 @@ -from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer from rpython.jit.metainterp.optimizeopt.rewrite import OptRewrite from rpython.jit.metainterp.optimizeopt.intbounds import OptIntBounds from rpython.jit.metainterp.optimizeopt.virtualize import OptVirtualize @@ -7,10 +6,8 @@ from rpython.jit.metainterp.optimizeopt.simplify import OptSimplify from rpython.jit.metainterp.optimizeopt.pure import OptPure from rpython.jit.metainterp.optimizeopt.earlyforce import OptEarlyForce -from rpython.rlib.rjitlog import rjitlog as jl from rpython.rlib.jit import PARAMETERS, ENABLE_ALL_OPTS from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.debug import debug_start, debug_stop, debug_print ALL_OPTS = [('intbounds', OptIntBounds), @@ -31,45 +28,17 @@ assert ENABLE_ALL_OPTS == ALL_OPTS_NAMES, ( 'please fix rlib/jit.py to say ENABLE_ALL_OPTS = %r' % (ALL_OPTS_NAMES,)) -def build_opt_chain(metainterp_sd, enable_opts): +def build_opt_chain(enable_opts): optimizations = [] - unroll = 'unroll' in enable_opts # 'enable_opts' is normally a dict - if (metainterp_sd.cpu is not None and - not metainterp_sd.cpu.supports_guard_gc_type): - unroll = False for name, opt in unroll_all_opts: if name in enable_opts: if opt is not None: o = opt() optimizations.append(o) - - if ('rewrite' not in enable_opts or 'virtualize' not in enable_opts - or 'heap' not in enable_opts or 'pure' not in enable_opts): - optimizations.append(OptSimplify(unroll)) - - return optimizations, unroll - -def optimize_trace(metainterp_sd, jitdriver_sd, compile_data, memo=None): - """Optimize loop.operations to remove internal overheadish operations. - """ - debug_start("jit-optimize") - try: - # mark that a new trace has been started - log = metainterp_sd.jitlog.log_trace(jl.MARK_TRACE, metainterp_sd, None) - log.write_trace(compile_data.trace) - if compile_data.log_noopt: - metainterp_sd.logger_noopt.log_loop_from_trace(compile_data.trace, memo=memo) - if memo is None: - memo = {} - compile_data.box_names_memo = memo - optimizations, unroll = build_opt_chain(metainterp_sd, - compile_data.enable_opts) - return compile_data.optimize(metainterp_sd, jitdriver_sd, - optimizations, unroll) - finally: - compile_data.forget_optimization_info() - debug_stop("jit-optimize") + if ('rewrite' not in enable_opts or 'virtualize' not in enable_opts or + 'heap' not in enable_opts or 'pure' not in enable_opts): + optimizations.append(OptSimplify()) + return optimizations if __name__ == '__main__': print ALL_OPTS_NAMES - diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py b/rpython/jit/metainterp/optimizeopt/bridgeopt.py --- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py +++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py @@ -3,6 +3,7 @@ from rpython.jit.metainterp import resumecode from rpython.jit.metainterp.history import Const, ConstInt, CONST_NULL +from .info import getptrinfo # adds the following sections at the end of the resume code: @@ -75,7 +76,7 @@ for box in liveboxes: if box is None or box.type != "r": continue - info = optimizer.getptrinfo(box) + info = getptrinfo(box) known_class = info is not None and info.get_known_class(optimizer.cpu) is not None bitfield <<= 1 bitfield |= known_class diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -1,26 +1,19 @@ -import os from collections import OrderedDict from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.optimizeopt.util import args_dict -from rpython.jit.metainterp.history import Const, ConstInt, new_ref_dict -from rpython.jit.metainterp.jitexc import JitException +from rpython.jit.metainterp.history import new_ref_dict from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED -from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method +from rpython.jit.metainterp.optimizeopt.util import ( + make_dispatcher_method, get_box_replacement) from rpython.jit.metainterp.optimizeopt.intutils import IntBound from rpython.jit.metainterp.optimizeopt.shortpreamble import PreambleOp from rpython.jit.metainterp.optimize import InvalidLoop -from rpython.jit.metainterp.resoperation import rop, ResOperation, OpHelpers,\ - GuardResOp +from rpython.jit.metainterp.resoperation import rop from rpython.rlib.objectmodel import we_are_translated from rpython.jit.metainterp.optimizeopt import info - -class BogusImmutableField(JitException): - pass - - class AbstractCachedEntry(object): """ abstract base class abstracting over the difference between caching struct fields and array items. """ @@ -56,40 +49,32 @@ descr, index=-1): assert self._lazy_set is None for i, info in enumerate(self.cached_infos): - structbox = optimizer.get_box_replacement(self.cached_structs[i]) + structbox = get_box_replacement(self.cached_structs[i]) info.produce_short_preamble_ops(structbox, descr, index, optimizer, shortboxes) - def possible_aliasing(self, optheap, opinfo): + def possible_aliasing(self, opinfo): # If lazy_set is set and contains a setfield on a different # structvalue, then we are annoyed, because it may point to either # the same or a different structure at runtime. # XXX constants? return (self._lazy_set is not None - and (not optheap.getptrinfo( - self._lazy_set.getarg(0)).same_info(opinfo))) + and not info.getptrinfo(self._lazy_set.getarg(0)).same_info(opinfo)) def do_setfield(self, optheap, op): # Update the state with the SETFIELD_GC/SETARRAYITEM_GC operation 'op'. structinfo = optheap.ensure_ptr_info_arg0(op) - arg1 = optheap.get_box_replacement(self._get_rhs_from_set_op(op)) - if self.possible_aliasing(optheap, structinfo): + arg1 = get_box_replacement(self._get_rhs_from_set_op(op)) + if self.possible_aliasing(structinfo): self.force_lazy_set(optheap, op.getdescr()) - assert not self.possible_aliasing(optheap, structinfo) + assert not self.possible_aliasing(structinfo) cached_field = self._getfield(structinfo, op.getdescr(), optheap, False) if cached_field is not None: - cached_field = optheap.get_box_replacement(cached_field) - - # Hack to ensure constants are imported from the preamble - # XXX no longer necessary? - #if cached_fieldvalue and fieldvalue.is_constant(): - # optheap.optimizer.ensure_imported(cached_fieldvalue) - # cached_fieldvalue = self._cached_fields.get(structvalue, None) + cached_field = cached_field.get_box_replacement() if not cached_field or not cached_field.same_box(arg1): # common case: store the 'op' as lazy_set self._lazy_set = op - else: # this is the case where the pending setfield ends up # storing precisely the value that is already there, @@ -104,11 +89,11 @@ def getfield_from_cache(self, optheap, opinfo, descr): # Returns the up-to-date field's value, or None if not cached. - if self.possible_aliasing(optheap, opinfo): + if self.possible_aliasing(opinfo): self.force_lazy_set(optheap, descr) if self._lazy_set is not None: op = self._lazy_set - return optheap.get_box_replacement(self._get_rhs_from_set_op(op)) + return get_box_replacement(self._get_rhs_from_set_op(op)) else: res = self._getfield(opinfo, descr, optheap) if res is not None: @@ -140,7 +125,6 @@ elif not can_cache: self.invalidate(descr) - # abstract methods def _get_rhs_from_set_op(self, op): @@ -167,8 +151,8 @@ return op.getarg(1) def put_field_back_to_info(self, op, opinfo, optheap): - arg = optheap.get_box_replacement(op.getarg(1)) - struct = optheap.get_box_replacement(op.getarg(0)) + arg = get_box_replacement(op.getarg(1)) + struct = get_box_replacement(op.getarg(0)) opinfo.setfield(op.getdescr(), struct, arg, optheap=optheap, cf=self) def _getfield(self, opinfo, descr, optheap, true_force=True): @@ -216,8 +200,8 @@ return res def put_field_back_to_info(self, op, opinfo, optheap): - arg = optheap.get_box_replacement(op.getarg(2)) - struct = optheap.get_box_replacement(op.getarg(0)) + arg = get_box_replacement(op.getarg(2)) + struct = get_box_replacement(op.getarg(0)) opinfo.setitem(op.getdescr(), self.index, struct, arg, optheap=optheap, cf=self) def invalidate(self, descr): @@ -412,8 +396,8 @@ d = self.cached_dict_reads[descr1] = args_dict() self.corresponding_array_descrs[descrs[1]] = descr1 # - key = [self.optimizer.get_box_replacement(op.getarg(1)), # dict - self.optimizer.get_box_replacement(op.getarg(2))] # key + key = [get_box_replacement(op.getarg(1)), # dict + get_box_replacement(op.getarg(2))] # key # other args can be ignored here (hash, store_flag) try: res_v = d[key] @@ -525,7 +509,7 @@ # guards' resume data is that of a virtual object that is stored # into a field of a non-virtual object. Here, 'op' in either # SETFIELD_GC or SETARRAYITEM_GC. - opinfo = self.getptrinfo(op.getarg(0)) + opinfo = info.getptrinfo(op.getarg(0)) assert not opinfo.is_virtual() # it must be a non-virtual if self.optimizer.is_virtual(op.getarg(2)): pendingfields.append(op) @@ -564,13 +548,6 @@ def optimize_SETFIELD_GC(self, op): self.setfield(op) - #opnum = OpHelpers.getfield_pure_for_descr(op.getdescr()) - #if self.has_pure_result(opnum, [op.getarg(0)], - # op.getdescr()): - # os.write(2, '[bogus _immutable_field_ declaration: %s]\n' % - # (op.getdescr().repr_of_descr())) - # raise BogusImmutableField - # def setfield(self, op): cf = self.field_cache(op.getdescr()) @@ -606,8 +583,8 @@ index = indexb.getint() cf = self.arrayitem_cache(op.getdescr(), index) arrayinfo.setitem(op.getdescr(), indexb.getint(), - self.get_box_replacement(op.getarg(0)), - self.get_box_replacement(op), optheap=self, + get_box_replacement(op.getarg(0)), + get_box_replacement(op), optheap=self, cf=cf) optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_GC_I optimize_GETARRAYITEM_GC_F = optimize_GETARRAYITEM_GC_I @@ -639,13 +616,6 @@ optimize_GETARRAYITEM_GC_PURE_F = optimize_GETARRAYITEM_GC_PURE_I def optimize_SETARRAYITEM_GC(self, op): - #opnum = OpHelpers.getarrayitem_pure_for_descr(op.getdescr()) - #if self.has_pure_result(opnum, [op.getarg(0), op.getarg(1)], - # op.getdescr()): - # os.write(2, '[bogus immutable array declaration: %s]\n' % - # (op.getdescr().repr_of_descr())) - # raise BogusImmutableField - # indexb = self.getintbound(op.getarg(1)) if indexb.is_constant(): arrayinfo = self.ensure_ptr_info_arg0(op) @@ -680,8 +650,7 @@ # check that the value is still correct; it could have changed # already between the tracing and now. In this case, we mark the loop # as invalid - if not qmutdescr.is_still_valid_for( - self.get_box_replacement(op.getarg(0))): + if not qmutdescr.is_still_valid_for(get_box_replacement(op.getarg(0))): raise InvalidLoop('quasi immutable field changed during tracing') # record as an out-of-line guard if self.optimizer.quasi_immutable_deps is None: @@ -701,10 +670,10 @@ result_getfield = [] for descr, cf in self.cached_fields.iteritems(): if cf._lazy_set: - continue # XXX safe default for now + continue # XXX safe default for now parent_descr = descr.get_parent_descr() if not parent_descr.is_object(): - continue # XXX could be extended to non-instance objects + continue # XXX could be extended to non-instance objects for i, box1 in enumerate(cf.cached_structs): if not box1.is_constant() and box1 not in available_boxes: continue @@ -721,7 +690,7 @@ for descr, indexdict in self.cached_arrayitems.iteritems(): for index, cf in indexdict.iteritems(): if cf._lazy_set: - continue # XXX safe default for now + continue # XXX safe default for now for i, box1 in enumerate(cf.cached_structs): if not box1.is_constant() and box1 not in available_boxes: continue diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -1,13 +1,14 @@ -from rpython.rlib.objectmodel import specialize, we_are_translated, compute_hash -from rpython.jit.metainterp.resoperation import AbstractValue, ResOperation,\ - rop, OpHelpers -from rpython.jit.metainterp.history import ConstInt, Const -from rpython.rtyper.lltypesystem import lltype, llmemory -from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, InvalidRawOperation +from rpython.rlib.objectmodel import specialize, compute_hash +from rpython.jit.metainterp.resoperation import ( + AbstractValue, ResOperation, rop, OpHelpers) +from rpython.jit.metainterp.history import ConstInt, ConstPtr, Const +from rpython.rtyper.lltypesystem import lltype +from rpython.jit.metainterp.optimizeopt.rawbuffer import ( + RawBuffer, InvalidRawOperation) from rpython.jit.metainterp.executor import execute from rpython.jit.metainterp.optimize import InvalidLoop - +from .util import get_box_replacement INFO_NULL = 0 INFO_NONNULL = 1 @@ -51,7 +52,7 @@ def force_at_the_end_of_preamble(self, op, optforce, rec): if not self.is_virtual(): - return optforce.get_box_replacement(op) + return get_box_replacement(op) return self._force_at_the_end_of_preamble(op, optforce, rec) def get_known_class(self, cpu): @@ -84,7 +85,7 @@ @specialize.arg(2) def get_constant_string_spec(self, string_optimizer, mode): - return None # can't be constant + return None # can't be constant class NonNullPtrInfo(PtrInfo): _attrs_ = ('last_guard_pos',) @@ -109,7 +110,7 @@ def mark_last_guard(self, optimizer): if (optimizer.getlastop() is None or - not optimizer.getlastop().is_guard()): + not optimizer.getlastop().is_guard()): # there can be a really emitted operation that's not a guard # e.g. a setfield, ignore those return @@ -140,12 +141,12 @@ constptr = optforce.optimizer.constant_fold(op) op.set_forwarded(constptr) self._is_virtual = False - self._force_elements_immutable(self.descr, constptr, optforce) + self._force_elements_immutable(self.descr, constptr, optforce.optimizer) return constptr # op.set_forwarded(None) optforce.emit_extra(op) - newop = optforce.getlastop() + newop = optforce.optimizer.getlastop() if newop is not op: op.set_forwarded(newop) newop.set_forwarded(self) @@ -161,14 +162,14 @@ def is_virtual(self): return self._is_virtual - def _visitor_walk_recursive(self, op, visitor, optimizer): + def _visitor_walk_recursive(self, op, visitor): raise NotImplementedError("abstract") - def visitor_walk_recursive(self, instbox, visitor, optimizer): + def visitor_walk_recursive(self, instbox, visitor): instbox = instbox.get_box_replacement() if visitor.already_seen_virtual(instbox): return - return self._visitor_walk_recursive(instbox, visitor, optimizer) + return self._visitor_walk_recursive(instbox, visitor) class AbstractStructPtrInfo(AbstractVirtualPtrInfo): @@ -181,7 +182,7 @@ self.descr = descr self._fields = [None] * len(descr.get_all_fielddescrs()) if index >= len(self._fields): - self.descr = descr # a more precise descr + self.descr = descr # a more precise descr # we found out a subclass with more fields extra_len = len(descr.get_all_fielddescrs()) - len(self._fields) self._fields = self._fields + [None] * extra_len @@ -218,7 +219,7 @@ for i, fielddescr in enumerate(descr.get_all_fielddescrs()): fld = self._fields[i] if fld is not None: - subbox = optforce.force_box(fld) + subbox = optforce.optimizer.force_box(fld) setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox], descr=fielddescr) self._fields[i] = None @@ -226,31 +227,30 @@ def _force_at_the_end_of_preamble(self, op, optforce, rec): if self._fields is None: - return optforce.get_box_replacement(op) + return get_box_replacement(op) if self in rec: - return optforce.get_box_replacement(op) + return get_box_replacement(op) rec[self] = None for i, fldbox in enumerate(self._fields): if fldbox is not None: - info = optforce.getptrinfo(fldbox) + info = getptrinfo(fldbox) if info is not None: fldbox = info.force_at_the_end_of_preamble(fldbox, optforce, rec) self._fields[i] = fldbox return op - def _visitor_walk_recursive(self, instbox, visitor, optimizer): + def _visitor_walk_recursive(self, instbox, visitor): lst = self.descr.get_all_fielddescrs() assert self.is_virtual() - visitor.register_virtual_fields(instbox, - [optimizer.get_box_replacement(box) - for box in self._fields]) + visitor.register_virtual_fields( + instbox, [get_box_replacement(box) for box in self._fields]) for i in range(len(lst)): op = self._fields[i] if op: - fieldinfo = optimizer.getptrinfo(op) + fieldinfo = getptrinfo(op) if fieldinfo and fieldinfo.is_virtual(): - fieldinfo.visitor_walk_recursive(op, visitor, optimizer) + fieldinfo.visitor_walk_recursive(op, visitor) def produce_short_preamble_ops(self, structbox, fielddescr, index, optimizer, shortboxes): @@ -259,7 +259,7 @@ if fielddescr.get_index() >= len(self._fields): # we don't know about this item return - op = optimizer.get_box_replacement(self._fields[fielddescr.get_index()]) + op = get_box_replacement(self._fields[fielddescr.get_index()]) if op is None: # XXX same bug as in serialize_opt: # op should never be None, because that's an invariant violation in @@ -290,7 +290,7 @@ if op.is_constant(): pass # it is a constant value: ok else: - fieldinfo = optimizer.getptrinfo(op) + fieldinfo = getptrinfo(op) if fieldinfo and fieldinfo.is_virtual(): # recursive check if memo is None: @@ -302,12 +302,12 @@ return False # not a constant at all return True - def _force_elements_immutable(self, descr, constptr, optforce): + def _force_elements_immutable(self, descr, constptr, optimizer): for i, fielddescr in enumerate(descr.get_all_fielddescrs()): fld = self._fields[i] - subbox = optforce.force_box(fld) + subbox = optimizer.force_box(fld) assert isinstance(subbox, Const) - execute(optforce.optimizer.cpu, None, rop.SETFIELD_GC, + execute(optimizer.cpu, None, rop.SETFIELD_GC, fielddescr, constptr, subbox) class InstancePtrInfo(AbstractStructPtrInfo): @@ -435,8 +435,8 @@ [op, ConstInt(offset), itembox], descr=descr) optforce.emit_extra(setfield_op) - def _visitor_walk_recursive(self, op, visitor, optimizer): - itemboxes = [optimizer.get_box_replacement(box) + def _visitor_walk_recursive(self, op, visitor): + itemboxes = [get_box_replacement(box) for box in self._get_buffer().values] visitor.register_virtual_fields(op, itemboxes) # there can be no virtuals stored in raw buffer @@ -465,21 +465,21 @@ return self.parent is not None def getitem_raw(self, offset, itemsize, descr): - return self.parent.getitem_raw(self.offset+offset, itemsize, descr) + return self.parent.getitem_raw(self.offset + offset, itemsize, descr) def setitem_raw(self, offset, itemsize, descr, itemop): - self.parent.setitem_raw(self.offset+offset, itemsize, descr, itemop) + self.parent.setitem_raw(self.offset + offset, itemsize, descr, itemop) def _force_elements(self, op, optforce, descr): if self.parent.is_virtual(): self.parent._force_elements(op, optforce, descr) self.parent = None - def _visitor_walk_recursive(self, op, visitor, optimizer): - source_op = optimizer.get_box_replacement(op.getarg(0)) + def _visitor_walk_recursive(self, op, visitor): + source_op = get_box_replacement(op.getarg(0)) visitor.register_virtual_fields(op, [source_op]) if self.parent.is_virtual(): - self.parent.visitor_walk_recursive(source_op, visitor, optimizer) + self.parent.visitor_walk_recursive(source_op, visitor) @specialize.argtype(1) def visitor_dispatch_virtual_type(self, visitor): @@ -534,7 +534,7 @@ def _force_elements(self, op, optforce, descr): # XXX descr = op.getdescr() - const = optforce.new_const_item(self.descr) + const = optforce.optimizer.new_const_item(self.descr) for i in range(self.length): item = self._items[i] if item is None: @@ -543,7 +543,7 @@ # clear the item so we don't know what's there self._items[i] = None continue - subbox = optforce.force_box(item) + subbox = optforce.optimizer.force_box(item) setop = ResOperation(rop.SETARRAYITEM_GC, [op, ConstInt(i), subbox], descr=descr) @@ -570,17 +570,15 @@ def getlength(self): return self.length - def _visitor_walk_recursive(self, instbox, visitor, optimizer): - itemops = [optimizer.get_box_replacement(item) - for item in self._items] + def _visitor_walk_recursive(self, instbox, visitor): + itemops = [get_box_replacement(item) for item in self._items] visitor.register_virtual_fields(instbox, itemops) for i in range(self.getlength()): itemop = self._items[i] - if (itemop is not None and - not isinstance(itemop, Const)): - ptrinfo = optimizer.getptrinfo(itemop) + if (itemop is not None and not isinstance(itemop, Const)): + ptrinfo = getptrinfo(itemop) if ptrinfo and ptrinfo.is_virtual(): - ptrinfo.visitor_walk_recursive(itemop, visitor, optimizer) + ptrinfo.visitor_walk_recursive(itemop, visitor) @specialize.argtype(1) def visitor_dispatch_virtual_type(self, visitor): @@ -596,7 +594,7 @@ item = self._items[index] if item is not None: # see comment in AbstractStructPtrInfo.produce_short_preamble_ops - op = optimizer.get_box_replacement(item) + op = get_box_replacement(item) opnum = OpHelpers.getarrayitem_for_descr(descr) getarrayitem_op = ResOperation(opnum, [structbox, ConstInt(index)], descr=descr) @@ -604,13 +602,13 @@ def _force_at_the_end_of_preamble(self, op, optforce, rec): if self._items is None: - return optforce.get_box_replacement(op) + return get_box_replacement(op) if self in rec: - return optforce.get_box_replacement(op) + return get_box_replacement(op) rec[self] = None for i, fldbox in enumerate(self._items): if fldbox is not None: - info = optforce.getptrinfo(fldbox) + info = getptrinfo(fldbox) if info is not None: fldbox = info.force_at_the_end_of_preamble(fldbox, optforce, rec) @@ -640,7 +638,7 @@ def _compute_index(self, index, fielddescr): all_fdescrs = fielddescr.get_arraydescr().get_all_fielddescrs() if all_fdescrs is None: - return 0 # annotation hack + return 0 # annotation hack one_size = len(all_fdescrs) return index * one_size + fielddescr.get_field_descr().get_index() @@ -659,7 +657,7 @@ for fielddescr in fielddescrs: fld = self._items[i] if fld is not None: - subbox = optforce.force_box(fld) + subbox = optforce.optimizer.force_box(fld) setfieldop = ResOperation(rop.SETINTERIORFIELD_GC, [op, ConstInt(index), subbox], descr=fielddescr) @@ -668,21 +666,18 @@ # if it does, we would need a fix here i += 1 - def _visitor_walk_recursive(self, instbox, visitor, optimizer): - itemops = [optimizer.get_box_replacement(item) - for item in self._items] + def _visitor_walk_recursive(self, instbox, visitor): + itemops = [get_box_replacement(item) for item in self._items] visitor.register_virtual_fields(instbox, itemops) fielddescrs = self.descr.get_all_fielddescrs() i = 0 for index in range(self.getlength()): for fielddescr in fielddescrs: itemop = self._items[i] - if (itemop is not None and - not isinstance(itemop, Const)): - ptrinfo = optimizer.getptrinfo(itemop) + if (itemop is not None and not isinstance(itemop, Const)): + ptrinfo = getptrinfo(itemop) if ptrinfo and ptrinfo.is_virtual(): - ptrinfo.visitor_walk_recursive(itemop, visitor, - optimizer) + ptrinfo.visitor_walk_recursive(itemop, visitor) i += 1 @specialize.argtype(1) @@ -705,7 +700,8 @@ def _get_info(self, descr, optheap): ref = self._const.getref_base() - if not ref: raise InvalidLoop # null protection + if not ref: + raise InvalidLoop # null protection info = optheap.const_infos.get(ref, None) if info is None: info = StructPtrInfo(descr) @@ -714,7 +710,8 @@ def _get_array_info(self, descr, optheap): ref = self._const.getref_base() - if not ref: raise InvalidLoop # null protection + if not ref: + raise InvalidLoop # null protection info = optheap.const_infos.get(ref, None) if info is None: info = ArrayPtrInfo(descr) @@ -780,8 +777,8 @@ return self._unpack_str(mode) def getlenbound(self, mode): - from rpython.jit.metainterp.optimizeopt.intutils import ConstIntBound,\ - IntLowerBound + from rpython.jit.metainterp.optimizeopt.intutils import ( + ConstIntBound, IntLowerBound) length = self.getstrlen1(mode) if length < 0: @@ -848,3 +845,36 @@ def make_guards(self, op, short, optimizer): short.append(ResOperation(rop.GUARD_VALUE, [op, self._const])) + + +def getrawptrinfo(op): + from rpython.jit.metainterp.optimizeopt.intutils import IntBound + assert op.type == 'i' + op = op.get_box_replacement() + assert op.type == 'i' + if isinstance(op, ConstInt): + return ConstPtrInfo(op) + fw = op.get_forwarded() + if isinstance(fw, IntBound): + return None + if fw is not None: + assert isinstance(fw, AbstractRawPtrInfo) + return fw + return None + +def getptrinfo(op): + if op.type == 'i': + return getrawptrinfo(op) + elif op.type == 'f': + return None + assert op.type == 'r' + op = get_box_replacement(op) + assert op.type == 'r' + if isinstance(op, ConstPtr): + return ConstPtrInfo(op) + fw = op.get_forwarded() + if fw is not None: + assert isinstance(fw, PtrInfo) + return fw + return None + diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py --- a/rpython/jit/metainterp/optimizeopt/intbounds.py +++ b/rpython/jit/metainterp/optimizeopt/intbounds.py @@ -5,7 +5,9 @@ IntLowerBound, IntUpperBound, ConstIntBound) from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, CONST_1, CONST_0) -from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method +from rpython.jit.metainterp.optimizeopt.util import ( + make_dispatcher_method, get_box_replacement) +from .info import getptrinfo from rpython.jit.metainterp.resoperation import rop from rpython.jit.metainterp.optimizeopt import vstring from rpython.jit.codewriter.effectinfo import EffectInfo @@ -64,8 +66,8 @@ postprocess_GUARD_VALUE = _postprocess_guard_true_false_value def optimize_INT_OR_or_XOR(self, op): - v1 = self.get_box_replacement(op.getarg(0)) - v2 = self.get_box_replacement(op.getarg(1)) + v1 = get_box_replacement(op.getarg(0)) + v2 = get_box_replacement(op.getarg(1)) if v1 is v2: if op.getopnum() == rop.INT_OR: self.make_equal_to(op, v1) @@ -75,9 +77,9 @@ return self.emit(op) def postprocess_INT_OR_or_XOR(self, op): - v1 = self.get_box_replacement(op.getarg(0)) + v1 = get_box_replacement(op.getarg(0)) b1 = self.getintbound(v1) - v2 = self.get_box_replacement(op.getarg(1)) + v2 = get_box_replacement(op.getarg(1)) b2 = self.getintbound(v2) b = b1.or_bound(b2) self.getintbound(op).intersect(b) @@ -108,8 +110,8 @@ self.getintbound(op).intersect(b) def optimize_INT_ADD(self, op): - arg1 = self.get_box_replacement(op.getarg(0)) - arg2 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(0)) + arg2 = get_box_replacement(op.getarg(1)) if self.is_raw_ptr(arg1) or self.is_raw_ptr(arg2): return self.emit(op) v1 = self.getintbound(arg1) @@ -130,8 +132,8 @@ arg1 = self.optimizer.as_operation(arg1) if arg1 is not None: if arg1.getopnum() == rop.INT_ADD: - prod_arg1 = self.get_box_replacement(arg1.getarg(0)) - prod_arg2 = self.get_box_replacement(arg1.getarg(1)) + prod_arg1 = get_box_replacement(arg1.getarg(0)) + prod_arg2 = get_box_replacement(arg1.getarg(1)) prod_v1 = self.getintbound(prod_arg1) prod_v2 = self.getintbound(prod_arg2) @@ -196,9 +198,9 @@ return self.emit(op) def postprocess_INT_LSHIFT(self, op): - arg0 = self.get_box_replacement(op.getarg(0)) + arg0 = get_box_replacement(op.getarg(0)) b1 = self.getintbound(arg0) - arg1 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(1)) b2 = self.getintbound(arg1) r = self.getintbound(op) b = b1.lshift_bound(b2) @@ -290,8 +292,8 @@ r.intersect(resbound) def optimize_INT_SUB_OVF(self, op): - arg0 = self.get_box_replacement(op.getarg(0)) - arg1 = self.get_box_replacement(op.getarg(1)) + arg0 = get_box_replacement(op.getarg(0)) + arg1 = get_box_replacement(op.getarg(1)) b0 = self.getintbound(arg0) b1 = self.getintbound(arg1) if arg0.same_box(arg1): @@ -304,8 +306,8 @@ return self.emit(op) def postprocess_INT_SUB_OVF(self, op): - arg0 = self.get_box_replacement(op.getarg(0)) - arg1 = self.get_box_replacement(op.getarg(1)) + arg0 = get_box_replacement(op.getarg(0)) + arg1 = get_box_replacement(op.getarg(1)) b0 = self.getintbound(arg0) b1 = self.getintbound(arg1) resbound = b0.sub_bound(b1) @@ -329,8 +331,8 @@ r.intersect(resbound) def optimize_INT_LT(self, op): - arg1 = self.get_box_replacement(op.getarg(0)) - arg2 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(0)) + arg2 = get_box_replacement(op.getarg(1)) b1 = self.getintbound(arg1) b2 = self.getintbound(arg2) if b1.known_lt(b2): @@ -341,8 +343,8 @@ return self.emit(op) def optimize_INT_GT(self, op): - arg1 = self.get_box_replacement(op.getarg(0)) - arg2 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(0)) + arg2 = get_box_replacement(op.getarg(1)) b1 = self.getintbound(arg1) b2 = self.getintbound(arg2) if b1.known_gt(b2): @@ -353,8 +355,8 @@ return self.emit(op) def optimize_INT_LE(self, op): - arg1 = self.get_box_replacement(op.getarg(0)) - arg2 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(0)) + arg2 = get_box_replacement(op.getarg(1)) b1 = self.getintbound(arg1) b2 = self.getintbound(arg2) if b1.known_le(b2) or arg1 is arg2: @@ -365,8 +367,8 @@ return self.emit(op) def optimize_INT_GE(self, op): - arg1 = self.get_box_replacement(op.getarg(0)) - arg2 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(0)) + arg2 = get_box_replacement(op.getarg(1)) b1 = self.getintbound(arg1) b2 = self.getintbound(arg2) if b1.known_ge(b2) or arg1 is arg2: @@ -377,9 +379,9 @@ return self.emit(op) def optimize_INT_EQ(self, op): - arg0 = self.get_box_replacement(op.getarg(0)) + arg0 = get_box_replacement(op.getarg(0)) b1 = self.getintbound(arg0) - arg1 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(1)) b2 = self.getintbound(arg1) if b1.known_gt(b2): self.make_constant_int(op, 0) @@ -391,9 +393,9 @@ return self.emit(op) def optimize_INT_NE(self, op): - arg0 = self.get_box_replacement(op.getarg(0)) + arg0 = get_box_replacement(op.getarg(0)) b1 = self.getintbound(arg0) - arg1 = self.get_box_replacement(op.getarg(1)) + arg1 = get_box_replacement(op.getarg(1)) b2 = self.getintbound(arg1) if b1.known_gt(b2): self.make_constant_int(op, 1) @@ -442,7 +444,7 @@ def postprocess_STRLEN(self, op): self.make_nonnull_str(op.getarg(0), vstring.mode_string) - array = self.getptrinfo(op.getarg(0)) + array = getptrinfo(op.getarg(0)) self.optimizer.setintbound(op, array.getlenbound(vstring.mode_string)) def optimize_UNICODELEN(self, op): @@ -450,7 +452,7 @@ def postprocess_UNICODELEN(self, op): self.make_nonnull_str(op.getarg(0), vstring.mode_unicode) - array = self.getptrinfo(op.getarg(0)) + array = getptrinfo(op.getarg(0)) self.optimizer.setintbound(op, array.getlenbound(vstring.mode_unicode)) def optimize_STRGETITEM(self, op): @@ -458,7 +460,7 @@ def postprocess_STRGETITEM(self, op): v1 = self.getintbound(op) - v2 = self.getptrinfo(op.getarg(0)) + v2 = getptrinfo(op.getarg(0)) intbound = self.getintbound(op.getarg(1)) if (intbound.has_lower and v2 is not None and v2.getlenbound(vstring.mode_string) is not None): @@ -523,7 +525,7 @@ def postprocess_UNICODEGETITEM(self, op): b1 = self.getintbound(op) b1.make_ge(IntLowerBound(0)) - v2 = self.getptrinfo(op.getarg(0)) + v2 = getptrinfo(op.getarg(0)) intbound = self.getintbound(op.getarg(1)) if (intbound.has_lower and v2 is not None and v2.getlenbound(vstring.mode_unicode) is not None): diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -1,16 +1,19 @@ from rpython.jit.metainterp import jitprof, resume, compile from rpython.jit.metainterp.executor import execute_nonspec_const from rpython.jit.metainterp.history import ( - Const, ConstInt, ConstPtr, CONST_NULL, new_ref_dict) -from rpython.jit.metainterp.optimizeopt.intutils import IntBound,\ - ConstIntBound, MININT, MAXINT, IntUnbounded -from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method -from rpython.jit.metainterp.resoperation import rop, AbstractResOp, GuardResOp,\ - OpHelpers + Const, ConstInt, CONST_NULL, new_ref_dict) +from rpython.jit.metainterp.optimizeopt.intutils import ( + IntBound, ConstIntBound, MININT, MAXINT, IntUnbounded) +from rpython.jit.metainterp.optimizeopt.util import ( + make_dispatcher_method, get_box_replacement) +from rpython.jit.metainterp.optimizeopt.bridgeopt import ( + deserialize_optimizer_knowledge) +from rpython.jit.metainterp.resoperation import ( + rop, AbstractResOp, GuardResOp, OpHelpers) +from .info import getrawptrinfo, getptrinfo from rpython.jit.metainterp.optimizeopt import info from rpython.jit.metainterp.optimize import InvalidLoop from rpython.rlib.objectmodel import specialize, we_are_translated -from rpython.rlib.debug import debug_print from rpython.rtyper import rclass from rpython.rtyper.lltypesystem import llmemory from rpython.jit.metainterp.optimize import SpeculativeError @@ -57,9 +60,6 @@ def __init__(self): pass # make rpython happy - def send_extra_operation(self, op, opt=None): - self.optimizer.send_extra_operation(op, opt) - _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit