Author: Richard Plangger <[email protected]>
Branch: ppc-vsx-support
Changeset: r85872:dd5d6c50f5bd
Date: 2016-07-27 12:43 +0200
http://bitbucket.org/pypy/pypy/changeset/dd5d6c50f5bd/
Log: merge default (pull in new-jit-log)
diff too long, truncating to 2000 out of 2870 lines
diff --git a/lib-python/2.7/test/test_hash.py b/lib-python/2.7/test/test_hash.py
--- a/lib-python/2.7/test/test_hash.py
+++ b/lib-python/2.7/test/test_hash.py
@@ -174,7 +174,7 @@
class StringlikeHashRandomizationTests(HashRandomizationTests):
if check_impl_detail(pypy=True):
- EMPTY_STRING_HASH = -1
+ EMPTY_STRING_HASH = -2
else:
EMPTY_STRING_HASH = 0
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -36,7 +36,7 @@
"cStringIO", "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
"binascii", "_multiprocessing", '_warnings', "_collections",
"_multibytecodec", "micronumpy", "_continuation", "_cffi_backend",
- "_csv", "cppyy", "_pypyjson",
+ "_csv", "cppyy", "_pypyjson", "_jitlog"
])
from rpython.jit.backend import detect_cpu
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -104,27 +104,24 @@
apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
- tk-dev libgc-dev liblzma-dev
-
-For the optional lzma module on PyPy3 you will also need ``liblzma-dev``.
+ tk-dev libgc-dev \
+ liblzma-dev # For lzma on PyPy3.
On Fedora::
dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \
lib-sqlite3-devel ncurses-devel expat-devel openssl-devel tk-devel \
- gdbm-devel
-
-For the optional lzma module on PyPy3 you will also need ``xz-devel``.
+ gdbm-devel \
+ xz-devel # For lzma on PyPy3.
On SLES11::
zypper install gcc make python-devel pkg-config \
zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
- libexpat-devel libffi-devel python-curses
+ libexpat-devel libffi-devel python-curses \
+ xz-devel # For lzma on PyPy3.
(XXX plus the SLES11 version of libgdbm-dev and tk-dev)
-For the optional lzma module on PyPy3 you will also need ``xz-devel``.
-
On Mac OS X, most of these build-time dependencies are installed alongside
the Developer Tools. However, note that in order for the installation to
find them you may need to run::
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
@@ -93,3 +93,11 @@
of ctypes. This avoids importing ctypes in many small programs and
scripts, which in turn avoids enabling threads (because ctypes
creates callbacks at import time, and callbacks need threads).
+
+.. branch: new-jit-log
+
+The new logging facility that integrates with and adds features to vmprof.com.
+
+.. branch: jitlog-32bit
+
+Resolve issues to use the new logging facility on a 32bit system
diff --git a/pypy/module/_jitlog/__init__.py b/pypy/module/_jitlog/__init__.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_jitlog/__init__.py
@@ -0,0 +1,13 @@
+from pypy.interpreter.mixedmodule import MixedModule
+from rpython.rlib.rvmprof import VMProfPlatformUnsupported
+
+class Module(MixedModule):
+ """ JitLog the new logging facility """
+ appleveldefs = {
+ }
+
+ interpleveldefs = {
+ 'enable': 'interp_jitlog.enable',
+ 'disable': 'interp_jitlog.disable',
+ 'JitlogError': 'space.fromcache(interp_jitlog.Cache).w_JitlogError',
+ }
diff --git a/pypy/module/_jitlog/interp_jitlog.py
b/pypy/module/_jitlog/interp_jitlog.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_jitlog/interp_jitlog.py
@@ -0,0 +1,28 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.pyframe import PyFrame
+from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.baseobjspace import W_Root
+from rpython.rlib.rjitlog import rjitlog
+from rpython.rlib import jit
+
+class Cache:
+ def __init__(self, space):
+ self.w_JitlogError = space.new_exception_class("_jitlog.JitlogError")
+
+def JitlogError(space, e):
+ w_JitlogError = space.fromcache(Cache).w_JitlogError
+ return OperationError(w_JitlogError, space.wrap(e.msg))
+
+@unwrap_spec(fileno=int)
+def enable(space, fileno):
+ """ Enable PyPy's logging facility. """
+ try:
+ rjitlog.enable_jitlog(fileno)
+ except rjitlog.JitlogError, e:
+ raise JitlogError(space, e)
+
[email protected]_look_inside
+def disable(space):
+ """ Disable PyPy's logging facility. """
+ rjitlog.disable_jitlog()
diff --git a/pypy/module/_jitlog/test/__init__.py
b/pypy/module/_jitlog/test/__init__.py
new file mode 100644
diff --git a/pypy/module/_jitlog/test/test__jitlog.py
b/pypy/module/_jitlog/test/test__jitlog.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_jitlog/test/test__jitlog.py
@@ -0,0 +1,32 @@
+
+import sys
+from rpython.tool.udir import udir
+from pypy.tool.pytest.objspace import gettestobjspace
+from rpython.rlib.rjitlog import rjitlog as jl
+
+class AppTestJitLog(object):
+ spaceconfig = {'usemodules': ['_jitlog', 'struct']}
+
+ def setup_class(cls):
+ cls.w_tmpfilename = cls.space.wrap(str(udir.join('test__jitlog.1')))
+ cls.w_mark_header = cls.space.wrap(jl.MARK_JITLOG_HEADER)
+ cls.w_version = cls.space.wrap(jl.JITLOG_VERSION_16BIT_LE)
+ cls.w_is_32bit = cls.space.wrap(sys.maxint == 2**31-1)
+
+ def test_enable(self):
+ import _jitlog, struct
+ tmpfile = open(self.tmpfilename, 'wb')
+ fileno = tmpfile.fileno()
+ _jitlog.enable(fileno)
+ _jitlog.disable()
+ # no need to clsoe tmpfile, it is done by jitlog
+
+ with open(self.tmpfilename, 'rb') as fd:
+ assert fd.read(1) == self.mark_header
+ assert fd.read(2) == self.version
+ assert bool(ord(fd.read(1))) == self.is_32bit
+ count, = struct.unpack('<h', fd.read(2))
+ for i in range(count):
+ opnum = struct.unpack('<h', fd.read(2))
+ strcount = struct.unpack('<i', fd.read(4))
+ fd.read(strcount)
diff --git a/pypy/module/_vmprof/interp_vmprof.py
b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -3,7 +3,7 @@
from pypy.interpreter.pyframe import PyFrame
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.baseobjspace import W_Root
-from rpython.rlib import rvmprof
+from rpython.rlib import rvmprof, jit
# ____________________________________________________________
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -126,7 +126,14 @@
source_strings=source_strings,
compile_extra=compile_extra,
link_extra=link_extra)
- return str(soname)
+ from imp import get_suffixes, C_EXTENSION
+ pydname = soname
+ for suffix, mode, typ in get_suffixes():
+ if typ == C_EXTENSION:
+ pydname = soname.new(purebasename=modname, ext=suffix)
+ soname.rename(pydname)
+ break
+ return str(pydname)
def freeze_refcnts(self):
rawrefcount._dont_free_any_more()
@@ -359,7 +366,11 @@
space.sys.get('modules'),
space.wrap(name))
else:
- return os.path.dirname(mod)
+ path = os.path.dirname(mod)
+ if self.runappdirect:
+ return path
+ else:
+ return space.wrap(path)
@gateway.unwrap_spec(mod=str, name=str)
def reimport_module(space, mod, name):
diff --git a/pypy/module/cpyext/test/test_import.py
b/pypy/module/cpyext/test/test_import.py
--- a/pypy/module/cpyext/test/test_import.py
+++ b/pypy/module/cpyext/test/test_import.py
@@ -39,7 +39,6 @@
class AppTestImportLogic(AppTestCpythonExtensionBase):
def test_import_logic(self):
- skip("leak?")
path = self.import_module(name='test_import_module', load_it=False)
import sys
sys.path.append(path)
diff --git a/pypy/module/cpyext/test/test_number.py
b/pypy/module/cpyext/test/test_number.py
--- a/pypy/module/cpyext/test/test_number.py
+++ b/pypy/module/cpyext/test/test_number.py
@@ -144,3 +144,15 @@
assert tupl[0] == 3.
assert tupl[1] == 1.
assert isinstance(tupl[0], float)'''
+
+ def test_PyNumber_Check(self):
+ mod = self.import_extension('foo', [
+ ("test_PyNumber_Check", "METH_VARARGS",
+ '''
+ PyObject *obj = PyTuple_GET_ITEM(args, 0);
+ int val = PyNumber_Check(obj);
+ Py_DECREF(obj);
+ return PyInt_FromLong(val);
+ ''')])
+ val = mod.test_PyNumber_Check(10)
+ assert val == 1
diff --git a/pypy/module/cpyext/test/test_object.py
b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -168,7 +168,7 @@
def test_hash(self, space, api):
assert api.PyObject_Hash(space.wrap(72)) == 72
- assert api.PyObject_Hash(space.wrap(-1)) == -1
+ assert api.PyObject_Hash(space.wrap(-1)) == -2
assert (api.PyObject_Hash(space.wrap([])) == -1 and
api.PyErr_Occurred() is space.w_TypeError)
api.PyErr_Clear()
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -729,7 +729,7 @@
x = list(it)
assert x == [1]
- def test_bool(self):
+ def test_intlike(self):
module = self.import_extension('foo', [
("newInt", "METH_VARARGS",
"""
@@ -739,10 +739,6 @@
if (!PyArg_ParseTuple(args, "i", &intval))
return NULL;
- IntLike_Type.tp_flags |= Py_TPFLAGS_DEFAULT;
- IntLike_Type.tp_as_number = &intlike_as_number;
- intlike_as_number.nb_nonzero = intlike_nb_nonzero;
- if (PyType_Ready(&IntLike_Type) < 0) return NULL;
intObj = PyObject_New(IntLikeObject, &IntLike_Type);
if (!intObj) {
return NULL;
@@ -750,8 +746,23 @@
intObj->value = intval;
return (PyObject *)intObj;
- """)],
- """
+ """),
+ ("check", "METH_VARARGS", """
+ IntLikeObject *intObj;
+ int intval, isint;
+
+ if (!PyArg_ParseTuple(args, "i", &intval))
+ return NULL;
+ intObj = PyObject_New(IntLikeObject, &IntLike_Type);
+ if (!intObj) {
+ return NULL;
+ }
+ intObj->value = intval;
+ isint = PyNumber_Check((PyObject*)intObj);
+ Py_DECREF((PyObject*)intObj);
+ return PyInt_FromLong(isint);
+ """),
+ ], prologue= """
typedef struct
{
PyObject_HEAD
@@ -770,6 +781,13 @@
return v->value;
}
+ static PyObject*
+ intlike_nb_int(PyObject* o)
+ {
+ IntLikeObject *v = (IntLikeObject*)o;
+ return PyInt_FromLong(v->value);
+ }
+
PyTypeObject IntLike_Type = {
PyObject_HEAD_INIT(0)
/*ob_size*/ 0,
@@ -777,11 +795,19 @@
/*tp_basicsize*/ sizeof(IntLikeObject),
};
static PyNumberMethods intlike_as_number;
+ """, more_init="""
+ IntLike_Type.tp_flags |= Py_TPFLAGS_DEFAULT;
+ IntLike_Type.tp_as_number = &intlike_as_number;
+ intlike_as_number.nb_nonzero = intlike_nb_nonzero;
+ intlike_as_number.nb_int = intlike_nb_int;
+ if (PyType_Ready(&IntLike_Type) < 0) return NULL;
""")
assert not bool(module.newInt(0))
assert bool(module.newInt(1))
raises(SystemError, bool, module.newInt(-1))
raises(ValueError, bool, module.newInt(-42))
+ val = module.check(10);
+ assert val == 1
def test_mathfunc(self):
module = self.import_extension('foo', [
diff --git a/pypy/module/pypyjit/interp_jit.py
b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -6,6 +6,7 @@
from rpython.rlib.rarithmetic import r_uint, intmask
from rpython.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
from rpython.rlib import jit, jit_hooks
+from rpython.rlib.rjitlog import rjitlog as jl
from rpython.rlib.jit import current_trace_length, unroll_parameters,\
JitHookInterface
from rpython.rtyper.annlowlevel import cast_instance_to_gcref
@@ -41,6 +42,19 @@
from rpython.rlib import rvmprof
return rvmprof.get_unique_id(bytecode)
[email protected](jl.MP_FILENAME, jl.MP_LINENO,
+ jl.MP_SCOPE, jl.MP_INDEX, jl.MP_OPCODE)
+def get_location(next_instr, is_being_profiled, bytecode):
+ from pypy.tool.stdlib_opcode import opcode_method_names
+ bcindex = ord(bytecode.co_code[next_instr])
+ opname = ""
+ if 0 <= bcindex < len(opcode_method_names):
+ opname = opcode_method_names[bcindex]
+ name = bytecode.co_name
+ if not name:
+ name = ""
+ return (bytecode.co_filename, bytecode.co_firstlineno,
+ name, intmask(next_instr), opname)
def should_unroll_one_iteration(next_instr, is_being_profiled, bytecode):
return (bytecode.co_flags & CO_GENERATOR) != 0
@@ -51,6 +65,7 @@
virtualizables = ['frame']
pypyjitdriver = PyPyJitDriver(get_printable_location = get_printable_location,
+ get_location = get_location,
get_unique_id = get_unique_id,
should_unroll_one_iteration =
should_unroll_one_iteration,
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -57,7 +57,10 @@
cmdline.append(str(self.filepath))
#
env = os.environ.copy()
+ # TODO old logging system
env['PYPYLOG'] = self.log_string + ':' + str(logfile)
+ jitlogfile = str(logfile) + '.jlog'
+ env['JITLOG'] = str(jitlogfile)
pipe = subprocess.Popen(cmdline,
env=env,
stdout=subprocess.PIPE,
@@ -84,6 +87,7 @@
log = Log(rawtraces)
log.result = eval(stdout)
log.logfile = str(logfile)
+ log.jitlogfile = jitlogfile
#
summaries = logparser.extract_category(rawlog, 'jit-summary')
if len(summaries) > 0:
diff --git a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py
b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py
--- a/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_jitlogparser.py
@@ -8,7 +8,6 @@
mangle_descr)
from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
-
class TestLogParser(BaseTestPyPyC):
log_string = 'jit-log-opt,jit-backend'
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -409,7 +409,7 @@
if not e.match(space, space.w_StopIteration):
raise
return space.w_False
- if space.eq_w(w_next, w_item):
+ if space.eq_w(w_item, w_next):
return space.w_True
def hash(space, w_obj):
@@ -425,17 +425,25 @@
"'%T' objects are unhashable", w_obj)
w_result = space.get_and_call_function(w_hash, w_obj)
w_resulttype = space.type(w_result)
+
+ # issue 2346 : returns now -2 for hashing -1 like cpython
if space.is_w(w_resulttype, space.w_int):
+ if space.int_w(w_result) == -1:
+ return space.wrap(-2)
return w_result
- elif space.is_w(w_resulttype, space.w_long):
- return space.hash(w_result)
elif space.isinstance_w(w_result, space.w_int):
# be careful about subclasses of 'int'...
- return space.wrap(space.int_w(w_result))
+ int_result = space.int_w(w_result)
+ if int_result == -1:
+ int_result == -2
+ return space.wrap(int_result)
elif space.isinstance_w(w_result, space.w_long):
# be careful about subclasses of 'long'...
bigint = space.bigint_w(w_result)
- return space.wrap(bigint.hash())
+ h = bigint.hash()
+ if h == -1:
+ h = -2
+ return space.wrap(h)
else:
raise oefmt(space.w_TypeError,
"__hash__() should return an int or long")
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -795,7 +795,7 @@
tp = space.type(w_item)
while i < stop and i < w_list.length():
find_jmp.jit_merge_point(tp=tp)
- if space.eq_w(w_list.getitem(i), w_item):
+ if space.eq_w(w_item, w_list.getitem(i)):
return i
i += 1
raise ValueError
diff --git a/pypy/objspace/std/specialisedtupleobject.py
b/pypy/objspace/std/specialisedtupleobject.py
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ b/pypy/objspace/std/specialisedtupleobject.py
@@ -62,6 +62,11 @@
value = getattr(self, 'value%s' % i)
if typetuple[i] == object:
y = space.int_w(space.hash(value))
+ elif typetuple[i] == int:
+ # mimic cpythons behavior of a hash value of -2 for -1
+ y = value
+ if y == -1:
+ y = -2
elif typetuple[i] == float:
# get the correct hash for float which is an
# integer & other less frequent cases
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py
b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -948,6 +948,41 @@
helper(lambda x: x.viewkeys())
helper(lambda x: x.viewitems())
+ def test_contains(self):
+ logger = []
+
+ class Foo(object):
+
+ def __init__(self, value, name=None):
+ self.value = value
+ self.name = name or value
+
+ def __repr__(self):
+ return '<Foo %s>' % self.name
+
+ def __eq__(self, other):
+ logger.append((self, other))
+ return self.value == other.value
+
+ def __hash__(self):
+ return 42 # __eq__ will be used given all objects' hashes
clash
+
+ foo1, foo2, foo3 = Foo(1), Foo(2), Foo(3)
+ foo42 = Foo(42)
+ foo_dict = {foo1: 1, foo2: 1, foo3: 1}
+ del logger[:]
+ foo42 in foo_dict
+ logger_copy = set(logger[:]) # prevent re-evaluation during pytest
error print
+ assert logger_copy == {(foo3, foo42), (foo2, foo42), (foo1, foo42)}
+
+ del logger[:]
+ foo2_bis = Foo(2, '2 bis')
+ foo2_bis in foo_dict
+ logger_copy = set(logger[:]) # prevent re-evaluation during pytest
error print
+ assert (foo2, foo2_bis) in logger_copy
+ assert logger_copy.issubset({(foo1, foo2_bis), (foo2, foo2_bis),
(foo3, foo2_bis)})
+
+
class AppTestStrategies(object):
def setup_class(cls):
if cls.runappdirect:
diff --git a/pypy/objspace/std/test/test_iterobject.py
b/pypy/objspace/std/test/test_iterobject.py
--- a/pypy/objspace/std/test/test_iterobject.py
+++ b/pypy/objspace/std/test/test_iterobject.py
@@ -97,3 +97,32 @@
def test_no_len_on_xrange(self):
iterable = xrange(10)
raises(TypeError, len, iter(iterable))
+
+ def test_contains(self):
+ logger = []
+
+ class Foo(object):
+
+ def __init__(self, value, name=None):
+ self.value = value
+ self.name = name or value
+
+ def __repr__(self):
+ return '<Foo %s>' % self.name
+
+ def __eq__(self, other):
+ logger.append((self, other))
+ return self.value == other.value
+
+ foo1, foo2, foo3 = Foo(1), Foo(2), Foo(3)
+ foo42 = Foo(42)
+ foo_list = [foo1, foo2, foo3]
+ foo42 in (x for x in foo_list)
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo42, foo1), (foo42, foo2), (foo42, foo3)]
+
+ del logger[:]
+ foo2_bis = Foo(2, '2 bis')
+ foo2_bis in (x for x in foo_list)
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo2_bis, foo1), (foo2_bis, foo2)]
diff --git a/pypy/objspace/std/test/test_listobject.py
b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -503,6 +503,34 @@
assert not l.__contains__(-20)
assert not l.__contains__(-21)
+ logger = []
+
+ class Foo(object):
+
+ def __init__(self, value, name=None):
+ self.value = value
+ self.name = name or value
+
+ def __repr__(self):
+ return '<Foo %s>' % self.name
+
+ def __eq__(self, other):
+ logger.append((self, other))
+ return self.value == other.value
+
+ foo1, foo2, foo3 = Foo(1), Foo(2), Foo(3)
+ foo42 = Foo(42)
+ foo_list = [foo1, foo2, foo3]
+ foo42 in foo_list
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo42, foo1), (foo42, foo2), (foo42, foo3)]
+
+ del logger[:]
+ foo2_bis = Foo(2, '2 bis')
+ foo2_bis in foo_list
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo2_bis, foo1), (foo2_bis, foo2)]
+
def test_call_list(self):
assert list('') == []
assert list('abc') == ['a', 'b', 'c']
diff --git a/pypy/objspace/std/test/test_setobject.py
b/pypy/objspace/std/test/test_setobject.py
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -532,6 +532,39 @@
assert (c in s) == (c in word)
raises(TypeError, s.__contains__, [])
+ logger = []
+
+ class Foo(object):
+
+ def __init__(self, value, name=None):
+ self.value = value
+ self.name = name or value
+
+ def __repr__(self):
+ return '<Foo %s>' % self.name
+
+ def __eq__(self, other):
+ logger.append((self, other))
+ return self.value == other.value
+
+ def __hash__(self):
+ return 42 # __eq__ will be used given all objects' hashes
clash
+
+ foo1, foo2, foo3 = Foo(1), Foo(2), Foo(3)
+ foo42 = Foo(42)
+ foo_set = {foo1, foo2, foo3}
+ del logger[:]
+ foo42 in foo_set
+ logger_copy = set(logger[:]) # prevent re-evaluation during pytest
error print
+ assert logger_copy == {(foo3, foo42), (foo2, foo42), (foo1, foo42)}
+
+ del logger[:]
+ foo2_bis = Foo(2, '2 bis')
+ foo2_bis in foo_set
+ logger_copy = set(logger[:]) # prevent re-evaluation during pytest
error print
+ assert (foo2, foo2_bis) in logger_copy
+ assert logger_copy.issubset({(foo1, foo2_bis), (foo2, foo2_bis),
(foo3, foo2_bis)})
+
def test_remove(self):
s = set('abc')
s.remove('a')
diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py
b/pypy/objspace/std/test/test_specialisedtupleobject.py
--- a/pypy/objspace/std/test/test_specialisedtupleobject.py
+++ b/pypy/objspace/std/test/test_specialisedtupleobject.py
@@ -177,6 +177,10 @@
assert hash(a) == hash((1L, 2L)) == hash((1.0, 2.0)) == hash((1.0, 2L))
+ x = (-1, -1)
+ y = tuple([-1, -1])
+ assert hash(x) == hash(y)
+
def test_getitem(self):
t = (5, 3)
assert (t)[0] == 5
diff --git a/pypy/objspace/std/test/test_tupleobject.py
b/pypy/objspace/std/test/test_tupleobject.py
--- a/pypy/objspace/std/test/test_tupleobject.py
+++ b/pypy/objspace/std/test/test_tupleobject.py
@@ -269,6 +269,34 @@
assert not 11 in t
assert not t in t
+ logger = []
+
+ class Foo(object):
+
+ def __init__(self, value, name=None):
+ self.value = value
+ self.name = name or value
+
+ def __repr__(self):
+ return '<Foo %s>' % self.name
+
+ def __eq__(self, other):
+ logger.append((self, other))
+ return self.value == other.value
+
+ foo1, foo2, foo3 = Foo(1), Foo(2), Foo(3)
+ foo42 = Foo(42)
+ foo_tuple = (foo1, foo2, foo3)
+ foo42 in foo_tuple
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo42, foo1), (foo42, foo2), (foo42, foo3)]
+
+ del logger[:]
+ foo2_bis = Foo(2, '2 bis')
+ foo2_bis in foo_tuple
+ logger_copy = logger[:] # prevent re-evaluation during pytest error
print
+ assert logger_copy == [(foo2_bis, foo1), (foo2_bis, foo2)]
+
def test_add(self):
t0 = ()
t1 = (5, 3, 99)
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -153,7 +153,7 @@
@jit.unroll_safe
def _descr_contains_unroll_safe(self, space, w_obj):
for w_item in self.tolist():
- if space.eq_w(w_item, w_obj):
+ if space.eq_w(w_obj, w_item):
return space.w_True
return space.w_False
@@ -161,7 +161,7 @@
tp = space.type(w_obj)
for w_item in self.tolist():
contains_jmp.jit_merge_point(tp=tp)
- if space.eq_w(w_item, w_obj):
+ if space.eq_w(w_obj, w_item):
return space.w_True
return space.w_False
diff --git a/pypy/objspace/test/test_descriptor.py
b/pypy/objspace/test/test_descriptor.py
--- a/pypy/objspace/test/test_descriptor.py
+++ b/pypy/objspace/test/test_descriptor.py
@@ -141,3 +141,31 @@
return myint(15)
assert hash(I()) == 15
assert type(hash(I())) is int
+
+ # check hashing of -1 to -2
+ class myint(int):
+ pass
+ class mylong(long):
+ pass
+ class myfloat(float):
+ pass
+ class myHashClass(object):
+ def __hash__(self):
+ return -1
+ class myHashClass2(object):
+ def __hash__(self):
+ return -1L
+ class myHashClass3(object):
+ def __hash__(self):
+ return -10**100
+
+ assert hash(-1) == -2
+ assert hash(-1L) == -2
+ assert hash(-1.0) == -2
+ assert hash(-1 + 0j) == -2
+ assert hash(myint(-1)) == -2
+ assert hash(mylong(-1)) == -2
+ assert hash(myfloat(-1.0)) == -2
+ assert hash(myHashClass()) == -2
+ assert hash(myHashClass2()) == -2
+ assert hash(myHashClass3()) == hash(-10**100)
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -14,7 +14,7 @@
CoreRegisterManager, check_imm_arg, VFPRegisterManager,
operations as regalloc_operations)
from rpython.jit.backend.llsupport import jitframe, rewrite
-from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER,
BaseAssembler
+from rpython.jit.backend.llsupport.assembler import BaseAssembler
from rpython.jit.backend.llsupport.regalloc import get_scale,
valid_addressing_size
from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
from rpython.jit.backend.model import CompiledLoopToken
@@ -29,6 +29,7 @@
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.jit.backend.arm import callbuilder
from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rlib.rjitlog import rjitlog as jl
class AssemblerARM(ResOpAssembler):
@@ -633,9 +634,17 @@
'loop.asm')
ops_offset = self.mc.ops_offset
- if logger is not None:
- logger.log_loop(inputargs, operations, 0, "rewritten",
- name=loopname, ops_offset=ops_offset)
+
+ if logger:
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset=ops_offset)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_loop(inputargs, operations, 0,
+ "rewritten", name=loopname,
+ ops_offset=ops_offset)
+
self.teardown()
debug_start("jit-backend-addr")
@@ -735,9 +744,18 @@
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
+
if logger:
- logger.log_bridge(inputargs, operations, "rewritten", faildescr,
- ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset)
+ # log that the already written bridge is stitched to a descr!
+ logger.log_patch_guard(descr_number, rawstart)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_bridge(inputargs, operations,
"rewritten",
+ faildescr, ops_offset=ops_offset)
+
self.teardown()
return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos)
diff --git a/rpython/jit/backend/llsupport/asmmemmgr.py
b/rpython/jit/backend/llsupport/asmmemmgr.py
--- a/rpython/jit/backend/llsupport/asmmemmgr.py
+++ b/rpython/jit/backend/llsupport/asmmemmgr.py
@@ -223,6 +223,7 @@
self.init_block_builder()
else:
self._become_a_plain_block_builder()
+ self.rawstart = 0
def init_block_builder(self):
self._cursubblock = lltype.nullptr(self.SUBBLOCK)
@@ -245,6 +246,9 @@
self._cursubblock.data[index] = char
self._cursubindex = index + 1
+ def absolute_addr(self):
+ return self.rawstart
+
def overwrite(self, index, char):
assert 0 <= index < self.get_relative_pos()
block = self._cursubblock
@@ -280,6 +284,19 @@
targetindex -= self.SUBBLOCK_SIZE
assert not block
+ def copy_core_dump(self, addr, offset=0, count=-1):
+ HEX = '0123456789ABCDEF'
+ dump = []
+ src = rffi.cast(rffi.CCHARP, addr)
+ end = self.get_relative_pos()
+ if count != -1:
+ end = offset + count
+ for p in range(offset, end):
+ o = ord(src[p])
+ dump.append(HEX[o >> 4])
+ dump.append(HEX[o & 15])
+ return ''.join(dump)
+
def _dump(self, addr, logname, backend=None):
debug_start(logname)
if have_debug_prints():
@@ -293,17 +310,11 @@
else:
debug_print('SYS_EXECUTABLE', '??')
#
- HEX = '0123456789ABCDEF'
- dump = []
- src = rffi.cast(rffi.CCHARP, addr)
- for p in range(self.get_relative_pos()):
- o = ord(src[p])
- dump.append(HEX[o >> 4])
- dump.append(HEX[o & 15])
+ dump = self.copy_core_dump(addr)
debug_print('CODE_DUMP',
'@%x' % addr,
'+0 ', # backwards compatibility
- ''.join(dump))
+ dump)
#
debug_stop(logname)
@@ -315,6 +326,7 @@
allblocks.append(malloced)
rawstart = malloced[0]
rawstart = (rawstart + align - 1) & (-align)
+ self.rawstart = rawstart
self.copy_to_raw_memory(rawstart)
if self.gcroot_markers is not None:
assert gcrootmap is not None
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -12,7 +12,7 @@
from rpython.rlib.objectmodel import specialize, compute_unique_id
from rpython.rtyper.annlowlevel import cast_instance_to_gcref, llhelper
from rpython.rtyper.lltypesystem import rffi, lltype
-
+from rpython.rlib.rjitlog import rjitlog as jl
DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER',
# 'b'ridge, 'l'abel or # 'e'ntry point
@@ -73,7 +73,9 @@
self.memcpy_addr = 0
self.memset_addr = 0
self.rtyper = cpu.rtyper
+ # do not rely on this attribute if you test for jitlog
self._debug = False
+ self.loop_run_counters = []
def stitch_bridge(self, faildescr, target):
raise NotImplementedError
@@ -129,11 +131,13 @@
self._build_stack_check_slowpath()
self._build_release_gil(gc_ll_descr.gcrootmap)
+ # do not rely on the attribute _debug for jitlog
if not self._debug:
# if self._debug is already set it means that someone called
# set_debug by hand before initializing the assembler. Leave it
# as it is
- self.set_debug(have_debug_prints_for('jit-backend-counts'))
+ should_debug = have_debug_prints_for('jit-backend-counts')
+ self.set_debug(should_debug)
# when finishing, we only have one value at [0], the rest dies
self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1,
flavor='raw',
@@ -337,16 +341,14 @@
# Here we join Path A and Path B again
self._call_assembler_patch_jmp(jmp_location)
+ def get_loop_run_counters(self, index):
+ return self.loop_run_counters[index]
+
@specialize.argtype(1)
def _inject_debugging_code(self, looptoken, operations, tp, number):
- if self._debug:
- s = 0
- for op in operations:
- s += op.getopnum()
-
+ if self._debug or jl.jitlog_enabled():
newoperations = []
- self._append_debugging_code(newoperations, tp, number,
- None)
+ self._append_debugging_code(newoperations, tp, number, None)
for op in operations:
newoperations.append(op)
if op.getopnum() == rop.LABEL:
@@ -362,10 +364,6 @@
ResOperation(rop.INCREMENT_DEBUG_COUNTER, [c_adr]))
def _register_counter(self, tp, number, token):
- # YYY very minor leak -- we need the counters to stay alive
- # forever, just because we want to report them at the end
- # of the process
-
# XXX the numbers here are ALMOST unique, but not quite, use a counter
# or something
struct = lltype.malloc(DEBUG_COUNTER, flavor='raw',
@@ -377,13 +375,18 @@
else:
assert token
struct.number = compute_unique_id(token)
+ # YYY very minor leak -- we need the counters to stay alive
+ # forever, just because we want to report them at the end
+ # of the process
self.loop_run_counters.append(struct)
return struct
def finish_once(self):
if self._debug:
+ # TODO remove the old logging system when jitlog is complete
debug_start('jit-backend-counts')
- for i in range(len(self.loop_run_counters)):
+ length = len(self.loop_run_counters)
+ for i in range(length):
struct = self.loop_run_counters[i]
if struct.type == 'l':
prefix = 'TargetToken(%d)' % struct.number
@@ -400,6 +403,23 @@
debug_print(prefix + ':' + str(struct.i))
debug_stop('jit-backend-counts')
+ self.flush_trace_counters()
+
+ def flush_trace_counters(self):
+ # this is always called, the jitlog knows if it is enabled
+ length = len(self.loop_run_counters)
+ for i in range(length):
+ struct = self.loop_run_counters[i]
+ # only log if it has been executed
+ if struct.i > 0:
+ jl._log_jit_counter(struct)
+ # reset the counter, flush in a later point in time will
+ # add up the counters!
+ struct.i = 0
+ # here would be the point to free some counters
+ # see YYY comment above! but first we should run this every once in a
while
+ # not just when jitlog_disable is called
+
@staticmethod
@rgc.no_collect
def _reacquire_gil_asmgcc(css, old_rpy_fastgil):
diff --git a/rpython/jit/backend/llsupport/llmodel.py
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -110,7 +110,7 @@
unique_id=0, log=True, name='', logger=None):
return self.assembler.assemble_loop(jd_id, unique_id, logger, name,
inputargs, operations,
- looptoken, log=log)
+ looptoken, log)
def stitch_bridge(self, faildescr, target):
self.assembler.stitch_bridge(faildescr, target)
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py
b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -12,6 +12,7 @@
from rpython.config.config import ConfigError
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.rjitlog import rjitlog as jl
class TranslationTest(CCompiledMixin):
@@ -48,9 +49,16 @@
lltype.Float, macro=True, releasegil=True,
compilation_info=eci)
+ @jl.returns(jl.MP_FILENAME,
+ jl.MP_LINENO,
+ jl.MP_INDEX)
+ def get_location():
+ return ("/home.py",0,0)
+
jitdriver = JitDriver(greens = [],
reds = ['total', 'frame', 'j'],
- virtualizables = ['frame'])
+ virtualizables = ['frame'],
+ get_location = get_location)
def f(i, j):
for param, _ in unroll_parameters:
defl = PARAMETERS[param]
@@ -233,6 +241,23 @@
assert res == 2
# one for loop and one for the prologue, no unrolling
+ def test_flush_trace_counts(self):
+ driver = JitDriver(greens = [], reds = ['i'])
+
+ def f():
+ i = 0
+ while i < 100000:
+ driver.jit_merge_point(i=i)
+ i += 1
+
+ def main():
+ jit_hooks.stats_set_debug(None, True)
+ f()
+ jl.stats_flush_trace_counts(None)
+ return 0
+
+ res = self.meta_interp(main, [])
+ assert res == 0
class TranslationRemoveTypePtrTest(CCompiledMixin):
CPUClass = getcpuclass()
diff --git a/rpython/jit/backend/ppc/ppc_assembler.py
b/rpython/jit/backend/ppc/ppc_assembler.py
--- a/rpython/jit/backend/ppc/ppc_assembler.py
+++ b/rpython/jit/backend/ppc/ppc_assembler.py
@@ -37,6 +37,7 @@
from rpython.rlib.jit import AsmInfo
from rpython.rlib.objectmodel import compute_unique_id
from rpython.rlib.rarithmetic import r_uint
+from rpython.rlib.rjitlog import rjitlog as jl
memcpy_fn = rffi.llexternal('memcpy', [llmemory.Address, llmemory.Address,
rffi.SIZE_T], lltype.Void,
@@ -795,9 +796,16 @@
looptoken._ppc_fullsize = full_size
looptoken._ppc_ops_offset = ops_offset
looptoken._ll_function_addr = rawstart
+
if logger:
- logger.log_loop(inputargs, operations, 0, "rewritten",
- name=loopname, ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset=ops_offset)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_loop(inputargs, operations, 0,
+ "rewritten", name=loopname,
+ ops_offset=ops_offset)
self.fixup_target_tokens(rawstart)
self.teardown()
@@ -868,9 +876,18 @@
ops_offset = self.mc.ops_offset
frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+
if logger:
- logger.log_bridge(inputargs, operations, "rewritten",
- ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset)
+ # log that the already written bridge is stitched to a descr!
+ logger.log_patch_guard(descr_number, rawstart)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_bridge(inputargs, operations,
"rewritten",
+ faildescr, ops_offset=ops_offset)
+
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
self.teardown()
diff --git a/rpython/jit/backend/test/jitlog_test.py
b/rpython/jit/backend/test/jitlog_test.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/test/jitlog_test.py
@@ -0,0 +1,80 @@
+import re
+import os
+from rpython.rlib import debug
+from rpython.jit.tool.oparser import pure_parse
+from rpython.jit.metainterp import logger
+from rpython.jit.metainterp.typesystem import llhelper
+from rpython.rlib.rjitlog import rjitlog as jl
+from StringIO import StringIO
+from rpython.jit.metainterp.optimizeopt.util import equaloplists
+from rpython.jit.metainterp.history import AbstractDescr, JitCellToken,
BasicFailDescr, BasicFinalDescr
+from rpython.jit.backend.model import AbstractCPU
+from rpython.rlib.jit import JitDriver
+from rpython.rlib.objectmodel import always_inline
+from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.rlib.rjitlog import rjitlog
+import tempfile
+
+class LoggerTest(LLJitMixin):
+
+ def test_explicit_enable(self, tmpdir):
+ file = tmpdir.join('jitlog')
+ fileno = os.open(file.strpath, os.O_WRONLY | os.O_CREAT)
+ enable_jitlog = lambda: rjitlog.enable_jitlog(fileno)
+ f = self.run_sample_loop(enable_jitlog)
+ self.meta_interp(f, [10, 0])
+
+ assert os.path.exists(file.strpath)
+ with file.open('rb') as f:
+ # check the file header
+ assert f.read(3) == jl.MARK_JITLOG_HEADER +
jl.JITLOG_VERSION_16BIT_LE
+ assert len(f.read()) > 0
+
+ def test_env(self, monkeypatch, tmpdir):
+ file = tmpdir.join('jitlog')
+ monkeypatch.setenv("JITLOG", file.strpath)
+ f = self.run_sample_loop(None)
+ self.meta_interp(f, [10,0])
+ assert os.path.exists(file.strpath)
+ with file.open('rb') as fd:
+ # check the file header
+ assert fd.read(3) == jl.MARK_JITLOG_HEADER +
jl.JITLOG_VERSION_16BIT_LE
+ assert len(fd.read()) > 0
+
+ def test_version(self, monkeypatch, tmpdir):
+ file = tmpdir.join('jitlog')
+ monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe')
+ monkeypatch.setenv("JITLOG", file.strpath)
+ f = self.run_sample_loop(None)
+ self.meta_interp(f, [10,0])
+ assert os.path.exists(file.strpath)
+ with file.open('rb') as fd:
+ # check the file header
+ assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe'
+ assert len(fd.read()) > 0
+
+ def test_version(self, monkeypatch, tmpdir):
+ file = tmpdir.join('jitlog')
+ monkeypatch.setattr(jl, 'JITLOG_VERSION_16BIT_LE', '\xff\xfe')
+ monkeypatch.setenv("JITLOG", file.strpath)
+ f = self.run_sample_loop(None)
+ self.meta_interp(f, [10,0])
+ assert os.path.exists(file.strpath)
+ with file.open('rb') as fd:
+ # check the file header
+ assert fd.read(3) == jl.MARK_JITLOG_HEADER + '\xff\xfe'
+ assert len(fd.read()) > 0
+
+ def run_sample_loop(self, func, myjitdriver = None):
+ if not myjitdriver:
+ myjitdriver = JitDriver(greens = [], reds = 'auto')
+ def f(y, x):
+ res = 0
+ if func:
+ func()
+ while y > 0:
+ myjitdriver.jit_merge_point()
+ res += x
+ y -= 1
+ return res
+ return f
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -3,13 +3,13 @@
import py
from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite
-from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler,
- DEBUG_COUNTER)
+from rpython.jit.backend.llsupport.assembler import (GuardToken,
BaseAssembler, debug_bridge)
from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
from rpython.jit.metainterp.history import (Const, VOID, ConstInt)
from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
from rpython.jit.metainterp.compile import ResumeGuardDescr
+from rpython.rlib.rjitlog import rjitlog as jl
from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rtyper.annlowlevel import cast_instance_to_gcref
@@ -490,8 +490,9 @@
clt.frame_info.clear() # for now
if log:
+ number = looptoken.number
operations = self._inject_debugging_code(looptoken, operations,
- 'e', looptoken.number)
+ 'e', number)
regalloc = RegAlloc(self, self.cpu.translate_support_code)
#
@@ -538,9 +539,16 @@
looptoken._x86_fullsize = full_size
looptoken._x86_ops_offset = ops_offset
looptoken._ll_function_addr = rawstart + functionpos
+
if logger:
- logger.log_loop(inputargs, operations, 0, "rewritten",
- name=loopname, ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset=ops_offset)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_loop(inputargs, operations, 0,
+ "rewritten", name=loopname,
+ ops_offset=ops_offset)
self.fixup_target_tokens(rawstart)
self.teardown()
@@ -605,9 +613,18 @@
ops_offset = self.mc.ops_offset
frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+
if logger:
- logger.log_bridge(inputargs, operations, "rewritten", faildescr,
- ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset)
+ # log that the already written bridge is stitched to a descr!
+ logger.log_patch_guard(descr_number, rawstart)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_bridge(inputargs, operations,
"rewritten",
+ faildescr, ops_offset=ops_offset)
+
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
self.teardown()
diff --git a/rpython/jit/backend/x86/runner.py
b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -119,9 +119,10 @@
looptoken.compiled_loop_token.invalidate_positions = []
def get_all_loop_runs(self):
+ asm = self.assembler
l = lltype.malloc(LOOP_RUN_CONTAINER,
- len(self.assembler.loop_run_counters))
- for i, ll_s in enumerate(self.assembler.loop_run_counters):
+ len(asm.loop_run_counters))
+ for i, ll_s in enumerate(asm.loop_run_counters):
l[i].type = ll_s.type
l[i].number = ll_s.number
l[i].counter = ll_s.i
diff --git a/rpython/jit/backend/x86/test/test_jitlog.py
b/rpython/jit/backend/x86/test/test_jitlog.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/x86/test/test_jitlog.py
@@ -0,0 +1,8 @@
+
+from rpython.jit.backend.x86.test.test_basic import Jit386Mixin
+from rpython.jit.backend.test.jitlog_test import LoggerTest
+
+class TestJitlog(Jit386Mixin, LoggerTest):
+ # for the individual tests see
+ # ====> ../../../test/jitlog_test.py
+ pass
diff --git a/rpython/jit/backend/x86/test/test_runner.py
b/rpython/jit/backend/x86/test/test_runner.py
--- a/rpython/jit/backend/x86/test/test_runner.py
+++ b/rpython/jit/backend/x86/test/test_runner.py
@@ -590,11 +590,11 @@
self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
self.cpu.execute_token(looptoken, 0)
# check debugging info
- struct = self.cpu.assembler.loop_run_counters[0]
+ struct = self.cpu.assembler.get_loop_run_counters(0)
assert struct.i == 1
- struct = self.cpu.assembler.loop_run_counters[1]
+ struct = self.cpu.assembler.get_loop_run_counters(1)
assert struct.i == 1
- struct = self.cpu.assembler.loop_run_counters[2]
+ struct = self.cpu.assembler.get_loop_run_counters(2)
assert struct.i == 9
self.cpu.finish_once()
finally:
diff --git a/rpython/jit/backend/zarch/assembler.py
b/rpython/jit/backend/zarch/assembler.py
--- a/rpython/jit/backend/zarch/assembler.py
+++ b/rpython/jit/backend/zarch/assembler.py
@@ -32,6 +32,7 @@
from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
from rpython.rlib.jit import AsmInfo
+from rpython.rlib.rjitlog import rjitlog as jl
class JitFrameTooDeep(Exception):
pass
@@ -669,9 +670,16 @@
looptoken._zarch_rawstart = rawstart
looptoken._zarch_fullsize = full_size
looptoken._zarch_ops_offset = ops_offset
+
if logger:
- logger.log_loop(inputargs, operations, 0, "rewritten",
- name=loopname, ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset=ops_offset)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_loop(inputargs, operations, 0,
+ "rewritten", name=loopname,
+ ops_offset=ops_offset)
self.fixup_target_tokens(rawstart)
self.teardown()
@@ -736,9 +744,18 @@
ops_offset = self.mc.ops_offset
frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
+
if logger:
- logger.log_bridge(inputargs, operations, "rewritten",
- ops_offset=ops_offset)
+ log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, ops_offset)
+ # log that the already written bridge is stitched to a descr!
+ logger.log_patch_guard(descr_number, rawstart)
+
+ # legacy
+ if logger.logger_ops:
+ logger.logger_ops.log_bridge(inputargs, operations,
"rewritten",
+ faildescr, ops_offset=ops_offset)
+
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
self.teardown()
diff --git a/rpython/jit/backend/zarch/test/test_jitlog.py
b/rpython/jit/backend/zarch/test/test_jitlog.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/zarch/test/test_jitlog.py
@@ -0,0 +1,8 @@
+
+from rpython.jit.backend.zarch.test.support import JitZARCHMixin
+from rpython.jit.backend.test.jitlog_test import LoggerTest
+
+class TestJitlog(JitZARCHMixin, LoggerTest):
+ # for the individual tests see
+ # ====> ../../../test/jitlog_test.py
+ pass
diff --git a/rpython/jit/backend/zarch/test/test_pool.py
b/rpython/jit/backend/zarch/test/test_pool.py
--- a/rpython/jit/backend/zarch/test/test_pool.py
+++ b/rpython/jit/backend/zarch/test/test_pool.py
@@ -40,7 +40,7 @@
def test_constant_in_call_malloc(self):
c = ConstPtr(rffi.cast(llmemory.GCREF, 0xdeadbeef1234))
- self.ensure_can_hold(rop.CALL_MALLOC_GC, [c], descr=self.calldescr)
+ self.ensure_can_hold(rop.COND_CALL, [c], descr=self.calldescr)
assert self.const_in_pool(c)
assert self.const_in_pool(ConstPtr(rffi.cast(llmemory.GCREF,
0xdeadbeef1234)))
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
@@ -6,6 +6,7 @@
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.conftest import option
from rpython.jit.metainterp.resoperation import ResOperation, rop,\
@@ -217,6 +218,7 @@
loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd,
data, metainterp.box_names_memo)
except InvalidLoop:
+ metainterp_sd.jitlog.trace_aborted()
trace.cut_at(cut_at)
return None
loop = create_empty_loop(metainterp)
@@ -250,7 +252,10 @@
history = metainterp.history
trace = history.trace
warmstate = jitdriver_sd.warmstate
-
+ #
+ metainterp_sd.jitlog.start_new_trace(metainterp_sd,
+ faildescr=None, entry_bridge=False)
+ #
enable_opts = jitdriver_sd.warmstate.enable_opts
if try_disabling_unroll:
if 'unroll' not in enable_opts:
@@ -275,6 +280,7 @@
preamble_data,
metainterp.box_names_memo)
except InvalidLoop:
+ metainterp_sd.jitlog.trace_aborted()
history.cut(cut_at)
return None
@@ -291,6 +297,7 @@
loop_data,
metainterp.box_names_memo)
except InvalidLoop:
+ metainterp_sd.jitlog.trace_aborted()
history.cut(cut_at)
return None
@@ -340,7 +347,10 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
history = metainterp.history
-
+ #
+ metainterp_sd.jitlog.start_new_trace(metainterp_sd,
+ faildescr=resumekey, entry_bridge=False)
+ #
loop_jitcell_token = metainterp.get_procedure_token(greenkey)
assert loop_jitcell_token
@@ -368,6 +378,7 @@
loop_data,
metainterp.box_names_memo)
except InvalidLoop:
+ metainterp_sd.jitlog.trace_aborted()
history.cut(cut)
return None
@@ -476,22 +487,28 @@
def do_compile_loop(jd_id, unique_id, metainterp_sd, inputargs, operations,
looptoken, log=True, name='', memo=None):
+ # legacy
metainterp_sd.logger_ops.log_loop(inputargs, operations, -2,
'compiling', None, name, memo)
+ _log = metainterp_sd.jitlog.log_trace(jl.MARK_TRACE_OPT, metainterp_sd,
None)
+ _log.write(inputargs, operations)
return metainterp_sd.cpu.compile_loop(inputargs,
operations, looptoken,
jd_id=jd_id, unique_id=unique_id,
log=log, name=name,
- logger=metainterp_sd.logger_ops)
+ logger=metainterp_sd.jitlog)
def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations,
original_loop_token, log=True, memo=None):
+ # legacy
metainterp_sd.logger_ops.log_bridge(inputargs, operations, "compiling",
memo=memo)
+ _log = metainterp_sd.jitlog.log_trace(jl.MARK_TRACE_OPT, metainterp_sd,
None)
+ _log.write(inputargs, operations)
assert isinstance(faildescr, AbstractFailDescr)
return metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations,
original_loop_token, log=log,
- logger=metainterp_sd.logger_ops)
+ logger=metainterp_sd.jitlog)
def forget_optimization_info(lst, reset_values=False):
for item in lst:
@@ -511,9 +528,7 @@
patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable)
original_jitcell_token = loop.original_jitcell_token
- globaldata = metainterp_sd.globaldata
- original_jitcell_token.number = n = globaldata.loopnumbering
- globaldata.loopnumbering += 1
+ original_jitcell_token.number = n = metainterp_sd.jitlog.trace_id
if not we_are_translated():
show_procedures(metainterp_sd, loop)
@@ -531,6 +546,7 @@
operations = get_deep_immutable_oplist(loop.operations)
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
+ log = have_debug_prints() or jl.jitlog_enabled()
try:
loopname = jitdriver_sd.warmstate.get_location_str(greenkey)
unique_id = jitdriver_sd.warmstate.get_unique_id(greenkey)
@@ -538,7 +554,7 @@
loop.inputargs,
operations, original_jitcell_token,
name=loopname,
- log=have_debug_prints(),
+ log=log,
memo=memo)
finally:
debug_stop("jit-backend")
@@ -582,10 +598,11 @@
operations = get_deep_immutable_oplist(operations)
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
+ log = have_debug_prints() or jl.jitlog_enabled()
try:
asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs,
operations,
- original_loop_token, have_debug_prints(),
+ original_loop_token, log,
memo)
finally:
debug_stop("jit-backend")
@@ -1020,7 +1037,7 @@
def compile_trace(metainterp, resumekey, runtime_boxes):
"""Try to compile a new bridge leading from the beginning of the history
- to some existging place.
+ to some existing place.
"""
from rpython.jit.metainterp.optimizeopt import optimize_trace
@@ -1033,6 +1050,10 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
+ #
+ metainterp_sd.jitlog.start_new_trace(metainterp_sd,
+ faildescr=resumekey, entry_bridge=False)
+ #
if isinstance(resumekey, ResumeAtPositionDescr):
inline_short_preamble = False
else:
@@ -1057,6 +1078,7 @@
info, newops = optimize_trace(metainterp_sd, jitdriver_sd,
data, 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
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
@@ -7,6 +7,7 @@
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
@@ -57,6 +58,9 @@
"""
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:
diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py
b/rpython/jit/metainterp/optimizeopt/dependency.py
--- a/rpython/jit/metainterp/optimizeopt/dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/dependency.py
@@ -22,6 +22,8 @@
, (rop.UNICODESETITEM, 0, -1)
]
+UNROLLED_MODIFY_COMPLEX_OBJ = unrolling_iterable(MODIFY_COMPLEX_OBJ)
+
LOAD_COMPLEX_OBJ = [ (rop.GETARRAYITEM_GC_I, 0, 1)
, (rop.GETARRAYITEM_GC_F, 0, 1)
, (rop.GETARRAYITEM_GC_R, 0, 1)
@@ -40,6 +42,8 @@
, (rop.GETFIELD_RAW_R, 0, -1)
]
+UNROLLED_LOAD_COMPLEX_OBJ = unrolling_iterable(LOAD_COMPLEX_OBJ)
+
class Path(object):
def __init__(self,path):
self.path = path
@@ -202,7 +206,7 @@
args = []
op = self.op
if self.modifies_complex_object():
- for opnum, i, j in unrolling_iterable(MODIFY_COMPLEX_OBJ):
+ for opnum, i, j in UNROLLED_MODIFY_COMPLEX_OBJ:
#unrolling_iterable(MODIFY_COMPLEX_OBJ):
if op.getopnum() == opnum:
op_args = op.getarglist()
if j == -1:
@@ -723,7 +727,7 @@
if node.loads_from_complex_object():
# If this complex object load operation loads an index that has
been
# modified, the last modification should be used to put a def-use
edge.
- for opnum, i, j in unrolling_iterable(LOAD_COMPLEX_OBJ):
+ for opnum, i, j in UNROLLED_LOAD_COMPLEX_OBJ:
if opnum == op.getopnum():
cobj = op.getarg(i)
if j != -1:
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -21,6 +21,7 @@
from rpython.jit.metainterp.resoperation import (rop, ResOperation,
InputArgRef, AbstractValue, OpHelpers)
from rpython.jit.metainterp.optimizeopt.util import args_dict
+from rpython.rlib.rjitlog import rjitlog as jl
def test_sort_descrs():
@@ -484,6 +485,7 @@
self.options = Fake()
self.globaldata = Fake()
self.config = get_combined_translation_config(translating=True)
+ self.jitlog = jl.JitLogger()
class logger_noopt:
@classmethod
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -13,6 +13,7 @@
from rpython.jit.metainterp.logger import Logger
from rpython.jit.metainterp.optimizeopt.util import args_dict
from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp
+from rpython.rlib.rjitlog import rjitlog as jl
from rpython.rlib import nonconst, rstack
from rpython.rlib.debug import debug_start, debug_stop, debug_print
from rpython.rlib.debug import have_debug_prints, make_sure_not_resized
@@ -1760,8 +1761,12 @@
self.cpu = cpu
self.stats = self.cpu.stats
self.options = options
+ self.jitlog = jl.JitLogger(self.cpu)
self.logger_noopt = Logger(self)
self.logger_ops = Logger(self, guard_number=True)
+ # legacy loggers
+ self.jitlog.logger_noopt = self.logger_noopt
+ self.jitlog.logger_ops = self.logger_ops
self.profiler = ProfilerClass()
self.profiler.cpu = cpu
@@ -1849,6 +1854,7 @@
def _setup_once(self):
"""Runtime setup needed by the various components of the JIT."""
if not self.globaldata.initialized:
+ self.jitlog.setup_once()
debug_print(self.jit_starting_line)
self.cpu.setup_once()
if not self.profiler.initialized:
@@ -1925,7 +1931,6 @@
self.initialized = False
self.indirectcall_dict = None
self.addr2name = None
- self.loopnumbering = 0
# ____________________________________________________________
diff --git a/rpython/jit/metainterp/test/test_compile.py
b/rpython/jit/metainterp/test/test_compile.py
--- a/rpython/jit/metainterp/test/test_compile.py
+++ b/rpython/jit/metainterp/test/test_compile.py
@@ -4,6 +4,7 @@
from rpython.jit.metainterp.compile import compile_loop
from rpython.jit.metainterp.compile import compile_tmp_callback
from rpython.jit.metainterp import jitexc
+from rpython.rlib.rjitlog import rjitlog as jl
from rpython.jit.metainterp import jitprof, typesystem, compile
from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
from rpython.jit.tool.oparser import parse, convert_loop_to_trace
@@ -51,13 +52,14 @@
return 'location'
class FakeGlobalData(object):
- loopnumbering = 0
+ pass
class FakeMetaInterpStaticData(object):
all_descrs = []
logger_noopt = FakeLogger()
logger_ops = FakeLogger()
config = get_combined_translation_config(translating=True)
+ jitlog = jl.JitLogger()
stats = Stats(None)
profiler = jitprof.EmptyProfiler()
@@ -78,8 +80,8 @@
cpu = FakeCPU()
staticdata = FakeMetaInterpStaticData()
staticdata.cpu = cpu
- staticdata.globaldata = FakeGlobalData()
- staticdata.globaldata.loopnumbering = 1
+ staticdata.jitlog = jl.JitLogger(cpu)
+ staticdata.jitlog.trace_id = 1
#
loop = parse('''
[p1]
@@ -106,8 +108,7 @@
jitcell_token = target_token.targeting_jitcell_token
assert jitcell_token == target_token.original_jitcell_token
assert jitcell_token.target_tokens == [target_token]
- assert jitcell_token.number == 1
- assert staticdata.globaldata.loopnumbering == 2
+ assert jitcell_token.number == 2
#
assert len(cpu.seen) == 1
assert cpu.seen[0][2] == jitcell_token
diff --git a/rpython/jit/metainterp/warmspot.py
b/rpython/jit/metainterp/warmspot.py
--- a/rpython/jit/metainterp/warmspot.py
+++ b/rpython/jit/metainterp/warmspot.py
@@ -6,6 +6,7 @@
cast_base_ptr_to_instance, hlstr, cast_instance_to_gcref)
from rpython.rtyper.llannotation import lltype_to_annotation
from rpython.annotator import model as annmodel
+from rpython.annotator.dictdef import DictDef
from rpython.rtyper.llinterp import LLException
from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache
from rpython.flowspace.model import SpaceOperation, Variable, Constant
@@ -119,6 +120,7 @@
return interp, graph
res = interp.eval_graph(graph, args)
if not kwds.get('translate_support_code', False):
+ warmrunnerdesc.metainterp_sd.jitlog.finish()
warmrunnerdesc.metainterp_sd.profiler.finish()
warmrunnerdesc.metainterp_sd.cpu.finish_once()
print '~~~ return value:', repr(res)
@@ -563,12 +565,12 @@
jd._EnterJitAssembler = EnterJitAssembler
def make_driverhook_graphs(self):
- s_Str = annmodel.SomeString()
#
annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
for jd in self.jitdrivers_sd:
jd._get_printable_location_ptr = self._make_hook_graph(jd,
- annhelper, jd.jitdriver.get_printable_location, s_Str)
+ annhelper, jd.jitdriver.get_printable_location,
+ annmodel.SomeString())
jd._get_unique_id_ptr = self._make_hook_graph(jd,
annhelper, jd.jitdriver.get_unique_id, annmodel.SomeInteger())
jd._confirm_enter_jit_ptr = self._make_hook_graph(jd,
@@ -579,6 +581,34 @@
jd._should_unroll_one_iteration_ptr = self._make_hook_graph(jd,
annhelper, jd.jitdriver.should_unroll_one_iteration,
annmodel.s_Bool)
+ #
+ items = []
+ types = ()
+ pos = ()
+ if jd.jitdriver.get_location:
+ assert hasattr(jd.jitdriver.get_location, '_loc_types'), """
+ You must decorate your get_location function:
+
+ from rpython.rlib.rjitlog import rjitlog as jl
+ @jl.returns(jl.MP_FILENAME, jl.MP_XXX, ...)
+ def get_loc(your, green, keys):
+ name = "x.txt" # extract it from your green keys
+ return (name, ...)
+ """
+ types = jd.jitdriver.get_location._loc_types
+ del jd.jitdriver.get_location._loc_types
+ #
+ for _,type in types:
+ if type == 's':
+ items.append(annmodel.SomeString())
+ elif type == 'i':
+ items.append(annmodel.SomeInteger())
+ else:
+ raise NotImplementedError
+ s_Tuple = annmodel.SomeTuple(items)
+ jd._get_location_ptr = self._make_hook_graph(jd,
+ annhelper, jd.jitdriver.get_location, s_Tuple)
+ jd._get_loc_types = types
annhelper.finish()
def _make_hook_graph(self, jitdriver_sd, annhelper, func,
diff --git a/rpython/jit/metainterp/warmstate.py
b/rpython/jit/metainterp/warmstate.py
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -6,6 +6,7 @@
from rpython.rlib.debug import debug_start, debug_stop, debug_print
from rpython.rlib.debug import have_debug_prints_for
from rpython.rlib.jit import PARAMETERS
+from rpython.rlib.rjitlog import rjitlog as jl
from rpython.rlib.nonconst import NonConstant
from rpython.rlib.objectmodel import specialize, we_are_translated, r_dict
from rpython.rlib.rarithmetic import intmask, r_uint
@@ -703,8 +704,35 @@
drivername = jitdriver.name
else:
drivername = '<unknown jitdriver>'
- get_location_ptr = self.jitdriver_sd._get_printable_location_ptr
- if get_location_ptr is None:
+ # get_location returns
+ get_location_ptr = getattr(self.jitdriver_sd, '_get_location_ptr',
None)
+ if get_location_ptr is not None:
+ types = self.jitdriver_sd._get_loc_types
+ unwrap_greenkey = self.make_unwrap_greenkey()
+ unrolled_types = unrolling_iterable(enumerate(types))
+ def get_location(greenkey):
+ greenargs = unwrap_greenkey(greenkey)
+ fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr)
+ value_tuple = fn(*greenargs)
+ values = []
+ for i, (sem_type,gen_type) in unrolled_types:
+ if gen_type == "s":
+ value = getattr(value_tuple, 'item' + str(i))
+ values.append(jl.wrap(sem_type,gen_type,hlstr(value)))
+ elif gen_type == "i":
+ value = getattr(value_tuple, 'item' + str(i))
+
values.append(jl.wrap(sem_type,gen_type,intmask(value)))
+ else:
+ raise NotImplementedError
+ return values
+ self.get_location_types = list(types)
+ self.get_location = get_location
+ else:
+ self.get_location_types = None
+ self.get_location = None
+ #
+ printable_loc_ptr = self.jitdriver_sd._get_printable_location_ptr
+ if printable_loc_ptr is None:
missing = '(%s: no get_printable_location)' % drivername
def get_location_str(greenkey):
return missing
@@ -720,7 +748,7 @@
if not have_debug_prints_for("jit-"):
return missing
greenargs = unwrap_greenkey(greenkey)
- fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr)
+ fn = support.maybe_on_top_of_llinterp(rtyper,
printable_loc_ptr)
llres = fn(*greenargs)
if not we_are_translated() and isinstance(llres, str):
return llres
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -605,8 +605,27 @@
get_printable_location=None, confirm_enter_jit=None,
can_never_inline=None, should_unroll_one_iteration=None,
name='jitdriver', check_untranslated=True, vectorize=False,
- get_unique_id=None, is_recursive=False):
- "NOT_RPYTHON"
+ get_unique_id=None, is_recursive=False, get_location=None):
+ """ NOT_RPYTHON
+ get_location:
+ The return value is designed to provide enough information to
express the
+ state of an interpreter when invoking jit_merge_point.
+ For a bytecode interperter such as PyPy this includes, filename,
line number,
+ function name, and more information. However, it should also be
able to express
+ the same state for an interpreter that evaluates an AST.
+ return paremter:
+ 0 -> filename. An absolute path specifying the file the
interpreter invoked.
+ If the input source is no file it should start
with the
+ prefix: "string://<name>"
+ 1 -> line number. The line number in filename. This should at
least point to
+ the enclosing name. It can however point to
the specific
+ source line of the instruction executed by
the interpreter.
+ 2 -> enclosing name. E.g. the function name.
+ 3 -> index. 64 bit number indicating the execution progress.
It can either be
+ an offset to byte code, or an index to the node in an AST
+ 4 -> operation name. a name further describing the current
program counter.
+ this can be either a byte code name or the name of an AST
node
+ """
if greens is not None:
self.greens = greens
self.name = name
@@ -640,6 +659,7 @@
assert get_jitcell_at is None, "get_jitcell_at no longer used"
assert set_jitcell_at is None, "set_jitcell_at no longer used"
self.get_printable_location = get_printable_location
+ self.get_location = get_location
if get_unique_id is None:
get_unique_id = lambda *args: 0
self.get_unique_id = get_unique_id
@@ -880,6 +900,7 @@
driver = self.instance.im_self
h = self.annotate_hook
h(driver.get_printable_location, driver.greens, **kwds_s)
+ h(driver.get_location, driver.greens, **kwds_s)
def annotate_hook(self, func, variables, args_s=[], **kwds_s):
if func is None:
diff --git a/rpython/rlib/rjitlog/__init__.py b/rpython/rlib/rjitlog/__init__.py
new file mode 100644
diff --git a/rpython/rlib/rjitlog/rjitlog.py b/rpython/rlib/rjitlog/rjitlog.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rjitlog/rjitlog.py
@@ -0,0 +1,614 @@
+import py
+import sys
+import weakref
+import struct
+import os
+from rpython.rlib import jit
+from rpython.tool.udir import udir
+from rpython.tool.version import rpythonroot
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.jit.metainterp import resoperation as resoperations
+from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.history import ConstInt, ConstFloat
+from rpython.rlib.objectmodel import we_are_translated
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rlib.objectmodel import compute_unique_id, always_inline
+from rpython.rlib.objectmodel import we_are_translated, specialize
+from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.jit_hooks import register_helper
+from rpython.annotator import model as annmodel
+
+
+ROOT = py.path.local(rpythonroot).join('rpython', 'rlib', 'rjitlog')
+SRC = ROOT.join('src')
+
+_libs = []
+if sys.platform.startswith('linux'):
+ _libs = ['dl']
+eci_kwds = dict(
+ include_dirs = [SRC],
+ includes = ['rjitlog.h'],
+ libraries = _libs,
+ separate_module_files = [SRC.join('rjitlog.c')],
+ post_include_bits=['#define RPYTHON_JITLOG\n'],
+ )
+eci = ExternalCompilationInfo(**eci_kwds)
+
+# jit log functions
+jitlog_init = rffi.llexternal("jitlog_init", [rffi.INT],
+ rffi.CCHARP, compilation_info=eci)
+jitlog_try_init_using_env = rffi.llexternal("jitlog_try_init_using_env",
+ [], lltype.Void, compilation_info=eci)
+jitlog_write_marked = rffi.llexternal("jitlog_write_marked",
+ [rffi.CCHARP, rffi.INT],
+ lltype.Void, compilation_info=eci,
+ releasegil=False)
+jitlog_enabled = rffi.llexternal("jitlog_enabled", [], rffi.INT,
+ compilation_info=eci,
+ releasegil=False)
+jitlog_teardown = rffi.llexternal("jitlog_teardown", [], lltype.Void,
+ compilation_info=eci)
+
+class JitlogError(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+ def __str__(self):
+ return self.msg
+
+@register_helper(None)
+def stats_flush_trace_counts(warmrunnerdesc):
+ if not we_are_translated():
+ return # first param is None untranslated
+ warmrunnerdesc.metainterp_sd.cpu.assembler.flush_trace_counters()
+
[email protected]_look_inside
+def enable_jitlog(fileno):
+ # initialize the jit log
+ p_error = jitlog_init(fileno)
+ if p_error:
+ raise JitlogError(rffi.charp2str(p_error))
+ blob = assemble_header()
+ jitlog_write_marked(MARK_JITLOG_HEADER + blob, len(blob) + 1)
+
+def disable_jitlog():
+ stats_flush_trace_counts(None)
+ jitlog_teardown()
+
+
+def commonprefix(a,b):
+ "Given a list of pathnames, returns the longest common leading component"
+ assert a is not None
+ assert b is not None
+ la = len(a)
+ lb = len(b)
+ c = min(la,lb)
+ if c == 0:
+ return ""
+ for i in range(c):
+ if a[i] != b[i]:
+ return a[:i] # partly matching
+ return a # full match
+
+@always_inline
+def encode_str(string):
+ val = len(string)
+ return ''.join([chr((val >> 0) & 0xff),
+ chr((val >> 8) & 0xff),
+ chr((val >> 16) & 0xff),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit