Author: Ronan Lamy <[email protected]>
Branch: callfamily
Changeset: r80005:44956214dd48
Date: 2015-09-25 18:57 +0100
http://bitbucket.org/pypy/pypy/changeset/44956214dd48/

Log:    hg merge default

diff too long, truncating to 2000 out of 56370 lines

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -15,3 +15,4 @@
 e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0
 e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0
 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0
+f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -168,7 +168,6 @@
   Michael Twomey
   Lucian Branescu Mihaila
   Yichao Yu
-  Anton Gulenko
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
@@ -215,6 +214,7 @@
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
+  Anton Gulenko
   Gabriel
   Lukas Vacek
   Andrew Dalke
@@ -247,6 +247,7 @@
   Toni Mattis
   Lucas Stadler
   Julian Berman
+  Markus Holtermann
   roberto@goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
@@ -352,8 +353,7 @@
 Except when otherwise stated (look for LICENSE files or copyright/license
 information at the beginning of each file) the files in the 'lib-python/2.7'
 directory are all copyrighted by the Python Software Foundation and licensed
-under the Python Software License of which you can find a copy here:
-http://www.python.org/doc/Copyright.html 
+under the terms that you can find here: https://docs.python.org/2/license.html
 
 License for 'pypy/module/unicodedata/'
 ======================================
@@ -430,9 +430,9 @@
 gdbm module, provided in the file lib_pypy/gdbm.py, is redistributed
 under the terms of the GPL license as well.
 
-License for 'pypy/module/_vmprof/src'
+License for 'rpython/rlib/rvmprof/src'
 --------------------------------------
 
 The code is based on gperftools. You may see a copy of the License for it at
 
-    https://code.google.com/p/gperftools/source/browse/COPYING
+    https://github.com/gperftools/gperftools/blob/master/COPYING
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -303,7 +303,7 @@
     RegrTest('test_memoryio.py'),
     RegrTest('test_memoryview.py'),
     RegrTest('test_md5.py'),
-    RegrTest('test_mhlib.py'),
+    RegrTest('test_mhlib.py', usemodules='binascii struct'),
     RegrTest('test_mimetools.py'),
     RegrTest('test_mimetypes.py'),
     RegrTest('test_MimeWriter.py', core=False, usemodules='binascii'),
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -1026,16 +1026,22 @@
 
 def tigetflag(capname):
     _ensure_initialised_setupterm()
+    if isinstance(capname, unicode):
+        capname = capname.encode('ascii')
     return lib.tigetflag(capname)
 
 
 def tigetnum(capname):
     _ensure_initialised_setupterm()
+    if isinstance(capname, unicode):
+        capname = capname.encode('ascii')
     return lib.tigetnum(capname)
 
 
 def tigetstr(capname):
     _ensure_initialised_setupterm()
+    if isinstance(capname, unicode):
+        capname = capname.encode('ascii')
     val = lib.tigetstr(capname)
     if int(ffi.cast("intptr_t", val)) in (0, -1):
         return None
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.2.0
+Version: 1.3.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
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.2.0"
-__version_info__ = (1, 2, 0)
+__version__ = "1.3.0"
+__version_info__ = (1, 3, 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/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h
--- a/lib_pypy/cffi/_cffi_include.h
+++ b/lib_pypy/cffi/_cffi_include.h
@@ -46,7 +46,7 @@
 # endif
 #else
 # include <stdint.h>
-# if (defined (__SVR4) && defined (__sun)) || defined(_AIX)
+# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux)
 #  include <alloca.h>
 # endif
 #endif
@@ -214,6 +214,12 @@
      (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) :    \
      _CFFI__UNKNOWN_PRIM)
 
+#define _cffi_prim_float(size)                                          \
+    ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT :                       \
+     (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE :                     \
+     (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE :       \
+     _CFFI__UNKNOWN_FLOAT_PRIM)
+
 #define _cffi_check_int(got, got_nonpos, expected)      \
     ((got_nonpos) == (expected <= 0) &&                 \
      (got) == (unsigned long long)expected)
diff --git a/lib_pypy/cffi/cffi_opcode.py b/lib_pypy/cffi/cffi_opcode.py
--- a/lib_pypy/cffi/cffi_opcode.py
+++ b/lib_pypy/cffi/cffi_opcode.py
@@ -106,7 +106,9 @@
 PRIM_UINTMAX       = 47
 
 _NUM_PRIM          = 48
-_UNKNOWN_PRIM      = -1
+_UNKNOWN_PRIM          = -1
+_UNKNOWN_FLOAT_PRIM    = -2
+_UNKNOWN_LONG_DOUBLE   = -3
 
 PRIMITIVE_TO_INDEX = {
     'char':               PRIM_CHAR,
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
@@ -15,9 +15,11 @@
 except ImportError:
     lock = None
 
-_r_comment = re.compile(r"/\*.*?\*/|//.*?$", re.DOTALL | re.MULTILINE)
-_r_define  = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)\s+(.*?)$",
-                        re.MULTILINE)
+_r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$",
+                        re.DOTALL | re.MULTILINE)
+_r_define  = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)"
+                        r"\b((?:[^\n\\]|\\.)*?)$",
+                        re.DOTALL | re.MULTILINE)
 _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}")
 _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$")
 _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]")
@@ -39,6 +41,7 @@
     macros = {}
     for match in _r_define.finditer(csource):
         macroname, macrovalue = match.groups()
+        macrovalue = macrovalue.replace('\\\n', '').strip()
         macros[macroname] = macrovalue
     csource = _r_define.sub('', csource)
     # Replace "[...]" with "[__dotdotdotarray__]"
@@ -423,13 +426,10 @@
                 raise api.CDefError(
                     "%s: a function with only '(...)' as argument"
                     " is not correct C" % (funcname or 'in expression'))
-        elif (len(params) == 1 and
-            isinstance(params[0].type, pycparser.c_ast.TypeDecl) and
-            isinstance(params[0].type.type, pycparser.c_ast.IdentifierType)
-                and list(params[0].type.type.names) == ['void']):
-            del params[0]
         args = [self._as_func_arg(self._get_type(argdeclnode.type))
                 for argdeclnode in params]
+        if not ellipsis and args == [model.void_type]:
+            args = []
         result = self._get_type(typenode.type)
         return model.RawFunctionType(tuple(args), result, ellipsis)
 
@@ -648,10 +648,21 @@
         assert typenames[-1] == '__dotdotdot__'
         if len(typenames) == 1:
             return model.unknown_type(decl.name)
-        for t in typenames[:-1]:
-            if t not in ['int', 'short', 'long', 'signed', 'unsigned', 'char']:
-                raise api.FFIError(':%d: bad usage of "..."' % decl.coord.line)
+
+        if (typenames[:-1] == ['float'] or
+            typenames[:-1] == ['double']):
+            # not for 'long double' so far
+            result = model.UnknownFloatType(decl.name)
+        else:
+            for t in typenames[:-1]:
+                if t not in ['int', 'short', 'long', 'signed',
+                             'unsigned', 'char']:
+                    raise api.FFIError(':%d: bad usage of "..."' %
+                                       decl.coord.line)
+            result = model.UnknownIntegerType(decl.name)
+
         if self._uses_new_feature is None:
             self._uses_new_feature = "'typedef %s... %s'" % (
                 ' '.join(typenames[:-1]), decl.name)
-        return model.UnknownIntegerType(decl.name)
+
+        return result
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -158,12 +158,23 @@
         self.c_name_with_marker = name + '&'
 
     def is_integer_type(self):
-        return True    # for now
+        return True
 
     def build_backend_type(self, ffi, finishlist):
         raise NotImplementedError("integer type '%s' can only be used after "
                                   "compilation" % self.name)
 
+class UnknownFloatType(BasePrimitiveType):
+    _attrs_ = ('name', )
+
+    def __init__(self, name):
+        self.name = name
+        self.c_name_with_marker = name + '&'
+
+    def build_backend_type(self, ffi, finishlist):
+        raise NotImplementedError("float type '%s' can only be used after "
+                                  "compilation" % self.name)
+
 
 class BaseFunctionType(BaseType):
     _attrs_ = ('args', 'result', 'ellipsis')
diff --git a/lib_pypy/cffi/parse_c_type.h b/lib_pypy/cffi/parse_c_type.h
--- a/lib_pypy/cffi/parse_c_type.h
+++ b/lib_pypy/cffi/parse_c_type.h
@@ -79,7 +79,9 @@
 #define _CFFI_PRIM_UINTMAX      47
 
 #define _CFFI__NUM_PRIM         48
-#define _CFFI__UNKNOWN_PRIM    (-1)
+#define _CFFI__UNKNOWN_PRIM           (-1)
+#define _CFFI__UNKNOWN_FLOAT_PRIM     (-2)
+#define _CFFI__UNKNOWN_LONG_DOUBLE    (-3)
 
 
 struct _cffi_global_s {
diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py
--- a/lib_pypy/cffi/recompiler.py
+++ b/lib_pypy/cffi/recompiler.py
@@ -4,11 +4,6 @@
 
 VERSION = "0x2601"
 
-try:
-    int_type = (int, long)
-except NameError:    # Python 3
-    int_type = int
-
 
 class GlobalExpr:
     def __init__(self, name, address, type_op, size=0, check_value=0):
@@ -473,6 +468,10 @@
             if tp.is_integer_type() and tp.name != '_Bool':
                 converter = '_cffi_to_c_int'
                 extraarg = ', %s' % tp.name
+            elif isinstance(tp, model.UnknownFloatType):
+                # don't check with is_float_type(): it may be a 'long
+                # double' here, and _cffi_to_c_double would loose precision
+                converter = '(%s)_cffi_to_c_double' % (tp.get_c_name(''),)
             else:
                 converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''),
                                                    tp.name.replace(' ', '_'))
@@ -527,6 +526,8 @@
         if isinstance(tp, model.BasePrimitiveType):
             if tp.is_integer_type():
                 return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
+            elif isinstance(tp, model.UnknownFloatType):
+                return '_cffi_from_c_double(%s)' % (var,)
             elif tp.name != 'long double':
                 return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
             else:
@@ -1112,6 +1113,12 @@
              '         ) <= 0)' % (tp.name, tp.name, tp.name))
         self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s)
 
+    def _emit_bytecode_UnknownFloatType(self, tp, index):
+        s = ('_cffi_prim_float(sizeof(%s) *\n'
+             '           (((%s)1) / 2) * 2 /* integer => 0, float => 1 */\n'
+             '         )' % (tp.name, tp.name))
+        self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s)
+
     def _emit_bytecode_RawFunctionType(self, tp, index):
         self.cffi_types[index] = CffiOp(OP_FUNCTION, 
self._typesdict[tp.result])
         index += 1
diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py
--- a/lib_pypy/cffi/setuptools_ext.py
+++ b/lib_pypy/cffi/setuptools_ext.py
@@ -81,10 +81,16 @@
     allsources.extend(kwds.pop('sources', []))
     ext = Extension(name=module_name, sources=allsources, **kwds)
 
-    def make_mod(tmpdir):
+    def make_mod(tmpdir, pre_run=None):
         c_file = os.path.join(tmpdir, module_name + source_extension)
         log.info("generating cffi module %r" % c_file)
         mkpath(tmpdir)
+        # a setuptools-only, API-only hook: called with the "ext" and "ffi"
+        # arguments just before we turn the ffi into C code.  To use it,
+        # subclass the 'distutils.command.build_ext.build_ext' class and
+        # add a method 'def pre_run(self, ext, ffi)'.
+        if pre_run is not None:
+            pre_run(ext, ffi)
         updated = recompiler.make_c_source(ffi, module_name, source, c_file)
         if not updated:
             log.info("already up-to-date")
@@ -98,7 +104,8 @@
     class build_ext_make_mod(base_class):
         def run(self):
             if ext.sources[0] == '$PLACEHOLDER':
-                ext.sources[0] = make_mod(self.build_temp)
+                pre_run = getattr(self, 'pre_run', None)
+                ext.sources[0] = make_mod(self.build_temp, pre_run)
             base_class.run(self)
     dist.cmdclass['build_ext'] = build_ext_make_mod
     # NB. multiple runs here will create multiple 'build_ext_make_mod'
diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py
--- a/lib_pypy/ctypes_support.py
+++ b/lib_pypy/ctypes_support.py
@@ -28,7 +28,7 @@
     def _where_is_errno():
         return standard_c_lib.__errno_location()
 
-elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'):
+elif sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
     standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int)
     standard_c_lib.__error.argtypes = None
     def _where_is_errno():
diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info
--- a/lib_pypy/greenlet.egg-info
+++ b/lib_pypy/greenlet.egg-info
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: greenlet
-Version: 0.4.7
+Version: 0.4.9
 Summary: Lightweight in-process concurrent programming
 Home-page: https://github.com/python-greenlet/greenlet
 Author: Ralf Schmitt (for CPython), PyPy team
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,7 +1,7 @@
 import sys
 import _continuation
 
-__version__ = "0.4.7"
+__version__ = "0.4.9"
 
 # ____________________________________________________________
 # Exceptions
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -39,7 +39,8 @@
     "_csv", "cppyy", "_pypyjson"
 ])
 
-if sys.platform.startswith('linux') and os.uname()[4] == 'x86_64':
+if (sys.platform.startswith('linux') and os.uname()[4] == 'x86_64'
+        and sys.maxint > 2**32):    # it's not enough that we get x86_64
     working_modules.add('_vmprof')
 
 translation_modules = default_modules.copy()
@@ -91,6 +92,8 @@
 if sys.platform == "win32":
     module_suggests["cpyext"].append(("translation.shared", True))
 
+
+# NOTE: this dictionary is not used any more
 module_import_dependencies = {
     # no _rawffi if importing rpython.rlib.clibffi raises ImportError
     # or CompilationError or py.test.skip.Exception
@@ -107,6 +110,7 @@
     }
 
 def get_module_validator(modname):
+    # NOTE: this function is not used any more
     if modname in module_import_dependencies:
         modlist = module_import_dependencies[modname]
         def validator(config):
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -67,7 +67,7 @@
 # The short X.Y version.
 version = '2.6'
 # The full version, including alpha/beta/rc tags.
-release = '2.6.0'
+release = '2.6.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst
--- a/pypy/doc/contributor.rst
+++ b/pypy/doc/contributor.rst
@@ -32,6 +32,7 @@
   Lukas Diekmann
   Sven Hager
   Anders Lehmann
+  Richard Plangger
   Aurelien Campeas
   Remi Meier
   Niklaus Haldimann
@@ -57,7 +58,6 @@
   Ludovic Aubry
   Jacob Hallen
   Jason Creighton
-  Richard Plangger
   Alex Martelli
   Michal Bendowski
   stian
@@ -138,7 +138,6 @@
   Michael Twomey
   Lucian Branescu Mihaila
   Yichao Yu
-  Anton Gulenko
   Gabriel Lavoie
   Olivier Dormond
   Jared Grubb
@@ -185,6 +184,7 @@
   Carl Meyer
   Karl Ramm
   Pieter Zieschang
+  Anton Gulenko
   Gabriel
   Lukas Vacek
   Andrew Dalke
@@ -217,6 +217,7 @@
   Toni Mattis
   Lucas Stadler
   Julian Berman
+  Markus Holtermann
   roberto@goyle
   Yury V. Zaytsev
   Anna Katrina Dominguez
@@ -252,6 +253,7 @@
   shoma hosaka
   Daniel Neuh&#228;user
   Ben Mather
+  Niclas Olofsson
   halgari
   Boglarka Vezer
   Chris Pressey
diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst
--- a/pypy/doc/embedding.rst
+++ b/pypy/doc/embedding.rst
@@ -20,10 +20,6 @@
    It initializes the RPython/PyPy GC and does a bunch of necessary startup
    code. This function cannot fail.
 
-.. function:: void pypy_init_threads(void);
-
-   Initialize threads. Only need to be called if there are any threads involved
-
 .. function:: int pypy_setup_home(char* home, int verbose);
 
    This function searches the PyPy standard library starting from the given
@@ -38,6 +34,11 @@
    Function returns 0 on success or -1 on failure, can be called multiple times
    until the library is found.
 
+.. function:: void pypy_init_threads(void);
+
+   Initialize threads. Only need to be called if there are any threads 
involved.
+   *Must be called after pypy_setup_home()*
+
 .. function:: int pypy_execute_source(char* source);
 
    Execute the Python source code given in the ``source`` argument. In case of
diff --git a/pypy/doc/extending.rst b/pypy/doc/extending.rst
--- a/pypy/doc/extending.rst
+++ b/pypy/doc/extending.rst
@@ -5,8 +5,8 @@
 with any external library.
 
 Right now, there are the following possibilities of providing
-third-party modules for the PyPy python interpreter (in order of
-usefulness):
+third-party modules for the PyPy python interpreter (in order, from most
+directly useful to most messy to use with PyPy):
 
 * Write them in pure Python and use CFFI_.
 
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -67,7 +67,7 @@
 The other commands of ``setup.py`` are available too, like ``build``.
 
 .. _PyPI: https://pypi.python.org/pypi
-.. _`use virtualenv (as documented here)`: 
getting-started.html#installing-using-virtualenv
+.. _`use virtualenv (as documented here)`: 
install.html#installing-using-virtualenv
 
 
 Module xyz does not work in the sandboxed PyPy?
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -31,15 +31,14 @@
   and add the new file to  pypy/doc/index-of-whatsnew.rst
 * go to pypy/tool/release and run
   ``force-builds.py <release branch>``
-  The following binaries should be built, however, we need more buildbots
- - JIT: windows, linux, os/x, armhf, armel
- - no JIT: windows, linux, os/x
- - sandbox: linux, os/x
+  The following JIT binaries should be built, however, we need more buildbots
+  windows, linux-32, linux-64, osx64, armhf-raring, armhf-raspberrian, armel,
+  freebsd64 
 
 * wait for builds to complete, make sure there are no failures
 * download the builds, repackage binaries. Tag the release version
   and download and repackage source from bitbucket. You may find it
-  convenient to use the ``repackage.sh`` script in pypy/tools to do this. 
+  convenient to use the ``repackage.sh`` script in pypy/tool/release to do 
this. 
 
   Otherwise repackage and upload source "-src.tar.bz2" to bitbucket
   and to cobra, as some packagers prefer a clearly labeled source package
diff --git a/pypy/doc/index-of-release-notes.rst 
b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
 
 .. toctree::
 
+   release-2.6.1.rst
    release-2.6.0.rst
    release-2.5.1.rst
    release-2.5.0.rst
diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst
--- a/pypy/doc/index-of-whatsnew.rst
+++ b/pypy/doc/index-of-whatsnew.rst
@@ -7,6 +7,7 @@
 .. toctree::
 
    whatsnew-head.rst
+   whatsnew-2.6.1.rst
    whatsnew-2.6.0.rst
    whatsnew-2.5.1.rst
    whatsnew-2.5.0.rst
diff --git a/pypy/doc/jit-hooks.rst b/pypy/doc/jit-hooks.rst
--- a/pypy/doc/jit-hooks.rst
+++ b/pypy/doc/jit-hooks.rst
@@ -5,19 +5,8 @@
 understanding what's pypy's JIT doing while running your program. There
 are three functions related to that coming from the ``pypyjit`` module:
 
-.. function:: set_optimize_hook(callable)
 
-    Set a compiling hook that will be called each time a loop is optimized,
-    but before assembler compilation. This allows adding additional
-    optimizations on Python level.
-
-    The callable will be called with the ``pypyjit.JitLoopInfo`` object.
-    Refer to it's documentation for details.
-
-    Result value will be the resulting list of operations, or None
-
-
-.. function:: set_compile_hook(callable)
+.. function:: set_compile_hook(callable, operations=True)
 
     Set a compiling hook that will be called each time a loop is compiled.
 
@@ -28,6 +17,9 @@
     inside the jit hook is itself jitted, it will get compiled, but the
     jit hook won't be called for that.
 
+    if operations=False, no list of operations will be available. Useful
+    if the hook is supposed to be very lighweight.
+
 .. function:: set_abort_hook(hook)
 
     Set a hook (callable) that will be called each time there is tracing
@@ -66,3 +58,25 @@
 
     * ``loop_run_times`` - counters for number of times loops are run, only
       works when ``enable_debug`` is called.
+
+.. class:: JitLoopInfo
+
+   A class containing information about the compiled loop. Usable attributes:
+
+   * ``operations`` - list of operations, if requested
+
+   * ``jitdriver_name`` - the name of jitdriver associated with this loop
+
+   * ``greenkey`` - a key at which the loop got compiled (e.g. code position,
+     is_being_profiled, pycode tuple for python jitdriver)
+
+   * ``loop_no`` - loop cardinal number
+
+   * ``bridge_no`` - id of the fail descr
+
+   * ``type`` - "entry bridge", "loop" or "bridge"
+
+   * ``asmaddr`` - an address in raw memory where assembler resides
+
+   * ``asmlen`` - length of raw memory with assembler associated
+
diff --git a/pypy/doc/release-2.6.1.rst b/pypy/doc/release-2.6.1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.6.1.rst
@@ -0,0 +1,129 @@
+==========
+PyPy 2.6.1 
+==========
+
+We're pleased to announce PyPy 2.6.1, an update to PyPy 2.6.0 released June 1.
+We have updated stdlib to 2.7.10, `cffi`_ to version 1.3, extended support for
+the new vmprof_ statistical profiler for multiple threads, and increased
+functionality of numpy.
+
+You can download the PyPy 2.6.1 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project, and our volunteers and contributors.  
+
+.. _`cffi`: https://cffi.readthedocs.org
+
+We would also like to encourage new people to join the project. PyPy has many
+layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation
+improvements, tweaking popular `modules`_ to run on pypy, or general `help`_ 
with making
+RPython's JIT even better. 
+
+.. _`PyPy`: http://doc.pypy.org 
+.. _`RPython`: https://rpython.readthedocs.org
+.. _`modules`: 
http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly
+.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy and cpython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports **x86** machines on most common operating systems
+(Linux 32/64, Mac OS X 64, Windows 32, OpenBSD_, freebsd_),
+as well as newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux.
+
+We also welcome developers of other
+`dynamic languages`_ to see what RPython can do for them.
+
+.. _`pypy and cpython 2.7.x`: http://speed.pypy.org
+.. _OpenBSD: http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/lang/pypy
+.. _freebsd: https://svnweb.freebsd.org/ports/head/lang/pypy/
+.. _`dynamic languages`: http://pypyjs.org
+
+Highlights 
+===========
+
+* Bug Fixes
+
+  * Revive non-SSE2 support
+
+  * Fixes for detaching _io.Buffer*
+
+  * On Windows, close (and flush) all open sockets on exiting
+
+  * Drop support for ancient macOS v10.4 and before
+
+  * Clear up contention in the garbage collector between trace-me-later and 
pinning
+
+  * Issues reported with our previous release were resolved_ after reports 
from users on
+    our issue tracker at https://bitbucket.org/pypy/pypy/issues or on IRC at
+    #pypy.
+
+* New features:
+
+  * cffi was updated to version 1.3
+
+  * The python stdlib was updated to 2.7.10 from 2.7.9
+
+  * vmprof now supports multiple threads and OS X
+
+  * The translation process builds cffi import libraries for some stdlib
+    packages, which should prevent confusion when package.py is not used
+
+  * better support for gdb debugging
+
+  * freebsd should be able to translate PyPy "out of the box" with no patches
+
+* Numpy:
+
+  * Better support for record dtypes, including the ``align`` keyword
+
+  * Implement casting and create output arrays accordingly (still missing some 
corner cases)
+
+  * Support creation of unicode ndarrays
+
+  * Better support ndarray.flags
+
+  * Support ``axis`` argument in more functions
+
+  * Refactor array indexing to support ellipses
+
+  * Allow the docstrings of built-in numpy objects to be set at run-time
+
+  * Support the ``buffered`` nditer creation keyword
+
+* Performance improvements:
+
+  * Delay recursive calls to make them non-recursive
+
+  * Skip loop unrolling if it compiles too much code
+
+  * Tweak the heapcache
+
+  * Add a list strategy for lists that store both floats and 32-bit integers.
+    The latter are encoded as nonstandard NaNs.  Benchmarks show that the speed
+    of such lists is now very close to the speed of purely-int or purely-float
+    lists. 
+
+  * Simplify implementation of ffi.gc() to avoid most weakrefs
+
+  * Massively improve the performance of map() with more than
+    one sequence argument
+
+.. _`vmprof`: https://vmprof.readthedocs.org
+.. _resolved: http://doc.pypy.org/en/latest/whatsnew-2.6.1.html
+
+Please try it out and let us know what you think. We welcome
+success stories, `experiments`_,  or `benchmarks`_, we know you are using 
PyPy, please tell us about it!
+
+Cheers
+
+The PyPy Team
+
+.. _`experiments`: 
https://morepypy.blogspot.com/2015/02/experiments-in-pyrlang-with-rpython.html
+.. _`benchmarks`: 
https://mithrandi.net/blog/2015/03/axiom-benchmark-results-on-pypy-2-5-0
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.6.1.rst
copy from pypy/doc/whatsnew-head.rst
copy to pypy/doc/whatsnew-2.6.1.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-2.6.1.rst
@@ -1,6 +1,6 @@
-=======================
-What's new in PyPy 2.6+
-=======================
+========================
+What's new in PyPy 2.6.1
+========================
 
 .. this is a revision shortly after release-2.6.0
 .. startrev: 91904d5c5188
@@ -32,7 +32,10 @@
 ``lst[0]`` is still *not* the float ``42.0`` but the integer ``42``.)
 
 .. branch: cffi-callback-onerror
+Part of cffi 1.2.
+
 .. branch: cffi-new-allocator
+Part of cffi 1.2.
 
 .. branch: unicode-dtype
 
@@ -67,3 +70,7 @@
 .. branch: vmprof-review
 
 Clean up of vmprof, notably to handle correctly multiple threads
+
+.. branch: no_boehm_dl
+
+Remove extra link library from Boehm GC
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
@@ -2,68 +2,40 @@
 What's new in PyPy 2.6+
 =======================
 
-.. this is a revision shortly after release-2.6.0
-.. startrev: 91904d5c5188
+.. this is a revision shortly after release-2.6.1
+.. startrev: 07769be4057b
 
-.. branch: use_min_scalar
-Correctly resolve the output dtype of ufunc(array, scalar) calls.
+.. branch: keys_with_hash
+Improve the performance of dict.update() and a bunch of methods from
+sets, by reusing the hash value stored in one dict when inspecting
+or changing another dict with that key.
 
-.. branch: stdlib-2.7.10
+.. branch: optresult-unroll 
+A major refactoring of the ResOperations that kills Box. Also rewrote
+unrolling to enable future enhancements.  Should improve warmup time
+by 20% or so.
 
-Update stdlib to version 2.7.10
+.. branch: optimize-cond-call
+Optimize common sequences of operations like
+``int_lt/cond_call`` in the JIT backends
 
-.. branch: issue2062
+.. branch: missing_openssl_include
+Fix for missing headers in OpenBSD, already applied in downstream ports
 
-.. branch: disable-unroll-for-short-loops
-The JIT no longer performs loop unrolling if the loop compiles to too much 
code.
+.. branch: gc-more-incremental
+Remove a source of non-incremental-ness in the GC: now
+external_malloc() no longer runs gc_step_until() any more. If there
+is a currently-running major collection, we do only so many steps
+before returning. This number of steps depends on the size of the
+allocated object. It is controlled by tracking the general progress
+of these major collection steps and the size of old objects that
+keep adding up between them.
 
-.. branch: run-create_cffi_imports
+.. branch: remember-tracing-counts
+Reenable jithooks
 
-Build cffi import libraries as part of translation by monkey-patching an 
-additional task into translation
+.. branch: detect_egd2
 
-.. branch: int-float-list-strategy
-
-Use a compact strategy for Python lists that mix integers and floats,
-at least if the integers fit inside 32 bits.  These lists are now
-stored as an array of floats, like lists that contain only floats; the
-difference is that integers are stored as tagged NaNs.  (This should
-have no visible effect!  After ``lst = [42, 42.5]``, the value of
-``lst[0]`` is still *not* the float ``42.0`` but the integer ``42``.)
-
-.. branch: cffi-callback-onerror
-.. branch: cffi-new-allocator
-
-.. branch: unicode-dtype
-
-Partial implementation of unicode dtype and unicode scalars.
-
-.. branch: dtypes-compatability
-
-Improve compatibility with numpy dtypes; handle offsets to create unions,
-fix str() and repr(), allow specifying itemsize, metadata and titles, add 
flags,
-allow subclassing dtype
-
-.. branch: indexing
-
-Refactor array indexing to support ellipses.
-
-.. branch: numpy-docstrings
-
-Allow the docstrings of built-in numpy objects to be set at run-time.
-
-.. branch: nditer-revisited
-
-Implement nditer 'buffered' flag and fix some edge cases
-
-.. branch: ufunc-reduce
-
-Allow multiple axes in ufunc.reduce()
-
-.. branch: fix-tinylang-goals
-
-Update tinylang goals to match current rpython
-
-.. branch: vmprof-review
-
-Clean up of vmprof, notably to handle correctly multiple threads
+.. branch: shadowstack-no-move-2
+Issue #2141: fix a crash on Windows and OS/X and ARM when running
+at least 20 threads.
diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py
--- a/pypy/interpreter/miscutils.py
+++ b/pypy/interpreter/miscutils.py
@@ -9,6 +9,7 @@
     implementation for this feature, and patches 'space.threadlocals' when
     'thread' is initialized.
     """
+    _immutable_fields_ = ['_value?']
     _value = None
 
     def get_ec(self):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -111,7 +111,6 @@
                                      'interp_magic.mapdict_cache_counter')
         PYC_MAGIC = get_pyc_magic(self.space)
         self.extra_interpdef('PYC_MAGIC', 'space.wrap(%d)' % PYC_MAGIC)
-        #
         try:
             from rpython.jit.backend import detect_cpu
             model = detect_cpu.autodetect()
@@ -121,7 +120,7 @@
                 raise
             else:
                 pass   # ok fine to ignore in this case
-        #
+        
         if self.space.config.translation.jit:
             features = detect_cpu.getcpufeatures(model)
             self.extra_interpdef('jit_backend_features',
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
@@ -2,7 +2,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib import rdynload
 
-VERSION = "1.2.0"
+VERSION = "1.3.0"
 
 
 class Module(MixedModule):
diff --git a/pypy/module/_cffi_backend/ccallback.py 
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -19,13 +19,27 @@
 # ____________________________________________________________
 
 
+class Closure(object):
+    """This small class is here to have a __del__ outside any cycle."""
+
+    ll_error = lltype.nullptr(rffi.CCHARP.TO)     # set manually
+
+    def __init__(self, ptr):
+        self.ptr = ptr
+
+    def __del__(self):
+        clibffi.closureHeap.free(rffi.cast(clibffi.FFI_CLOSUREP, self.ptr))
+        if self.ll_error:
+            lltype.free(self.ll_error, flavor='raw')
+
+
 class W_CDataCallback(W_CData):
     #_immutable_fields_ = ...
-    ll_error = lltype.nullptr(rffi.CCHARP.TO)
     w_onerror = None
 
     def __init__(self, space, ctype, w_callable, w_error, w_onerror):
         raw_closure = rffi.cast(rffi.CCHARP, clibffi.closureHeap.alloc())
+        self._closure = Closure(raw_closure)
         W_CData.__init__(self, space, raw_closure, ctype)
         #
         if not space.is_true(space.callable(w_callable)):
@@ -44,10 +58,11 @@
         if size > 0:
             if fresult.is_primitive_integer and size < SIZE_OF_FFI_ARG:
                 size = SIZE_OF_FFI_ARG
-            self.ll_error = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw',
-                                          zero=True)
+            self._closure.ll_error = lltype.malloc(rffi.CCHARP.TO, size,
+                                                   flavor='raw', zero=True)
         if not space.is_none(w_error):
-            convert_from_object_fficallback(fresult, self.ll_error, w_error)
+            convert_from_object_fficallback(fresult, self._closure.ll_error,
+                                            w_error)
         #
         self.unique_id = compute_unique_id(self)
         global_callback_mapping.set(self.unique_id, self)
@@ -74,12 +89,6 @@
             from pypy.module.thread.os_thread import setup_threads
             setup_threads(space)
 
-    #@rgc.must_be_light_finalizer
-    def __del__(self):
-        clibffi.closureHeap.free(rffi.cast(clibffi.FFI_CLOSUREP, self._ptr))
-        if self.ll_error:
-            lltype.free(self.ll_error, flavor='raw')
-
     def _repr_extra(self):
         space = self.space
         return 'calling ' + space.str_w(space.repr(self.w_callable))
@@ -114,8 +123,8 @@
     def write_error_return_value(self, ll_res):
         fresult = self.getfunctype().ctitem
         if fresult.size > 0:
-            misc._raw_memcopy(self.ll_error, ll_res, fresult.size)
-            keepalive_until_here(self)     # to keep self.ll_error alive
+            misc._raw_memcopy(self._closure.ll_error, ll_res, fresult.size)
+            keepalive_until_here(self)   # to keep self._closure.ll_error alive
 
 
 global_callback_mapping = rweakref.RWeakValueDictionary(int, W_CDataCallback)
diff --git a/pypy/module/_cffi_backend/cffi_opcode.py 
b/pypy/module/_cffi_backend/cffi_opcode.py
--- a/pypy/module/_cffi_backend/cffi_opcode.py
+++ b/pypy/module/_cffi_backend/cffi_opcode.py
@@ -9,16 +9,16 @@
             assert isinstance(self.arg, str)
             return '(_cffi_opcode_t)(%s)' % (self.arg,)
         classname = CLASS_NAME[self.op]
-        return '_CFFI_OP(_CFFI_OP_%s, %d)' % (classname, self.arg)
+        return '_CFFI_OP(_CFFI_OP_%s, %s)' % (classname, self.arg)
 
     def as_python_bytes(self):
-        if self.op is None:
-            if self.arg.isdigit():
-                value = int(self.arg)     # non-negative: '-' not in self.arg
-                if value >= 2**31:
-                    raise OverflowError("cannot emit %r: limited to 2**31-1"
-                                        % (self.arg,))
-                return format_four_bytes(value)
+        if self.op is None and self.arg.isdigit():
+            value = int(self.arg)     # non-negative: '-' not in self.arg
+            if value >= 2**31:
+                raise OverflowError("cannot emit %r: limited to 2**31-1"
+                                    % (self.arg,))
+            return format_four_bytes(value)
+        if isinstance(self.arg, str):
             from .ffiplatform import VerificationError
             raise VerificationError("cannot emit to Python: %r" % (self.arg,))
         return format_four_bytes((self.arg << 8) | self.op)
@@ -106,7 +106,9 @@
 PRIM_UINTMAX       = 47
 
 _NUM_PRIM          = 48
-_UNKNOWN_PRIM      = -1
+_UNKNOWN_PRIM          = -1
+_UNKNOWN_FLOAT_PRIM    = -2
+_UNKNOWN_LONG_DOUBLE   = -3
 
 PRIMITIVE_TO_INDEX = {
     'char':               PRIM_CHAR,
diff --git a/pypy/module/_cffi_backend/realize_c_type.py 
b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -81,6 +81,13 @@
         if num == cffi_opcode._UNKNOWN_PRIM:
             raise oefmt(ffi.w_FFIError, "primitive integer type with an "
                         "unexpected size (or not an integer type at all)")
+        elif num == cffi_opcode._UNKNOWN_FLOAT_PRIM:
+            raise oefmt(ffi.w_FFIError, "primitive floating-point type with an 
"
+                        "unexpected size (or not a float type at all)")
+        elif num == cffi_opcode._UNKNOWN_LONG_DOUBLE:
+            raise oefmt(ffi.w_FFIError, "primitive floating-point type is "
+                        "'long double', not supported for now with "
+                        "the syntax 'typedef double... xxx;'")
         else:
             raise oefmt(space.w_NotImplementedError, "prim=%d", num)
     realize_cache = space.fromcache(RealizeCache)
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,6 +1,9 @@
 # ____________________________________________________________
 
 import sys
+assert __version__ == "1.3.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,):
     type_or_class = "type"
     mandatory_b_prefix = ''
@@ -3424,7 +3427,3 @@
                             "be 'foo *', but the types are different (check "
                             "that you are not e.g. mixing up different ffi "
                             "instances)")
-
-def test_version():
-    # this test is here mostly for PyPy
-    assert __version__ == "1.2.0"
diff --git a/pypy/module/_multiprocessing/test/test_memory.py 
b/pypy/module/_multiprocessing/test/test_memory.py
--- a/pypy/module/_multiprocessing/test/test_memory.py
+++ b/pypy/module/_multiprocessing/test/test_memory.py
@@ -1,8 +1,12 @@
+import sys
+
 class AppTestMemory:
     spaceconfig = dict(usemodules=('_multiprocessing', 'mmap',
                                    '_rawffi', 'itertools',
-                                   'signal', 'select', 'fcntl',
+                                   'signal', 'select',
                                    'binascii'))
+    if sys.platform != 'win32':
+        spaceconfig['usemodules'] += ('fcntl',)
 
     def test_address_of(self):
         import _multiprocessing
diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py 
b/pypy/module/_multiprocessing/test/test_semaphore.py
--- a/pypy/module/_multiprocessing/test/test_semaphore.py
+++ b/pypy/module/_multiprocessing/test/test_semaphore.py
@@ -1,12 +1,19 @@
+import sys
+
 from pypy.module._multiprocessing.interp_semaphore import (
     RECURSIVE_MUTEX, SEMAPHORE)
 
 
 class AppTestSemaphore:
     spaceconfig = dict(usemodules=('_multiprocessing', 'thread',
-                                   'signal', 'select', 'fcntl',
+                                   'signal', 'select',
                                    'binascii', 'struct'))
 
+    if sys.platform == 'win32':
+        spaceconfig['usemodules'] += ('_rawffi',)
+    else:
+        spaceconfig['usemodules'] += ('fcntl',)
+
     def setup_class(cls):
         cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE)
         cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX)
diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py
--- a/pypy/module/_ssl/interp_ssl.py
+++ b/pypy/module/_ssl/interp_ssl.py
@@ -241,20 +241,26 @@
         res = libssl_RAND_status()
         return space.wrap(res)
 
-    @unwrap_spec(path=str)
-    def RAND_egd(space, path):
-        """RAND_egd(path) -> bytes
+    if HAVE_OPENSSL_RAND_EGD:
+        @unwrap_spec(path=str)
+        def RAND_egd(space, path):
+            """RAND_egd(path) -> bytes
 
-        Queries the entropy gather daemon (EGD) on socket path.  Returns number
-        of bytes read.  Raises socket.sslerror if connection to EGD fails or
-        if it does provide enough data to seed PRNG."""
-        with rffi.scoped_str2charp(path) as socket_path:
-            bytes = libssl_RAND_egd(socket_path)
-        if bytes == -1:
-            raise ssl_error(space,
-                            "EGD connection failed or EGD did not return "
-                            "enough data to seed the PRNG")
-        return space.wrap(bytes)
+            Queries the entropy gather daemon (EGD) on socket path.  Returns 
number
+            of bytes read.  Raises socket.sslerror if connection to EGD fails 
or
+            if it does provide enough data to seed PRNG."""
+            with rffi.scoped_str2charp(path) as socket_path:
+                bytes = libssl_RAND_egd(socket_path)
+            if bytes == -1:
+                raise ssl_error(space,
+                                "EGD connection failed or EGD did not return "
+                                "enough data to seed the PRNG")
+            return space.wrap(bytes)
+    else:
+        # Dummy func for platforms missing RAND_egd(). Most likely LibreSSL.
+        @unwrap_spec(path=str)
+        def RAND_egd(space, path):
+            raise ssl_error(space, "RAND_egd unavailable")
 
 
 class _SSLSocket(W_Root):
diff --git a/pypy/module/_ssl/test/test_ssl.py 
b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -36,7 +36,8 @@
         assert isinstance(_ssl.OPENSSL_VERSION_INFO, tuple)
         assert len(_ssl.OPENSSL_VERSION_INFO) == 5
         assert isinstance(_ssl.OPENSSL_VERSION, str)
-        assert 'openssl' in _ssl.OPENSSL_VERSION.lower()
+        lower_version = _ssl.OPENSSL_VERSION.lower()
+        assert 'openssl' in lower_version or "libressl" in lower_version
 
         assert isinstance(_ssl.ALERT_DESCRIPTION_ACCESS_DENIED, int)
 
@@ -69,8 +70,9 @@
 
     def test_sslwrap(self):
         import _ssl, _socket, sys, gc
-        if sys.platform == 'darwin' or 'freebsd' in sys.platform:
-            skip("hangs indefinitely on OSX & FreeBSD (also on CPython)")
+        if sys.platform == 'darwin' or 'freebsd' in sys.platform or \
+                'openbsd' in sys.platform:
+            skip("hangs indefinitely on OSX & BSD (also on CPython)")
         s = _socket.socket()
         if sys.version_info < (2, 7, 9):
             ss = _ssl.sslwrap(s, 0)
diff --git a/pypy/module/_vmprof/test/test__vmprof.py 
b/pypy/module/_vmprof/test/test__vmprof.py
--- a/pypy/module/_vmprof/test/test__vmprof.py
+++ b/pypy/module/_vmprof/test/test__vmprof.py
@@ -21,11 +21,12 @@
             i = 0
             count = 0
             i += 5 * WORD # header
-            assert s[i] == '\x04'
-            i += 1 # marker
-            assert s[i] == '\x04'
-            i += 1 # length
-            i += len('pypy')
+            assert s[i    ] == '\x05'    # MARKER_HEADER
+            assert s[i + 1] == '\x00'    # 0
+            assert s[i + 2] == '\x01'    # VERSION_THREAD_ID
+            assert s[i + 3] == chr(4)    # len('pypy')
+            assert s[i + 4: i + 8] == 'pypy'
+            i += 8
             while i < len(s):
                 if s[i] == '\x03':
                     break
diff --git a/pypy/module/_vmprof/test/test_direct.py 
b/pypy/module/_vmprof/test/test_direct.py
--- a/pypy/module/_vmprof/test/test_direct.py
+++ b/pypy/module/_vmprof/test/test_direct.py
@@ -42,7 +42,7 @@
 }
 
 
-""" + open(str(srcdir.join("rvmprof_get_custom_offset.h"))).read())
+""" + open(str(srcdir.join("vmprof_get_custom_offset.h"))).read())
 
 class TestDirect(object):
     def test_infrastructure(self):
diff --git a/pypy/module/cpyext/include/object.h 
b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -379,6 +379,8 @@
     PyObject *ht_name, *ht_slots;
 } PyHeapTypeObject;
 
+#define PyObject_Bytes PyObject_Str
+
 /* Flag bits for printing: */
 #define Py_PRINT_RAW   1       /* No string quotes etc. */
 
diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -2,6 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
+from rpython.rlib import jit
 
 
 class W_Count(W_Root):
@@ -322,6 +323,11 @@
     """)
 
 
+islice_ignore_items_driver = jit.JitDriver(name='islice_ignore_items',
+                                           greens=['tp'],
+                                           reds=['num', 'w_islice',
+                                                 'w_iterator'])
+
 class W_ISlice(W_Root):
     def __init__(self, space, w_iterable, w_startstop, args_w):
         self.iterable = space.iter(w_iterable)
@@ -407,11 +413,18 @@
             raise
 
     def _ignore_items(self, num):
-        if self.iterable is None:
+        w_iterator = self.iterable
+        if w_iterator is None:
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
+
+        tp = self.space.type(w_iterator)
         while True:
+            islice_ignore_items_driver.jit_merge_point(tp=tp,
+                                                       num=num,
+                                                       w_islice=self,
+                                                       w_iterator=w_iterator)
             try:
-                self.space.next(self.iterable)
+                self.space.next(w_iterator)
             except OperationError as e:
                 if e.match(self.space, self.space.w_StopIteration):
                     self.iterable = None
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -1085,3 +1085,18 @@
                 assert list(itertools.islice(c2, 3)) == expected
                 c3 = pickle.loads(pickle.dumps(c))
                 assert list(itertools.islice(c3, 3)) == expected
+
+    def test_islice_attack(self):
+        import itertools
+        class Iterator(object):
+            first = True
+            def __iter__(self):
+                return self
+            def next(self):
+                if self.first:
+                    self.first = False
+                    list(islice)
+                return 52
+        myiter = Iterator()
+        islice = itertools.islice(myiter, 5, 8)
+        raises(StopIteration, islice.next)
diff --git a/pypy/module/micronumpy/__init__.py 
b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -9,6 +9,7 @@
         'ndarray': 'ndarray.W_NDimArray',
         'dtype': 'descriptor.W_Dtype',
         'flatiter': 'flatiter.W_FlatIterator',
+        'flagsobj': 'flagsobj.W_FlagsObject',
 
         '_reconstruct' : 'ndarray._reconstruct',
         'scalar' : 'ctors.build_scalar',
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.tool.pairtype import extendabletype
+from rpython.rlib.rarithmetic import ovfcheck
 from pypy.module.micronumpy import support
 from pypy.module.micronumpy import constants as NPY
 
@@ -44,9 +45,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(shape) * dtype.elsize
+            ovfcheck(support.product_check(shape) * dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         strides, backstrides = calc_strides(shape, dtype.base, order)
         impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
                                       backstrides, zero=zero)
@@ -68,9 +69,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            totalsize = support.product(shape) * isize
+            totalsize = ovfcheck(support.product_check(shape) * isize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         if storage_bytes > 0 :
             if totalsize > storage_bytes:
                 raise OperationError(space.w_TypeError, space.wrap(
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -147,7 +147,7 @@
 
     def get_flags(self):
         return (NPY.ARRAY_C_CONTIGUOUS | NPY.ARRAY_F_CONTIGUOUS |
-                NPY.ARRAY_WRITEABLE | NPY.ARRAY_OWNDATA)
+                NPY.ARRAY_ALIGNED | NPY.ARRAY_OWNDATA)
 
     def item(self, space):
         return self.get_dtype(space).itemtype.to_builtin_type(space, self)
diff --git a/pypy/module/micronumpy/concrete.py 
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -1,5 +1,6 @@
 from pypy.interpreter.error import OperationError, oefmt
 from rpython.rlib import jit, rgc
+from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rlib.buffer import Buffer
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage, \
@@ -409,6 +410,7 @@
         make_sure_not_resized(strides)
         make_sure_not_resized(backstrides)
         self.shape = shape
+        # already tested for overflow in from_shape_and_storage
         self.size = support.product(shape) * dtype.elsize
         self.order = order
         self.dtype = dtype
@@ -428,9 +430,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(new_shape) * self.dtype.elsize
+            ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         strides, backstrides = calc_strides(new_shape, self.dtype,
                                                     self.order)
         return SliceArray(self.start, strides, backstrides, new_shape, self,
@@ -457,8 +459,11 @@
                  storage=lltype.nullptr(RAW_STORAGE), zero=True):
         gcstruct = V_OBJECTSTORE
         flags = NPY.ARRAY_ALIGNED | NPY.ARRAY_WRITEABLE
-        length = support.product(shape)
-        self.size = length * dtype.elsize
+        try:
+            length = support.product_check(shape)
+            self.size = ovfcheck(length * dtype.elsize)
+        except OverflowError: 
+            raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.")
         if storage == lltype.nullptr(RAW_STORAGE):
             if dtype.num == NPY.OBJECT:
                 storage = dtype.itemtype.malloc(length * dtype.elsize, 
zero=True)
@@ -542,7 +547,10 @@
         self.gcstruct = parent.gcstruct
         self.order = parent.order
         self.dtype = dtype
-        self.size = support.product(shape) * self.dtype.elsize
+        try:
+            self.size = ovfcheck(support.product_check(shape) * 
self.dtype.elsize)
+        except OverflowError:
+            raise oefmt(dtype.itemtype.space.w_ValueError, "array is too big.")
         self.start = start
         self.orig_arr = orig_arr
         flags = parent.flags & NPY.ARRAY_ALIGNED
@@ -564,9 +572,9 @@
             raise oefmt(space.w_ValueError,
                 "sequence too large; must be smaller than %d", NPY.MAXDIMS)
         try:
-            support.product(new_shape) * self.dtype.elsize
+            ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
-            raise oefmt(space.w_ValueError, "array is too big")
+            raise oefmt(space.w_ValueError, "array is too big.")
         if len(self.get_shape()) < 2 or self.size == 0:
             # TODO: this code could be refactored into calc_strides
             # but then calc_strides would have to accept a stepping factor
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -153,7 +153,7 @@
             dtype = descriptor.variable_dtype(space, dtype.char + '1')
 
     w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
-    if support.product(shape) == 1:
+    if support.product(shape) == 1: # safe from overflow since from_shape 
checks
         w_arr.set_scalar_value(dtype.coerce(space, elems_w[0]))
     else:
         loop.assign(space, w_arr, elems_w)
@@ -213,10 +213,9 @@
             raise OperationError(space.w_ValueError, space.wrap(
                 "negative dimensions are not allowed"))
     try:
-        support.product(shape)
+        support.product_check(shape)
     except OverflowError:
-        raise OperationError(space.w_ValueError, space.wrap(
-            "array is too big."))
+        raise oefmt(space.w_ValueError, "array is too big.")
     return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
 
 def empty(space, w_shape, w_dtype=None, w_order=None):
diff --git a/pypy/module/micronumpy/flagsobj.py 
b/pypy/module/micronumpy/flagsobj.py
--- a/pypy/module/micronumpy/flagsobj.py
+++ b/pypy/module/micronumpy/flagsobj.py
@@ -57,6 +57,9 @@
             self.flags & NPY.ARRAY_F_CONTIGUOUS or
             self.flags & NPY.ARRAY_C_CONTIGUOUS ))
 
+    def descr_get_num(self, space):
+        return space.wrap(self.flags)
+
     def descr_getitem(self, space, w_item):
         key = space.str_w(w_item)
         if key == "C" or key == "CONTIGUOUS" or key == "C_CONTIGUOUS":
@@ -122,4 +125,5 @@
     aligned = GetSetProperty(W_FlagsObject.descr_get_aligned),
     fnc = GetSetProperty(W_FlagsObject.descr_get_fnc),
     forc = GetSetProperty(W_FlagsObject.descr_get_forc),
+    num = GetSetProperty(W_FlagsObject.descr_get_num),
 )
diff --git a/pypy/module/micronumpy/ndarray.py 
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -6,6 +6,7 @@
 from rpython.rlib import jit
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rawstorage import RAW_STORAGE_PTR
+from rpython.rlib.rarithmetic import ovfcheck
 from rpython.rtyper.lltypesystem import rffi
 from rpython.tool.sourcetools import func_with_new_name
 from pypy.module.micronumpy import descriptor, ufuncs, boxes, arrayops, loop, \
@@ -611,6 +612,7 @@
                 "__array__(dtype) not implemented"))
         if type(self) is W_NDimArray:
             return self
+        # sz cannot overflow since self is valid
         sz = support.product(self.get_shape()) * self.get_dtype().elsize
         return W_NDimArray.from_shape_and_storage(
             space, self.get_shape(), self.implementation.storage,
@@ -1405,9 +1407,9 @@
         return W_NDimArray.from_shape(space, shape, dtype, order)
     strides, backstrides = calc_strides(shape, dtype.base, order)
     try:
-        totalsize = support.product(shape) * dtype.base.elsize
+        totalsize = ovfcheck(support.product_check(shape) * dtype.base.elsize)
     except OverflowError as e:
-        raise oefmt(space.w_ValueError, "array is too big")
+        raise oefmt(space.w_ValueError, "array is too big.")
     impl = ConcreteArray(shape, dtype.base, order, strides, backstrides)
     w_ret = space.allocate_instance(W_NDimArray, w_subtype)
     W_NDimArray.__init__(w_ret, impl)
diff --git a/pypy/module/micronumpy/support.py 
b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -32,10 +32,16 @@
 def product(s):
     i = 1
     for x in s:
+        i *= x
+    return i
+
[email protected]_safe
+def product_check(s):
+    i = 1
+    for x in s:
         i = ovfcheck(i * x)
     return i
 
-
 def check_and_adjust_index(space, index, size, axis):
     if index < -size or index >= size:
         if axis >= 0:
diff --git a/pypy/module/micronumpy/test/test_flagsobj.py 
b/pypy/module/micronumpy/test/test_flagsobj.py
--- a/pypy/module/micronumpy/test/test_flagsobj.py
+++ b/pypy/module/micronumpy/test/test_flagsobj.py
@@ -30,6 +30,7 @@
         assert a.flags.forc == True
         assert a.flags['FNC'] == False
         assert a.flags['FORC'] == True
+        assert a.flags.num == 1287
         raises(KeyError, "a.flags['blah']")
         raises(KeyError, "a.flags['C_CONTIGUOUS'] = False")
         raises((TypeError, AttributeError), "a.flags.c_contiguous = False")
@@ -38,6 +39,7 @@
         import numpy as np
         a = np.int32(2)
         assert a.flags.c_contiguous == True
+        assert a.flags.num == 263
 
     def test_compare(self):
         import numpy as np
diff --git a/pypy/module/micronumpy/test/test_ndarray.py 
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -270,7 +270,7 @@
         exc = raises(ValueError, ndarray, [1,2,256]*10000)
         assert exc.value[0] == 'sequence too large; must be smaller than 32'
         exc = raises(ValueError, ndarray, [1,2,256]*10)
-        assert exc.value[0] == 'array is too big'
+        assert exc.value[0] == 'array is too big.'
 
     def test_ndmin(self):
         from numpy import array
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -1006,7 +1006,6 @@
             assert isinstance(curarg, W_NDimArray)
             if len(arg_shapes[i]) != curarg.ndims():
                 # reshape
-
                 sz = product(curarg.get_shape()) * curarg.get_dtype().elsize
                 with curarg.implementation as storage:
                     inargs[i] = W_NDimArray.from_shape_and_storage(
diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -8,8 +8,11 @@
         'set_param':    'interp_jit.set_param',
         'residual_call': 'interp_jit.residual_call',
         'not_from_assembler': 'interp_jit.W_NotFromAssembler',
+        'get_jitcell_at_key': 'interp_jit.get_jitcell_at_key',
+        'dont_trace_here': 'interp_jit.dont_trace_here',
+        'trace_next_iteration': 'interp_jit.trace_next_iteration',
+        'trace_next_iteration_hash': 'interp_jit.trace_next_iteration_hash',
         'set_compile_hook': 'interp_resop.set_compile_hook',
-        'set_optimize_hook': 'interp_resop.set_optimize_hook',
         'set_abort_hook': 'interp_resop.set_abort_hook',
         'get_stats_snapshot': 'interp_resop.get_stats_snapshot',
         'enable_debug': 'interp_resop.enable_debug',
@@ -17,7 +20,6 @@
         'ResOperation': 'interp_resop.WrappedOp',
         'DebugMergePoint': 'interp_resop.DebugMergePoint',
         'JitLoopInfo': 'interp_resop.W_JitLoopInfo',
-        'Box': 'interp_resop.WrappedBox',
         'PARAMETER_DOCS': 'space.wrap(rpython.rlib.jit.PARAMETER_DOCS)',
     }
 
diff --git a/pypy/module/pypyjit/hooks.py b/pypy/module/pypyjit/hooks.py
--- a/pypy/module/pypyjit/hooks.py
+++ b/pypy/module/pypyjit/hooks.py
@@ -35,10 +35,10 @@
         self._compile_hook(debug_info, is_bridge=True)
 
     def before_compile(self, debug_info):
-        self._optimize_hook(debug_info, is_bridge=False)
+        pass
 
     def before_compile_bridge(self, debug_info):
-        self._optimize_hook(debug_info, is_bridge=True)
+        pass
 
     def _compile_hook(self, debug_info, is_bridge):
         space = self.space
@@ -46,7 +46,8 @@
         if cache.in_recursion:
             return
         if space.is_true(cache.w_compile_hook):
-            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
+            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge,
+                                         cache.compile_hook_with_ops)
             cache.in_recursion = True
             try:
                 try:
@@ -57,33 +58,4 @@
             finally:
                 cache.in_recursion = False
 
-    def _optimize_hook(self, debug_info, is_bridge=False):
-        space = self.space
-        cache = space.fromcache(Cache)
-        if cache.in_recursion:
-            return
-        if space.is_true(cache.w_optimize_hook):
-            w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
-            cache.in_recursion = True
-            try:
-                try:
-                    w_res = space.call_function(cache.w_optimize_hook,
-                                                space.wrap(w_debug_info))
-                    if space.is_w(w_res, space.w_None):
-                        return
-                    l = []
-                    for w_item in space.listview(w_res):
-                        item = space.interp_w(WrappedOp, w_item)
-                        l.append(jit_hooks._cast_to_resop(item.op))
-                    del debug_info.operations[:] # modifying operations above 
is
-                    # probably not a great idea since types may not work
-                    # and we'll end up with half-working list and
-                    # a segfault/fatal RPython error
-                    for elem in l:
-                        debug_info.operations.append(elem)
-                except OperationError, e:
-                    e.write_unraisable(space, "jit hook ", 
cache.w_compile_hook)
-            finally:
-                cache.in_recursion = False
-
 pypy_hooks = PyPyJitIface()
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
@@ -5,11 +5,14 @@
 
 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
-from rpython.rlib.jit import current_trace_length, unroll_parameters
+from rpython.rlib import jit, jit_hooks
+from rpython.rlib.jit import current_trace_length, unroll_parameters,\
+     JitHookInterface
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
 import pypy.interpreter.pyopcode   # for side-effects
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.pycode import CO_GENERATOR, PyCode
+from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pyopcode import ExitFrame, Yield
 from pypy.interpreter.baseobjspace import W_Root
@@ -188,3 +191,100 @@
     __call__ = interp2app(W_NotFromAssembler.descr_call),
 )
 W_NotFromAssembler.typedef.acceptable_as_base_class = False
+
+@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+@dont_look_inside
+def get_jitcell_at_key(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    return space.wrap(bool(jit_hooks.get_jitcell_at_key(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)))
+
+@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+@dont_look_inside
+def dont_trace_here(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    jit_hooks.dont_trace_here(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)
+    return space.w_None
+
+@unwrap_spec(next_instr=int, is_being_profiled=bool, w_pycode=PyCode)
+@dont_look_inside
+def trace_next_iteration(space, next_instr, is_being_profiled, w_pycode):
+    ll_pycode = cast_instance_to_gcref(w_pycode)
+    jit_hooks.trace_next_iteration(
+        'pypyjit', r_uint(next_instr), int(is_being_profiled), ll_pycode)
+    return space.w_None
+
+@unwrap_spec(hash=r_uint)
+@dont_look_inside
+def trace_next_iteration_hash(space, hash):
+    jit_hooks.trace_next_iteration_hash('pypyjit', hash)
+    return space.w_None
+
+# class Cache(object):
+#     in_recursion = False
+
+#     def __init__(self, space):
+#         self.w_compile_bridge = space.w_None
+#         self.w_compile_loop = space.w_None
+
+# def set_compile_bridge(space, w_hook):
+#     cache = space.fromcache(Cache)
+#     assert w_hook is not None
+#     cache.w_compile_bridge = w_hook
+
+# def set_compile_loop(space, w_hook):
+#     from rpython.rlib.nonconst import NonConstant
+    
+#     cache = space.fromcache(Cache)
+#     assert w_hook is not None
+#     cache.w_compile_loop = w_hook
+#     cache.in_recursion = NonConstant(False)
+
+# class PyPyJitHookInterface(JitHookInterface):
+#     def after_compile(self, debug_info):
+#         space = self.space
+#         cache = space.fromcache(Cache)
+#         if cache.in_recursion:
+#             return
+#         l_w = []
+#         if not space.is_true(cache.w_compile_loop):
+#             return
+#         for i, op in enumerate(debug_info.operations):
+#             if op.is_guard():
+#                 w_t = space.newtuple([space.wrap(i), 
space.wrap(op.getopnum()), space.wrap(op.getdescr().get_jitcounter_hash())])
+#                 l_w.append(w_t)
+#         try:
+#             cache.in_recursion = True
+#             try:
+#                 space.call_function(cache.w_compile_loop, space.newlist(l_w))
+#             except OperationError, e:
+#                 e.write_unraisable(space, "jit hook ", 
cache.w_compile_bridge)
+#         finally:
+#             cache.in_recursion = False
+
+#     def after_compile_bridge(self, debug_info):
+#         space = self.space
+#         cache = space.fromcache(Cache)
+#         if cache.in_recursion:
+#             return
+#         if not space.is_true(cache.w_compile_bridge):
+#             return
+#         w_hash = space.wrap(debug_info.fail_descr.get_jitcounter_hash())
+#         try:
+#             cache.in_recursion = True
+#             try:
+#                 space.call_function(cache.w_compile_bridge, w_hash)
+#             except OperationError, e:
+#                 e.write_unraisable(space, "jit hook ", 
cache.w_compile_bridge)
+#         finally:
+#             cache.in_recursion = False
+
+#     def before_compile(self, debug_info):
+#         pass
+
+#     def before_compile_bridge(self, debug_info):
+#         pass
+
+# pypy_hooks = PyPyJitHookInterface()
+
diff --git a/pypy/module/pypyjit/interp_resop.py 
b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -8,7 +8,7 @@
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, hlstr
 from rpython.rtyper.rclass import OBJECT
-from rpython.jit.metainterp.resoperation import rop
+#from rpython.jit.metainterp.resoperation import rop
 from rpython.rlib.nonconst import NonConstant
 from rpython.rlib import jit_hooks
 from rpython.rlib.jit import Counters
@@ -22,7 +22,6 @@
     def __init__(self, space):
         self.w_compile_hook = space.w_None
         self.w_abort_hook = space.w_None
-        self.w_optimize_hook = space.w_None
 
     def getno(self):
         self.no += 1
@@ -43,8 +42,9 @@
     else:
         return space.wrap(greenkey_repr)
 
-def set_compile_hook(space, w_hook):
-    """ set_compile_hook(hook)
+@unwrap_spec(operations=bool)
+def set_compile_hook(space, w_hook, operations=True):
+    """ set_compile_hook(hook, operations=True)
 
     Set a compiling hook that will be called each time a loop is compiled.
 
@@ -58,25 +58,9 @@
     cache = space.fromcache(Cache)
     assert w_hook is not None
     cache.w_compile_hook = w_hook
+    cache.compile_hook_with_ops = operations
     cache.in_recursion = NonConstant(False)
 
-def set_optimize_hook(space, w_hook):
-    """ set_optimize_hook(hook)
-
-    Set a compiling hook that will be called each time a loop is optimized,
-    but before assembler compilation. This allows adding additional
-    optimizations on Python level.
-
-    The hook will be called with the pypyjit.JitLoopInfo object. Refer to it's
-    docstring for details.
-
-    Result value will be the resulting list of operations, or None
-    """
-    cache = space.fromcache(Cache)
-    cache.w_optimize_hook = w_hook
-    cache.in_recursion = NonConstant(False)
-
-
 def set_abort_hook(space, w_hook):
     """ set_abort_hook(hook)
 
@@ -96,6 +80,9 @@
     cache.in_recursion = NonConstant(False)
 
 def wrap_oplist(space, logops, operations, ops_offset=None):
+    # this function is called from the JIT
+    from rpython.jit.metainterp.resoperation import rop
+    
     l_w = []
     jitdrivers_sd = logops.metainterp_sd.jitdrivers_sd
     for op in operations:
@@ -103,117 +90,58 @@
             ofs = -1
         else:
             ofs = ops_offset.get(op, 0)
-        if op.opnum == rop.DEBUG_MERGE_POINT:
+        num = op.getopnum()
+        name = op.getopname()
+        if num == rop.DEBUG_MERGE_POINT:
             jd_sd = jitdrivers_sd[op.getarg(0).getint()]
             greenkey = op.getarglist()[3:]
             repr = jd_sd.warmstate.get_location_str(greenkey)
             w_greenkey = wrap_greenkey(space, jd_sd.jitdriver, greenkey, repr)
-            l_w.append(DebugMergePoint(space, jit_hooks._cast_to_gcref(op),
+            l_w.append(DebugMergePoint(space, name,
                                        logops.repr_of_resop(op),
                                        jd_sd.jitdriver.name,
                                        op.getarg(1).getint(),
                                        op.getarg(2).getint(),
                                        w_greenkey))
         else:
-            l_w.append(WrappedOp(jit_hooks._cast_to_gcref(op), ofs,
-                                 logops.repr_of_resop(op)))
+            l_w.append(WrappedOp(name, ofs, logops.repr_of_resop(op)))
     return l_w
 
+@unwrap_spec(offset=int, repr=str, name=str)
+def descr_new_resop(space, w_tp, name, offset=-1, repr=''):
+    return WrappedOp(name, offset, repr)
 
-class WrappedBox(W_Root):
-    """ A class representing a single box
-    """
-    def __init__(self, llbox):
-        self.llbox = llbox
-
-    def descr_getint(self, space):
-        if not jit_hooks.box_isint(self.llbox):
-            raise OperationError(space.w_NotImplementedError,
-                                 space.wrap("Box has no int value"))
-        return space.wrap(jit_hooks.box_getint(self.llbox))
-
-@unwrap_spec(no=int)
-def descr_new_box(space, w_tp, no):
-    return WrappedBox(jit_hooks.boxint_new(no))
-
-WrappedBox.typedef = TypeDef(
-    'Box',
-    __new__ = interp2app(descr_new_box),
-    getint = interp2app(WrappedBox.descr_getint),
-)
-
-@unwrap_spec(num=int, offset=int, repr=str, w_res=W_Root)
-def descr_new_resop(space, w_tp, num, w_args, w_res, offset=-1,
-                    repr=''):
-    args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
-            space.listview(w_args)]
-    if space.is_none(w_res):
-        llres = jit_hooks.emptyval()
-    else:
-        if not isinstance(w_res, WrappedBox):
-            raise OperationError(space.w_TypeError, space.wrap(
-                "expected box type, got %s" % space.type(w_res)))
-        llres = w_res.llbox
-    return WrappedOp(jit_hooks.resop_new(num, args, llres), offset, repr)
-
-@unwrap_spec(repr=str, jd_name=str, call_depth=int, call_id=int)
-def descr_new_dmp(space, w_tp, w_args, repr, jd_name, call_depth, call_id,
+@unwrap_spec(repr=str, name=str, jd_name=str, call_depth=int, call_id=int)
+def descr_new_dmp(space, w_tp, name, repr, jd_name, call_depth, call_id,
     w_greenkey):
 
-    args = [space.interp_w(WrappedBox, w_arg).llbox for w_arg in
-            space.listview(w_args)]
-    num = rop.DEBUG_MERGE_POINT
-    return DebugMergePoint(space,
-                           jit_hooks.resop_new(num, args, 
jit_hooks.emptyval()),
+    return DebugMergePoint(space, name,
                            repr, jd_name, call_depth, call_id, w_greenkey)
 
 
 class WrappedOp(W_Root):
     """ A class representing a single ResOperation, wrapped nicely
     """
-    def __init__(self, op, offset, repr_of_resop):
-        self.op = op
+    def __init__(self, name, offset, repr_of_resop):
         self.offset = offset
+        self.name = name
         self.repr_of_resop = repr_of_resop
 
     def descr_repr(self, space):
         return space.wrap(self.repr_of_resop)
 
-    def descr_num(self, space):
-        return space.wrap(jit_hooks.resop_getopnum(self.op))
-
     def descr_name(self, space):
-        return space.wrap(hlstr(jit_hooks.resop_getopname(self.op)))
-
-    @unwrap_spec(no=int)
-    def descr_getarg(self, space, no):
-        try:
-            box = jit_hooks.resop_getarg(self.op, no)
-        except IndexError:
-            raise OperationError(space.w_IndexError,
-                                 space.wrap("Index out of range"))
-        return WrappedBox(box)
-
-    @unwrap_spec(no=int, w_box=WrappedBox)
-    def descr_setarg(self, space, no, w_box):
-        jit_hooks.resop_setarg(self.op, no, w_box.llbox)
-
-    def descr_getresult(self, space):
-        return WrappedBox(jit_hooks.resop_getresult(self.op))
-
-    def descr_setresult(self, space, w_box):
-        box = space.interp_w(WrappedBox, w_box)
-        jit_hooks.resop_setresult(self.op, box.llbox)
+        return space.wrap(self.name)
 
 class DebugMergePoint(WrappedOp):
     """ A class representing Debug Merge Point - the entry point
     to a jitted loop.
     """
 
-    def __init__(self, space, op, repr_of_resop, jd_name, call_depth, call_id,
-        w_greenkey):
+    def __init__(self, space, name, repr_of_resop, jd_name, call_depth,
+                 call_id, w_greenkey):
 
-        WrappedOp.__init__(self, op, -1, repr_of_resop)
+        WrappedOp.__init__(self, name, -1, repr_of_resop)
         self.jd_name = jd_name
         self.call_depth = call_depth
         self.call_id = call_id
@@ -237,12 +165,7 @@
     __doc__ = WrappedOp.__doc__,
     __new__ = interp2app(descr_new_resop),
     __repr__ = interp2app(WrappedOp.descr_repr),
-    num = GetSetProperty(WrappedOp.descr_num),
     name = GetSetProperty(WrappedOp.descr_name),
-    getarg = interp2app(WrappedOp.descr_getarg),
-    setarg = interp2app(WrappedOp.descr_setarg),
-    result = GetSetProperty(WrappedOp.descr_getresult,
-                            WrappedOp.descr_setresult),
     offset = interp_attrproperty("offset", cls=WrappedOp),
 )
 WrappedOp.typedef.acceptable_as_base_class = False
@@ -278,14 +201,18 @@
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to