Commits

wlav committed 5b43899 Merge

merge default into branch

Comments (0)

Files changed (100)

lib-python/2.7/argparse.py

             # error if this argument is not allowed with other previously
             # seen arguments, assuming that actions that use the default
             # value don't really count as "present"
-            if argument_values is not action.default:
+
+            # XXX PyPy bug-to-bug compatibility: "is" on primitive types
+            # is not consistent in CPython.  We'll assume it is close
+            # enough for ints (which is true only for "small ints"), but
+            # for floats and longs and complexes we'll go for the option
+            # of forcing "is" to say False, like it usually does on
+            # CPython.  A fix is pending on CPython trunk
+            # (http://bugs.python.org/issue18943) but that might change
+            # the details of the semantics and so not be applied to 2.7.
+            # See the line AA below.
+
+            if (argument_values is not action.default or
+                    type(argument_values) in (float, long, complex)):  # AA
                 seen_non_default_actions.add(action)
                 for conflict_action in action_conflicts.get(action, []):
                     if conflict_action in seen_non_default_actions:

lib_pypy/_tkinter/__init__.py

 READABLE = tklib.TCL_READABLE
 WRITABLE = tklib.TCL_WRITABLE
 EXCEPTION = tklib.TCL_EXCEPTION
+DONT_WAIT = tklib.TCL_DONT_WAIT
 
 def create(screenName=None, baseName=None, className=None,
            interactive=False, wantobjects=False, wantTk=True,

lib_pypy/_tkinter/app.py

 from . import TclError
 from .tclobj import TclObject, FromObj, AsObj, TypeCache
 
+import contextlib
 import sys
+import threading
+import time
+
+
+class _DummyLock(object):
+    "A lock-like object that does not do anything"
+    def acquire(self):
+        pass
+    def release(self):
+        pass
+    def __enter__(self):
+        pass
+    def __exit__(self, *exc):
+        pass
+
 
 def varname_converter(input):
     if isinstance(input, TclObject):
     def PythonCmd(clientData, interp, argc, argv):
         self = tkffi.from_handle(clientData)
         assert self.app.interp == interp
-        try:
-            args = [tkffi.string(arg) for arg in argv[1:argc]]
-            result = self.func(*args)
-            obj = AsObj(result)
-            tklib.Tcl_SetObjResult(interp, obj)
-        except:
-            self.app.errorInCmd = True
-            self.app.exc_info = sys.exc_info()
-            return tklib.TCL_ERROR
-        else:
-            return tklib.TCL_OK
+        with self.app._tcl_lock_released():
+            try:
+                args = [tkffi.string(arg) for arg in argv[1:argc]]
+                result = self.func(*args)
+                obj = AsObj(result)
+                tklib.Tcl_SetObjResult(interp, obj)
+            except:
+                self.app.errorInCmd = True
+                self.app.exc_info = sys.exc_info()
+                return tklib.TCL_ERROR
+            else:
+                return tklib.TCL_OK
 
     @tkffi.callback("Tcl_CmdDeleteProc")
     def PythonCmdDelete(clientData):
 
 
 class TkApp(object):
+    _busywaitinterval = 0.02  # 20ms.
+
     def __new__(cls, screenName, baseName, className,
                 interactive, wantobjects, wantTk, sync, use):
         if not wantobjects:
         self.quitMainLoop = False
         self.errorInCmd = False
 
+        if not self.threaded:
+            # TCL is not thread-safe, calls needs to be serialized.
+            self._tcl_lock = threading.Lock()
+        else:
+            self._tcl_lock = _DummyLock()
+
         self._typeCache = TypeCache()
         self._commands = {}
 
         if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
             raise RuntimeError("Calling Tcl from different appartment")
 
+    @contextlib.contextmanager
+    def _tcl_lock_released(self):
+        "Context manager to temporarily release the tcl lock."
+        self._tcl_lock.release()
+        yield
+        self._tcl_lock.acquire()
+
     def loadtk(self):
         # We want to guard against calling Tk_Init() multiple times
         err = tklib.Tcl_Eval(self.interp, "info exists     tk_version")
         flags=tklib.TCL_LEAVE_ERR_MSG
         if global_only:
             flags |= tklib.TCL_GLOBAL_ONLY
-        res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
-        if not res:
-            self.raiseTclError()
-        assert self._wantobjects
-        return FromObj(self, res)
+        with self._tcl_lock:
+            res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
+            if not res:
+                self.raiseTclError()
+            assert self._wantobjects
+            return FromObj(self, res)
 
     def _setvar(self, name1, value, global_only=False):
         name1 = varname_converter(name1)
+        # XXX Acquire tcl lock???
         newval = AsObj(value)
         flags=tklib.TCL_LEAVE_ERR_MSG
         if global_only:
             flags |= tklib.TCL_GLOBAL_ONLY
-        res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
-                                  newval, flags)
-        if not res:
-            self.raiseTclError()
+        with self._tcl_lock:
+            res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
+                                      newval, flags)
+            if not res:
+                self.raiseTclError()
 
     def _unsetvar(self, name1, name2=None, global_only=False):
         name1 = varname_converter(name1)
         flags=tklib.TCL_LEAVE_ERR_MSG
         if global_only:
             flags |= tklib.TCL_GLOBAL_ONLY
-        res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
-        if res == tklib.TCL_ERROR:
-            self.raiseTclError()
+        with self._tcl_lock:
+            res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
+            if res == tklib.TCL_ERROR:
+                self.raiseTclError()
 
     def getvar(self, name1, name2=None):
         return self._var_invoke(self._getvar, name1, name2)
         if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
             raise NotImplementedError("Call from another thread")
 
-        res = tklib.Tcl_CreateCommand(
-            self.interp, cmdName, _CommandData.PythonCmd,
-            clientData, _CommandData.PythonCmdDelete)
+        with self._tcl_lock:
+            res = tklib.Tcl_CreateCommand(
+                self.interp, cmdName, _CommandData.PythonCmd,
+                clientData, _CommandData.PythonCmdDelete)
         if not res:
             raise TclError("can't create Tcl command")
 
         if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
             raise NotImplementedError("Call from another thread")
 
-        res = tklib.Tcl_DeleteCommand(self.interp, cmdName)
+        with self._tcl_lock:
+            res = tklib.Tcl_DeleteCommand(self.interp, cmdName)
         if res == -1:
             raise TclError("can't delete Tcl command")
 
                 tklib.Tcl_IncrRefCount(obj)
                 objects[i] = obj
 
-            res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
-            if res == tklib.TCL_ERROR:
-                self.raiseTclError()
-            else:
-                result = self._callResult()
+            with self._tcl_lock:
+                res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
+                if res == tklib.TCL_ERROR:
+                    self.raiseTclError()
+                else:
+                    result = self._callResult()
         finally:
             for obj in objects:
                 if obj:
 
     def eval(self, script):
         self._check_tcl_appartment()
-        res = tklib.Tcl_Eval(self.interp, script)
-        if res == tklib.TCL_ERROR:
-            self.raiseTclError()
-        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        with self._tcl_lock:
+            res = tklib.Tcl_Eval(self.interp, script)
+            if res == tklib.TCL_ERROR:
+                self.raiseTclError()
+            return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
 
     def evalfile(self, filename):
         self._check_tcl_appartment()
-        res = tklib.Tcl_EvalFile(self.interp, filename)
-        if res == tklib.TCL_ERROR:
-            self.raiseTclError()
-        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+        with self._tcl_lock:
+            res = tklib.Tcl_EvalFile(self.interp, filename)
+            if res == tklib.TCL_ERROR:
+                self.raiseTclError()
+            return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
 
     def split(self, arg):
         if isinstance(arg, tuple):
             if self.threaded:
                 result = tklib.Tcl_DoOneEvent(0)
             else:
-                raise NotImplementedError("TCL configured without threads")
+                with self._tcl_lock:
+                    result = tklib.Tcl_DoOneEvent(tklib.TCL_DONT_WAIT)
+                if result == 0:
+                    time.sleep(self._busywaitinterval)
 
             if result < 0:
                 break

lib_pypy/_tkinter/tklib.py

 # C bindings with libtcl and libtk.
 
 from cffi import FFI
+import sys
 
 tkffi = FFI()
 
 #define TCL_EVAL_DIRECT ...
 #define TCL_EVAL_GLOBAL ...
 
+#define TCL_DONT_WAIT ...
+
 typedef unsigned short Tcl_UniChar;
 typedef ... Tcl_Interp;
 typedef ...* Tcl_ThreadId;
 int Tk_GetNumMainWindows();
 """)
 
+# XXX find a better way to detect paths
+# XXX pick up CPPFLAGS and LDFLAGS and add to these paths?
+if sys.platform.startswith("openbsd"):
+    incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include']
+    linklibs = ['tk85', 'tcl85']
+    libdirs = ['/usr/local/lib', '/usr/X11R6/lib']
+else:
+    incdirs=['/usr/include/tcl']
+    linklibs=['tcl', 'tk']
+    libdirs = []
+
 tklib = tkffi.verify("""
 #include <tcl.h>
 #include <tk.h>
 char *get_tk_version() { return TK_VERSION; }
 char *get_tcl_version() { return TCL_VERSION; }
 """,
-include_dirs=['/usr/include/tcl'],
-libraries=['tcl', 'tk'],
+include_dirs=incdirs,
+libraries=linklibs,
+library_dirs = libdirs
 )

pypy/doc/whatsnew-head.rst

 .. branch: reflex-support
 .. branch: numpypy-inplace-op
 .. branch: rewritten-loop-logging
+.. branch: no-release-gil
 
 .. branch: nobold-backtrace
 Work on improving UnionError messages and stack trace displays.

pypy/interpreter/baseobjspace.py

         raise NotImplementedError("only for interp-level user subclasses "
                                   "from typedef.py")
 
-    def getname(self, space, default='?'):
+    def getname(self, space):
         try:
             return space.str_w(space.getattr(self, space.wrap('__name__')))
         except OperationError, e:
             if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError):
-                return default
+                return '?'
             raise
 
     def getaddrstring(self, space):

pypy/interpreter/function.py

                 space.abstract_isinstance_w(w_firstarg, self.w_class)):
             pass  # ok
         else:
-            clsdescr = self.w_class.getname(space, "")
-            if clsdescr:
+            clsdescr = self.w_class.getname(space)
+            if clsdescr and clsdescr != '?':
                 clsdescr += " instance"
             else:
                 clsdescr = "instance"
             if w_firstarg is None:
                 instdescr = "nothing"
             else:
-                instname = space.abstract_getclass(w_firstarg).getname(space,
-                                                                       "")
-                if instname:
+                instname = space.abstract_getclass(w_firstarg).getname(space)
+                if instname and instname != '?':
                     instdescr = instname + " instance"
                 else:
                     instdescr = "instance"

pypy/interpreter/test/test_argument.py

 
     def type(self, obj):
         class Type:
-            def getname(self, space, default='?'):
+            def getname(self, space):
                 return type(obj).__name__
         return Type()
 

pypy/module/__pypy__/interp_time.py

 
     c_clock_gettime = rffi.llexternal("clock_gettime",
         [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
-        compilation_info=CConfig._compilation_info_, threadsafe=False
+        compilation_info=CConfig._compilation_info_, releasegil=False
     )
     c_clock_getres = rffi.llexternal("clock_getres",
         [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
-        compilation_info=CConfig._compilation_info_, threadsafe=False
+        compilation_info=CConfig._compilation_info_, releasegil=False
     )
 
     @unwrap_spec(clk_id="c_int")

pypy/module/_cffi_backend/ccallback.py

         if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
             raise OperationError(space.w_SystemError,
                 space.wrap("libffi failed to build this callback"))
+        #
+        # We must setup the GIL here, in case the callback is invoked in
+        # some other non-Pythonic thread.  This is the same as cffi on
+        # CPython.
+        if space.config.translation.thread:
+            from pypy.module.thread.os_thread import setup_threads
+            setup_threads(space)
 
     def get_closure(self):
         return rffi.cast(clibffi.FFI_CLOSUREP, self._cdata)

pypy/module/_minimal_curses/fficurses.py

 def try_ldflags():
     yield ExternalCompilationInfo(libraries=['curses'])
     yield ExternalCompilationInfo(libraries=['curses', 'tinfo'])
+    yield ExternalCompilationInfo(libraries=['ncurses'])
+    yield ExternalCompilationInfo(libraries=['ncurses'],
+                                  library_dirs=['/usr/lib64'])
 
 def try_tools():
     try:

pypy/module/_multiprocessing/interp_semaphore.py

         'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR],
         rwin32.HANDLE)
     _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE],
-        rwin32.BOOL, threadsafe=False)
+        rwin32.BOOL, releasegil=False)
     _ReleaseSemaphore = rwin32.winexternal(
         'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP],
         rwin32.BOOL)
     _sem_open = external('sem_open',
                          [rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT],
                          SEM_T)
-    # tread sem_close as not threadsafe for now to be able to use the __del__
-    _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False)
+    # sem_close is releasegil=False to be able to use it in the __del__
+    _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False)
     _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT)
     _sem_wait = external('sem_wait', [SEM_T], rffi.INT)
     _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT)

pypy/module/_weakref/interp__weakref.py

             state = '; dead'
         else:
             typename = space.type(w_obj).getname(space)
-            objname = w_obj.getname(space, '')
-            if objname:
+            objname = w_obj.getname(space)
+            if objname and objname != '?':
                 state = "; to '%s' (%s)" % (typename, objname)
             else:
                 state = "; to '%s'" % (typename,)

pypy/module/bz2/interp_bz2.py

 BZ2_bzCompressInit = external('BZ2_bzCompressInit', [bz_stream, rffi.INT,
                               rffi.INT, rffi.INT], rffi.INT)
 BZ2_bzCompressEnd = external('BZ2_bzCompressEnd', [bz_stream], rffi.INT,
-                             threadsafe=False)
+                             releasegil=False)
 BZ2_bzCompress = external('BZ2_bzCompress', [bz_stream, rffi.INT], rffi.INT)
 BZ2_bzDecompressInit = external('BZ2_bzDecompressInit', [bz_stream, rffi.INT,
                                                          rffi.INT], rffi.INT)
 BZ2_bzDecompressEnd = external('BZ2_bzDecompressEnd', [bz_stream], rffi.INT,
-                               threadsafe=False)
+                               releasegil=False)
 BZ2_bzDecompress = external('BZ2_bzDecompress', [bz_stream], rffi.INT)
 
 def _catch_bz2_error(space, bzerror):

pypy/module/cppyy/capi/builtin_capi.py

 _c_num_scopes = rffi.llexternal(
     "cppyy_num_scopes",
     [C_SCOPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_num_scopes(space, cppscope):
     return _c_num_scopes(cppscope.handle)
 _c_resolve_name = rffi.llexternal(
     "cppyy_resolve_name",
     [rffi.CCHARP], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_resolve_name(space, name):
     return charp2str_free(space, _c_resolve_name(name))
 _c_get_scope_opaque = rffi.llexternal(
     "cppyy_get_scope",
     [rffi.CCHARP], C_SCOPE,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_get_scope_opaque(space, name):
     return _c_get_scope_opaque(name)
 _c_get_template = rffi.llexternal(
     "cppyy_get_template",
     [rffi.CCHARP], C_TYPE,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_get_template(space, name):
     return _c_get_template(name)
 _c_actual_class = rffi.llexternal(
     "cppyy_actual_class",
     [C_TYPE, C_OBJECT], C_TYPE,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_actual_class(space, cppclass, cppobj):
     return _c_actual_class(cppclass.handle, cppobj)
 _c_allocate = rffi.llexternal(
     "cppyy_allocate",
     [C_TYPE], C_OBJECT,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci)
 def c_allocate(space, cppclass):
     return _c_allocate(cppclass.handle)
 _c_deallocate = rffi.llexternal(
     "cppyy_deallocate",
     [C_TYPE, C_OBJECT], lltype.Void,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci)
 def c_deallocate(space, cppclass, cppobject):
     _c_deallocate(cppclass.handle, cppobject)
 _c_destruct = rffi.llexternal(
     "cppyy_destruct",
     [C_TYPE, C_OBJECT], lltype.Void,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_destruct(space, cppclass, cppobject):
     _c_destruct(cppclass.handle, cppobject)
 _c_call_v = rffi.llexternal(
     "cppyy_call_v",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_v(space, cppmethod, cppobject, nargs, args):
     _c_call_v(cppmethod, cppobject, nargs, args)
 _c_call_b = rffi.llexternal(
     "cppyy_call_b",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.UCHAR,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_b(space, cppmethod, cppobject, nargs, args):
     return _c_call_b(cppmethod, cppobject, nargs, args)
 _c_call_c = rffi.llexternal(
     "cppyy_call_c",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CHAR,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_c(space, cppmethod, cppobject, nargs, args):
     return _c_call_c(cppmethod, cppobject, nargs, args)
 _c_call_h = rffi.llexternal(
     "cppyy_call_h",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.SHORT,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_h(space, cppmethod, cppobject, nargs, args):
     return _c_call_h(cppmethod, cppobject, nargs, args)
 _c_call_i = rffi.llexternal(
     "cppyy_call_i",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.INT,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_i(space, cppmethod, cppobject, nargs, args):
     return _c_call_i(cppmethod, cppobject, nargs, args)
 _c_call_l = rffi.llexternal(
     "cppyy_call_l",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONG,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_l(space, cppmethod, cppobject, nargs, args):
     return _c_call_l(cppmethod, cppobject, nargs, args)
 _c_call_ll = rffi.llexternal(
     "cppyy_call_ll",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.LONGLONG,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_ll(space, cppmethod, cppobject, nargs, args):
     return _c_call_ll(cppmethod, cppobject, nargs, args)
 _c_call_f = rffi.llexternal(
     "cppyy_call_f",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.FLOAT,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_f(space, cppmethod, cppobject, nargs, args):
     return _c_call_f(cppmethod, cppobject, nargs, args)
 _c_call_d = rffi.llexternal(
     "cppyy_call_d",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.DOUBLE,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_d(space, cppmethod, cppobject, nargs, args):
     return _c_call_d(cppmethod, cppobject, nargs, args)
 _c_call_r = rffi.llexternal(
     "cppyy_call_r",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.VOIDP,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_r(space, cppmethod, cppobject, nargs, args):
     return _c_call_r(cppmethod, cppobject, nargs, args)
 _c_call_s = rffi.llexternal(
     "cppyy_call_s",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_s(space, cppmethod, cppobject, nargs, args):
     return _c_call_s(cppmethod, cppobject, nargs, args)
 _c_constructor = rffi.llexternal(
     "cppyy_constructor",
     [C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_constructor(space, cppmethod, cppobject, nargs, args):
     return _c_constructor(cppmethod, cppobject, nargs, args)
 _c_call_o = rffi.llexternal(
     "cppyy_call_o",
     [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, C_TYPE], rffi.LONG,
-    threadsafe=ts_call,
+    releasegil=ts_call,
     compilation_info=backend.eci)
 def c_call_o(space, method, cppobj, nargs, args, cppclass):
     return _c_call_o(method, cppobj, nargs, args, cppclass.handle)
 _c_get_methptr_getter = rffi.llexternal(
     "cppyy_get_methptr_getter",
     [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci,
     elidable_function=True)
 def c_get_methptr_getter(space, cppscope, index):
 _c_allocate_function_args = rffi.llexternal(
     "cppyy_allocate_function_args",
     [rffi.SIZE_T], rffi.VOIDP,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci)
 def c_allocate_function_args(space, size):
     return _c_allocate_function_args(size)
 _c_deallocate_function_args = rffi.llexternal(
     "cppyy_deallocate_function_args",
     [rffi.VOIDP], lltype.Void,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci)
 def c_deallocate_function_args(space, args):
     _c_deallocate_function_args(args)
 _c_function_arg_sizeof = rffi.llexternal(
     "cppyy_function_arg_sizeof",
     [], rffi.SIZE_T,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci,
     elidable_function=True)
 def c_function_arg_sizeof(space):
 _c_function_arg_typeoffset = rffi.llexternal(
     "cppyy_function_arg_typeoffset",
     [], rffi.SIZE_T,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci,
     elidable_function=True)
 def c_function_arg_typeoffset(space):
 _c_is_namespace = rffi.llexternal(
     "cppyy_is_namespace",
     [C_SCOPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_namespace(space, scope):
     return _c_is_namespace(scope)
 _c_is_enum = rffi.llexternal(
     "cppyy_is_enum",
     [rffi.CCHARP], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_enum(space, name):
     return _c_is_enum(name)
 _c_final_name = rffi.llexternal(
     "cppyy_final_name",
     [C_TYPE], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_final_name(space, cpptype):
     return charp2str_free(space, _c_final_name(cpptype))
 _c_scoped_final_name = rffi.llexternal(
     "cppyy_scoped_final_name",
     [C_TYPE], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_scoped_final_name(space, cpptype):
     return charp2str_free(space, _c_scoped_final_name(cpptype))
 _c_has_complex_hierarchy = rffi.llexternal(
     "cppyy_has_complex_hierarchy",
     [C_TYPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_has_complex_hierarchy(space, cpptype):
     return _c_has_complex_hierarchy(cpptype)
 _c_num_bases = rffi.llexternal(
     "cppyy_num_bases",
     [C_TYPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_num_bases(space, cppclass):
     return _c_num_bases(cppclass.handle)
 _c_base_name = rffi.llexternal(
     "cppyy_base_name",
     [C_TYPE, rffi.INT], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_base_name(space, cppclass, base_index):
     return charp2str_free(space, _c_base_name(cppclass.handle, base_index))
 _c_is_subtype = rffi.llexternal(
     "cppyy_is_subtype",
     [C_TYPE, C_TYPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci,
     elidable_function=True)
 @jit.elidable_promote('2')
 _c_base_offset = rffi.llexternal(
     "cppyy_base_offset",
     [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci,
     elidable_function=True)
 @jit.elidable_promote('1,2,4')
 _c_num_methods = rffi.llexternal(
     "cppyy_num_methods",
     [C_SCOPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_num_methods(space, cppscope):
     return _c_num_methods(cppscope.handle)
 _c_method_index_at = rffi.llexternal(
     "cppyy_method_index_at",
     [C_SCOPE, rffi.INT], C_INDEX,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_index_at(space, cppscope, imethod):
     return _c_method_index_at(cppscope.handle, imethod)
 _c_method_indices_from_name = rffi.llexternal(
     "cppyy_method_indices_from_name",
     [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_indices_from_name(space, cppscope, name):
     indices = _c_method_indices_from_name(cppscope.handle, name)
 _c_method_name = rffi.llexternal(
     "cppyy_method_name",
     [C_SCOPE, C_INDEX], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_name(space, cppscope, index):
     return charp2str_free(space, _c_method_name(cppscope.handle, index))
 _c_method_result_type = rffi.llexternal(
     "cppyy_method_result_type",
     [C_SCOPE, C_INDEX], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_result_type(space, cppscope, index):
     return charp2str_free(space, _c_method_result_type(cppscope.handle, index))
 _c_method_num_args = rffi.llexternal(
     "cppyy_method_num_args",
     [C_SCOPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_num_args(space, cppscope, index):
     return _c_method_num_args(cppscope.handle, index)
 _c_method_req_args = rffi.llexternal(
     "cppyy_method_req_args",
     [C_SCOPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_req_args(space, cppscope, index):
     return _c_method_req_args(cppscope.handle, index)
 _c_method_arg_type = rffi.llexternal(
     "cppyy_method_arg_type",
     [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_arg_type(space, cppscope, index, arg_index):
     return charp2str_free(space, _c_method_arg_type(cppscope.handle, index, arg_index))
 _c_method_arg_default = rffi.llexternal(
     "cppyy_method_arg_default",
     [C_SCOPE, C_INDEX, rffi.INT], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_arg_default(space, cppscope, index, arg_index):
     return charp2str_free(space, _c_method_arg_default(cppscope.handle, index, arg_index))
 _c_method_signature = rffi.llexternal(
     "cppyy_method_signature",
     [C_SCOPE, C_INDEX], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_signature(space, cppscope, index):
     return charp2str_free(space, _c_method_signature(cppscope.handle, index))
 _c_method_is_template = rffi.llexternal(
     "cppyy_method_is_template",
     [C_SCOPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_method_is_template(space, cppscope, index):
     return _c_method_is_template(cppscope.handle, index)
 _c_method_num_template_args = rffi.llexternal(
     "cppyy_method_num_template_args",
     [C_SCOPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 _c_method_template_arg_name = rffi.llexternal(
     "cppyy_method_template_arg_name",
     [C_SCOPE, C_INDEX, C_INDEX], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_template_args(space, cppscope, index):
     nargs = _c_method_num_template_args(cppscope.handle, index)
 _c_get_method = rffi.llexternal(
     "cppyy_get_method",
     [C_SCOPE, C_INDEX], C_METHOD,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_get_method(space, cppscope, index):
     return _c_get_method(cppscope.handle, index)
 _c_get_global_operator = rffi.llexternal(
     "cppyy_get_global_operator",
     [C_SCOPE, C_SCOPE, C_SCOPE, rffi.CCHARP], WLAVC_INDEX,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_get_global_operator(space, nss, lc, rc, op):
     if nss is not None:
 _c_is_constructor = rffi.llexternal(
     "cppyy_is_constructor",
     [C_TYPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_constructor(space, cppclass, index):
     return _c_is_constructor(cppclass.handle, index)
 _c_is_staticmethod = rffi.llexternal(
     "cppyy_is_staticmethod",
     [C_TYPE, C_INDEX], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_staticmethod(space, cppclass, index):
     return _c_is_staticmethod(cppclass.handle, index)
 _c_num_datamembers = rffi.llexternal(
     "cppyy_num_datamembers",
     [C_SCOPE], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_num_datamembers(space, cppscope):
     return _c_num_datamembers(cppscope.handle)
 _c_datamember_name = rffi.llexternal(
     "cppyy_datamember_name",
     [C_SCOPE, rffi.INT], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_datamember_name(space, cppscope, datamember_index):
     return charp2str_free(space, _c_datamember_name(cppscope.handle, datamember_index))
 _c_datamember_type = rffi.llexternal(
     "cppyy_datamember_type",
     [C_SCOPE, rffi.INT], rffi.CCHARP,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_datamember_type(space, cppscope, datamember_index):
     return charp2str_free(space, _c_datamember_type(cppscope.handle, datamember_index))
 _c_datamember_offset = rffi.llexternal(
     "cppyy_datamember_offset",
     [C_SCOPE, rffi.INT], rffi.SIZE_T,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_datamember_offset(space, cppscope, datamember_index):
     return _c_datamember_offset(cppscope.handle, datamember_index)
 _c_datamember_index = rffi.llexternal(
     "cppyy_datamember_index",
     [C_SCOPE, rffi.CCHARP], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_datamember_index(space, cppscope, name):
     return _c_datamember_index(cppscope.handle, name)
 _c_is_publicdata = rffi.llexternal(
     "cppyy_is_publicdata",
     [C_SCOPE, rffi.INT], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_publicdata(space, cppscope, datamember_index):
     return _c_is_publicdata(cppscope.handle, datamember_index)
 _c_is_staticdata = rffi.llexternal(
     "cppyy_is_staticdata",
     [C_SCOPE, rffi.INT], rffi.INT,
-    threadsafe=ts_reflect,
+    releasegil=ts_reflect,
     compilation_info=backend.eci)
 def c_is_staticdata(space, cppscope, datamember_index):
     return _c_is_staticdata(cppscope.handle, datamember_index)
 _c_strtoll = rffi.llexternal(
     "cppyy_strtoll",
     [rffi.CCHARP], rffi.LONGLONG,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=backend.eci)
 def c_strtoll(space, svalue):
     return _c_strtoll(svalue)
 _c_strtoull = rffi.llexternal(
     "cppyy_strtoull",
     [rffi.CCHARP], rffi.ULONGLONG,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=backend.eci)
 def c_strtoull(space, svalue):
     return _c_strtoull(svalue)
 c_free = rffi.llexternal(
     "cppyy_free",
     [rffi.VOIDP], lltype.Void,
-    threadsafe=ts_memory,
+    releasegil=ts_memory,
     compilation_info=backend.eci)
 
 def charp2str_free(space, charp):
 _c_charp2stdstring = rffi.llexternal(
     "cppyy_charp2stdstring",
     [rffi.CCHARP], C_OBJECT,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=backend.eci)
 def c_charp2stdstring(space, svalue):
     charp = rffi.str2charp(svalue)
 _c_stdstring2stdstring = rffi.llexternal(
     "cppyy_stdstring2stdstring",
     [C_OBJECT], C_OBJECT,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=backend.eci)
 def c_stdstring2stdstring(space, cppobject):
     return _c_stdstring2stdstring(cppobject)

pypy/module/cppyy/capi/cint_capi.py

 _c_load_dictionary = rffi.llexternal(
     "cppyy_load_dictionary",
     [rffi.CCHARP], rdynload.DLLHANDLE,
-    threadsafe=False,
+    releasegil=False,
     compilation_info=eci)
 
 def c_load_dictionary(name):
 _c_charp2TString = rffi.llexternal(
     "cppyy_charp2TString",
     [rffi.CCHARP], C_OBJECT,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=eci)
 def c_charp2TString(space, svalue):
     charp = rffi.str2charp(svalue)
 _c_TString2TString = rffi.llexternal(
     "cppyy_TString2TString",
     [C_OBJECT], C_OBJECT,
-    threadsafe=ts_helper,
+    releasegil=ts_helper,
     compilation_info=eci)
 def c_TString2TString(space, cppobject):
     return _c_TString2TString(cppobject)
 _tfn_install = rffi.llexternal(
     "cppyy_tfn_install",
     [rffi.CCHARP, rffi.INT], rffi.LONG,
-    threadsafe=False,
+    releasegil=False,
     compilation_info=eci)
 
 @unwrap_spec(args_w='args_w')
 _ttree_Branch = rffi.llexternal(
     "cppyy_ttree_Branch",
     [rffi.VOIDP, rffi.CCHARP, rffi.CCHARP, rffi.VOIDP, rffi.INT, rffi.INT], rffi.LONG,
-    threadsafe=False,
+    releasegil=False,
     compilation_info=eci)
 
 @unwrap_spec(args_w='args_w')
 c_ttree_GetEntry = rffi.llexternal(
     "cppyy_ttree_GetEntry",
     [rffi.VOIDP, rffi.LONGLONG], rffi.LONGLONG,
-    threadsafe=False,
+    releasegil=False,
     compilation_info=eci)
 
 @unwrap_spec(args_w='args_w')

pypy/module/crypt/interp_crypt.py

 else:
     eci = ExternalCompilationInfo(libraries=['crypt'])
 c_crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP], rffi.CCHARP,
-                          compilation_info=eci, threadsafe=False)
+                          compilation_info=eci, releasegil=False)
 
 @unwrap_spec(word=str, salt=str)
 def crypt(space, word, salt):

pypy/module/micronumpy/test/test_dtypes.py

 
     def test_unicode_boxes(self):
         from numpypy import unicode_
-        assert isinstance(unicode_(3), unicode)
+        try:
+            u = unicode_(3)
+        except NotImplementedError, e:
+            if e.message.find('not supported yet') >= 0:
+                skip('unicode box not implemented')
+        else:
+            assert isinstance(u, unicode)
 
     def test_character_dtype(self):
         from numpypy import array, character

pypy/module/pyexpat/interp_pyexpat.py

 XML_ParserCreateNS = expat_external(
     'XML_ParserCreateNS', [rffi.CCHARP, rffi.CHAR], XML_Parser)
 XML_ParserFree = expat_external(
-    'XML_ParserFree', [XML_Parser], lltype.Void, threadsafe=False)
+    'XML_ParserFree', [XML_Parser], lltype.Void, releasegil=False)
 XML_SetUserData = expat_external(
     'XML_SetUserData', [XML_Parser, rffi.VOIDP], lltype.Void)
 def XML_GetUserData(parser):

pypy/module/pypyjit/policy.py

                        'posix', '_socket', '_sre', '_lsprof', '_weakref',
                        '__pypy__', 'cStringIO', '_collections', 'struct',
                        'mmap', 'marshal', '_codecs', 'rctime', 'cppyy',
-                       '_cffi_backend', 'pyexpat', '_continuation', '_io']:
+                       '_cffi_backend', 'pyexpat', '_continuation', '_io',
+                       'thread']:
             if modname == 'pypyjit' and 'interp_resop' in rest:
                 return False
             return True

pypy/module/pypyjit/test/test_policy.py

     from pypy.module._io.interp_bytesio import W_BytesIO
     assert pypypolicy.look_inside_function(W_BytesIO.seek_w.im_func)
 
+def test_thread():
+    from pypy.module.thread.os_lock import Lock
+    assert pypypolicy.look_inside_function(Lock.descr_lock_acquire.im_func)
+
 def test_pypy_module():
     from pypy.module._collections.interp_deque import W_Deque
     from pypy.module._random.interp_random import W_Random

pypy/module/pypyjit/test_pypy_c/test_thread.py

             i58 = arraylen_gc(p43, descr=...)
             jump(..., descr=...)
         """)
+
+    def test_lock_acquire_release(self):
+        def main(n):
+            import threading
+            lock = threading.Lock()
+            while n > 0:
+                with lock:
+                    n -= 1
+        log = self.run(main, [500])
+        assert log.result == main(500)
+        loop, = log.loops_by_filename(self.filepath)
+        assert loop.match("""
+        i58 = int_gt(i43, 0)
+        guard_true(i58, descr=<Guard0x10483adb8>)
+        p59 = getfield_gc(p15, descr=<FieldP pypy.module.thread.os_lock.Lock.inst_lock 8>)
+        i60 = getfield_gc(p59, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+        p61 = force_token()
+        setfield_gc(p0, p61, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+        i62 = call_release_gil(4312440032, i60, 1, descr=<Calli 4 ii EF=6>)
+        guard_not_forced(descr=<Guard0x103f3cca0>)
+        guard_no_exception(descr=<Guard0x10483ad40>)
+        i63 = int_is_true(i62)
+        guard_true(i63, descr=<Guard0x10483acc8>)
+        i64 = int_sub(i43, 1)
+        guard_not_invalidated(descr=<Guard0x10483ac50>)
+        p66 = getfield_gc(p15, descr=<FieldP pypy.module.thread.os_lock.Lock.inst_lock 8>)
+        i67 = getfield_gc(p66, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+        p68 = force_token()
+        setfield_gc(p0, p68, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+        i69 = call_release_gil(4312440032, i67, 0, descr=<Calli 4 ii EF=6>)
+        guard_not_forced(descr=<Guard0x103f3cc20>)
+        guard_no_exception(descr=<Guard0x10483aae8>)
+        i70 = int_is_true(i69)
+        guard_false(i70, descr=<Guard0x10483aa70>)
+        i71 = getfield_gc(p66, descr=<FieldU rpython.rlib.rthread.Lock.inst__lock 8>)
+        p72 = force_token()
+        setfield_gc(p0, p72, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 24>)
+        call_release_gil(4312441056, i71, descr=<Callv 0 i EF=6>)
+        guard_not_forced(descr=<Guard0x103f3cba0>)
+        guard_no_exception(descr=<Guard0x10483a9f8>)
+        guard_not_invalidated(descr=<Guard0x10483a980>)
+        --TICK--
+        jump(..., descr=TargetToken(4361239720))
+        """)

pypy/module/rctime/interp_time.py

     return rffi.llexternal(name, args, result,
                            compilation_info=eci,
                            calling_conv=calling_conv,
-                           threadsafe=False)
+                           releasegil=False)
 
 if _POSIX:
     cConfig.timeval.__name__ = "_timeval"

pypy/module/test_lib_pypy/test_resource.py

 from lib_pypy.ctypes_config_cache import rebuild
 from pypy.module.test_lib_pypy.support import import_lib_pypy
 
+import os
+if os.name != 'posix':
+    skip('resource.h only available on unix')
 
 class AppTestResource:
 

pypy/module/thread/test/test_thread.py

             skip("this OS supports too many threads to check (> 1000)")
         lock = thread.allocate_lock()
         lock.acquire()
+        count = [0]
         def f():
+            count[0] += 1
             lock.acquire()
             lock.release()
+            count[0] -= 1
         try:
             try:
                 for i in range(1000):
             finally:
                 lock.release()
                 # wait a bit to allow most threads to finish now
-                self.busywait(2.0)
+                while count[0] > 10:
+                    print count[0]     # <- releases the GIL
+                print "ok."
         except (thread.error, MemoryError):
             pass
         else:
             raise Exception("could unexpectedly start 1000 threads")
+        # safety: check that we can start a new thread here
+        thread.start_new_thread(lambda: None, ())
 
     def test_stack_size(self):
         import thread

pypy/objspace/descroperation.py

         if num1 != num2:
             lt = num1      # if obj1 is a number, it is Lower Than obj2
         else:
-            name1 = w_typ1.getname(space, "")
-            name2 = w_typ2.getname(space, "")
+            name1 = w_typ1.getname(space)
+            name2 = w_typ2.getname(space)
             if name1 != name2:
                 lt = name1 < name2
             else:

pypy/objspace/std/typeobject.py

         else:
             return w_self.name
 
+    def getname(w_self, space):
+        name = w_self.name
+        if name is None:
+            name = '?'
+        return name
+
     def add_subclass(w_self, w_subclass):
         space = w_self.space
         if not space.config.translation.rweakref:

rpython/jit/backend/arm/assembler.py

 from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.jit.backend.arm import callbuilder
+from rpython.rtyper.lltypesystem.lloperation import llop
 
 class AssemblerARM(ResOpAssembler):
 
 
 
 def not_implemented(msg):
-    os.write(2, '[ARM/asm] %s\n' % msg)
+    msg = '[ARM/asm] %s\n' % msg
+    if we_are_translated():
+        llop.debug_print(lltype.Void, msg)
     raise NotImplementedError(msg)
 
 

rpython/jit/backend/arm/runner.py

     def finish_once(self):
         self.assembler.finish_once()
 
-    def compile_loop(self, logger, inputargs, operations, looptoken,
-                                                    log=True, name=''):
+    def compile_loop(self, inputargs, operations, looptoken,
+                     log=True, name='', logger=None):
         return self.assembler.assemble_loop(logger, name, inputargs, operations,
                                             looptoken, log=log)
 
-    def compile_bridge(self, logger, faildescr, inputargs, operations,
-                                       original_loop_token, log=True):
+    def compile_bridge(self, faildescr, inputargs, operations,
+                       original_loop_token, log=True, logger=None):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
         return self.assembler.assemble_bridge(logger, faildescr, inputargs,

rpython/jit/backend/arm/test/test_generated.py

         looptoken = JitCellToken()
         operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
         operations[3].setfailargs([v9, v6, v10, v2, v8, v5, v1, v4])
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 0
         operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
         operations[-1].setfailargs([v7, v1, v2])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 105
         operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6])
 
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
         operations[5].setfailargs([])
         operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == -29
         looptoken = JitCellToken()
         operations[5].setfailargs([])
         operations[-1].setfailargs([v1, v4, v10, v8, v7, v3])
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 1073741824
         operations[9].setfailargs([v10, v13])
         operations[-1].setfailargs([v8, v10, v6, v3, v2, v9])
         args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12]
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
         assert cpu.get_int_value(deadframe, 0) == 12
         operations[8].setfailargs([v5, v9])
         operations[-1].setfailargs([v4, v10, v6, v5, v9, v7])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
         operations[-2].setfailargs([v9, v4, v10, v11, v14])
         operations[-1].setfailargs([v10, v8, v1, v6, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
         operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8])
         operations[-1].setfailargs([v1, v2, v9])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
         operations[2].setfailargs([v10, v3, v6, v11, v9, v2])
         operations[-1].setfailargs([v8, v2, v10, v6, v7, v9, v5, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
         operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9])
         operations[4].setfailargs([v14])
         looptoken = JitCellToken()
-        cpu.compile_loop(None, inputargs, operations, looptoken)
+        cpu.compile_loop(inputargs, operations, looptoken)
         args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1

rpython/jit/backend/arm/test/test_regalloc2.py

     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(None, inputargs, operations, looptoken)
+    cpu.compile_loop(inputargs, operations, looptoken)
     deadframe = cpu.execute_token(looptoken, 9)
     assert cpu.get_int_value(deadframe, 0) == (9 >> 3)
     assert cpu.get_int_value(deadframe, 1) == (~18)
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(None, inputargs, operations, looptoken)
+    cpu.compile_loop(inputargs, operations, looptoken)
     deadframe = cpu.execute_token(looptoken, -10)
     assert cpu.get_int_value(deadframe, 0) == 0
     assert cpu.get_int_value(deadframe, 1) == -1000
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(None, inputargs, operations, looptoken)
+    cpu.compile_loop(inputargs, operations, looptoken)
     args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26]
     deadframe = cpu.execute_token(looptoken, *args)
     assert cpu.get_int_value(deadframe, 0) == 0
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(None, inputargs, operations, looptoken)
+    cpu.compile_loop(inputargs, operations, looptoken)
     args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8]
     deadframe = cpu.execute_token(looptoken, *args)
     assert cpu.get_int_value(deadframe, 0) == 0

rpython/jit/backend/arm/test/test_runner.py

             ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)),
             ]
         operations[-2].setfailargs(out)
-        cpu.compile_loop(None, inp, operations, looptoken)
+        cpu.compile_loop(inp, operations, looptoken)
         args = [i for i in range(1, 15)]
         deadframe = self.cpu.execute_token(looptoken, *args)
         output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)]
         i1 = int_sub(i0, 1)
         finish(i1)
         ''')
-        self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2)
-        self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3)
-        self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1)
+        self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2)
+        self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3)
+        self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1)
         df = self.cpu.execute_token(lt1, 10)
         assert self.cpu.get_int_value(df, 0) == 7
 
             ops = "".join(ops)
             loop = parse(ops)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
+            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
             ARGS = [lltype.Signed] * numargs
             RES = lltype.Signed
             args = [i+1 for i in range(numargs)]
         try:
             self.cpu.assembler.set_debug(True)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken)
+            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]
         faildescr = BasicFailDescr(2)
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
-        info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
+        info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         ops2 = """
         [i0, f1]
         i1 = same_as(i0)
         """
         loop2 = parse(ops2, self.cpu, namespace=locals())
         looptoken2 = JitCellToken()
-        info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2)
+        info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2)
 
         deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5))
         res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0))

rpython/jit/backend/llgraph/runner.py

         self.stats = stats or MiniStats()
         self.vinfo_for_tests = kwds.get('vinfo_for_tests', None)
 
-    def compile_loop(self, logger, inputargs, operations, looptoken, log=True,
-                     name=''):
+    def compile_loop(self, inputargs, operations, looptoken, log=True,
+                     name='', logger=None):
         clt = model.CompiledLoopToken(self, looptoken.number)
         looptoken.compiled_loop_token = clt
         lltrace = LLTrace(inputargs, operations)
         clt._llgraph_alltraces = [lltrace]
         self._record_labels(lltrace)
 
-    def compile_bridge(self, logger, faildescr, inputargs, operations,
-                       original_loop_token, log=True):
+    def compile_bridge(self, faildescr, inputargs, operations,
+                       original_loop_token, log=True, logger=None):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
         lltrace = LLTrace(inputargs, operations)
 
     bh_setfield_raw   = bh_setfield_gc
     bh_setfield_raw_i = bh_setfield_raw
-    bh_setfield_raw_r = bh_setfield_raw
     bh_setfield_raw_f = bh_setfield_raw
 
     def bh_arraylen_gc(self, a, descr):

rpython/jit/backend/llsupport/gc.py

         return True
     def initialize(self):
         pass
-    def do_write_barrier(self, gcref_struct, gcref_newptr):
-        pass
     def can_use_nursery_malloc(self, size):
         return False
     def has_write_barrier_class(self):
     def malloc_jitframe(self, frame_info):
         """ Allocate a new frame, overwritten by tests
         """
-        frame = jitframe.JITFRAME.allocate(frame_info)
-        llop.gc_writebarrier(lltype.Void, frame)
-        return frame
+        return jitframe.JITFRAME.allocate(frame_info)
 
 class JitFrameDescrs:
     def _freeze_(self):
         hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR)
         hdr.tid = tid
 
-    def do_write_barrier(self, gcref_struct, gcref_newptr):
-        hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct)
-        hdr_addr -= self.gcheaderbuilder.size_gc_header
-        hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR)
-        if hdr.tid & self.GCClass.JIT_WB_IF_FLAG:
-            # get a pointer to the 'remember_young_pointer' function from
-            # the GC, and call it immediately
-            llop1 = self.llop1
-            funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
-            funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
-
     def can_use_nursery_malloc(self, size):
         return size < self.max_size_of_young_obj
 

rpython/jit/backend/llsupport/llmodel.py

                     else:
                         assert kind == history.REF
                         self.set_ref_value(ll_frame, num, arg)
+                llop.gc_writebarrier(lltype.Void, ll_frame)
                 ll_frame = func(ll_frame)
             finally:
                 if not self.translate_support_code:
 
     @specialize.argtype(1)
     def read_int_at_mem(self, gcref, ofs, size, sign):
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
         for STYPE, UTYPE, itemsize in unroll_basic_sizes:
             if size == itemsize:
                 if sign:
-                    items = rffi.cast(rffi.CArrayPtr(STYPE), items)
-                    val = items[0]
+                    val = llop.raw_load(STYPE, gcref, ofs)
                     val = rffi.cast(lltype.Signed, val)
                 else:
-                    items = rffi.cast(rffi.CArrayPtr(UTYPE), items)
-                    val = items[0]
+                    val = llop.raw_load(UTYPE, gcref, ofs)
                     val = rffi.cast(lltype.Signed, val)
-                # --- end of GC unsafe code ---
                 return val
         else:
             raise NotImplementedError("size = %d" % size)
 
     @specialize.argtype(1)
-    def write_int_at_mem(self, gcref, ofs, size, sign, newvalue):
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
+    def write_int_at_mem(self, gcref, ofs, size, newvalue):
         for TYPE, _, itemsize in unroll_basic_sizes:
             if size == itemsize:
-                items = rffi.cast(rffi.CArrayPtr(TYPE), items)
-                items[0] = rffi.cast(TYPE, newvalue)
-                # --- end of GC unsafe code ---
+                newvalue = rffi.cast(TYPE, newvalue)
+                llop.raw_store(lltype.Void, gcref, ofs, newvalue)
                 return
         else:
             raise NotImplementedError("size = %d" % size)
 
+    @specialize.argtype(1)
     def read_ref_at_mem(self, gcref, ofs):
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
-        pval = self._cast_int_to_gcref(items[0])
-        # --- end of GC unsafe code ---
-        return pval
+        return llop.raw_load(llmemory.GCREF, gcref, ofs)
 
+    # non-@specialized: must only be called with llmemory.GCREF
     def write_ref_at_mem(self, gcref, ofs, newvalue):
-        self.gc_ll_descr.do_write_barrier(gcref, newvalue)
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
-        items[0] = self.cast_gcref_to_int(newvalue)
-        # --- end of GC unsafe code ---
+        llop.raw_store(lltype.Void, gcref, ofs, newvalue)
+        # the write barrier is implied above
 
     @specialize.argtype(1)
     def read_float_at_mem(self, gcref, ofs):
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
-        fval = items[0]
-        # --- end of GC unsafe code ---
-        return fval
+        return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs)
 
     @specialize.argtype(1)
     def write_float_at_mem(self, gcref, ofs, newvalue):
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
-        items[0] = newvalue
-        # --- end of GC unsafe code ---
+        llop.raw_store(lltype.Void, gcref, ofs, newvalue)
 
     # ____________________________________________________________
 
         """
         descr = self.gc_ll_descr.getframedescrs(self).arraydescr
         ofs = self.unpack_arraydescr(descr)
-        self.write_int_at_mem(newframe, ofs + index, WORD, 1, value)
+        self.write_int_at_mem(newframe, ofs + index, WORD, value)
 
     def set_ref_value(self, newframe, index, value):
         descr = self.gc_ll_descr.getframedescrs(self).arraydescr
     def bh_arraylen_gc(self, array, arraydescr):
         assert isinstance(arraydescr, ArrayDescr)
         ofs = arraydescr.lendescr.offset
-        return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD]
+        return self.read_int_at_mem(array, ofs, WORD, 1)
 
     @specialize.argtype(1)
     def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr):
     @specialize.argtype(1)
     def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr):
         ofs, size, sign = self.unpack_arraydescr_size(arraydescr)
-        self.write_int_at_mem(gcref, ofs + itemindex * size, size, sign,
-                              newvalue)
+        self.write_int_at_mem(gcref, ofs + itemindex * size, size, newvalue)
 
     def bh_setarrayitem_gc_r(self, gcref, itemindex, newvalue, arraydescr):
         ofs = self.unpack_arraydescr(arraydescr)
 
     def bh_getinteriorfield_gc_i(self, gcref, itemindex, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
-        ofs += descr.fielddescr.offset
-        fieldsize = descr.fielddescr.field_size
-        sign = descr.fielddescr.is_field_signed()
-        fullofs = itemindex * size + ofs
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), fullofs)
-        for STYPE, UTYPE, itemsize in unroll_basic_sizes:
-            if fieldsize == itemsize:
-                if sign:
-                    item = rffi.cast(rffi.CArrayPtr(STYPE), items)
-                    val = item[0]
-                    val = rffi.cast(lltype.Signed, val)
-                else:
-                    item = rffi.cast(rffi.CArrayPtr(UTYPE), items)
-                    val = item[0]
-                    val = rffi.cast(lltype.Signed, val)
-                # --- end of GC unsafe code ---
-                return val
-        else:
-            raise NotImplementedError("size = %d" % fieldsize)
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
+        fldofs, fldsize, sign = self.unpack_fielddescr_size(descr.fielddescr)
+        ofs += itemindex * size + fldofs
+        return self.read_int_at_mem(gcref, ofs, fldsize, sign)
 
     def bh_getinteriorfield_gc_r(self, gcref, itemindex, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
         ofs += descr.fielddescr.offset
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs +
-                            size * itemindex)
-        items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
-        pval = self._cast_int_to_gcref(items[0])
-        # --- end of GC unsafe code ---
-        return pval
+        fullofs = itemindex * size + ofs
+        return self.read_ref_at_mem(gcref, fullofs)
 
     def bh_getinteriorfield_gc_f(self, gcref, itemindex, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
         ofs += descr.fielddescr.offset
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs +
-                            size * itemindex)
-        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
-        fval = items[0]
-        # --- end of GC unsafe code ---
-        return fval
+        fullofs = itemindex * size + ofs
+        return self.read_float_at_mem(gcref, fullofs)
 
-    def bh_setinteriorfield_gc_i(self, gcref, itemindex, value, descr):
+    def bh_setinteriorfield_gc_i(self, gcref, itemindex, newvalue, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
-        ofs += descr.fielddescr.offset
-        fieldsize = descr.fielddescr.field_size
-        ofs = itemindex * size + ofs
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
-        for TYPE, _, itemsize in unroll_basic_sizes:
-            if fieldsize == itemsize:
-                items = rffi.cast(rffi.CArrayPtr(TYPE), items)
-                items[0] = rffi.cast(TYPE, value)
-                # --- end of GC unsafe code ---
-                return
-        else:
-            raise NotImplementedError("size = %d" % fieldsize)
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
+        fldofs, fldsize, _ = self.unpack_fielddescr_size(descr.fielddescr)
+        ofs += itemindex * size + fldofs
+        self.write_int_at_mem(gcref, ofs, fldsize, newvalue)
 
     def bh_setinteriorfield_gc_r(self, gcref, itemindex, newvalue, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
-        ofs += descr.fielddescr.offset
-        self.gc_ll_descr.do_write_barrier(gcref, newvalue)
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref),
-                            ofs + size * itemindex)
-        items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items)
-        items[0] = self.cast_gcref_to_int(newvalue)
-        # --- end of GC unsafe code ---
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
+        ofs += itemindex * size + descr.fielddescr.offset
+        self.write_ref_at_mem(gcref, ofs, newvalue)
 
     def bh_setinteriorfield_gc_f(self, gcref, itemindex, newvalue, descr):
         assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
-        ofs += descr.fielddescr.offset
-        # --- start of GC unsafe code (no GC operation!) ---
-        items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref),
-                            ofs + size * itemindex)
-        items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items)
-        items[0] = newvalue
-        # --- end of GC unsafe code ---
+        ofs, size, _ = self.unpack_arraydescr_size(descr.arraydescr)
+        ofs += itemindex * size + descr.fielddescr.offset
+        self.write_float_at_mem(gcref, ofs, newvalue)
 
     def bh_strlen(self, string):
         s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
         return ord(u.chars[index])
 
     @specialize.argtype(1)
-    def _base_do_getfield_i(self, struct, fielddescr):
+    def bh_getfield_gc_i(self, struct, fielddescr):
         ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
-        # --- start of GC unsafe code (no GC operation!) ---
-        fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
-        for STYPE, UTYPE, itemsize in unroll_basic_sizes:
-            if size == itemsize:
-                # Note that in the common case where size==sizeof(Signed),
-                # both cases of what follows are doing the same thing.
-                # But gcc is clever enough to figure this out :-)
-                if sign:
-                    val = rffi.cast(rffi.CArrayPtr(STYPE), fieldptr)[0]
-                    val = rffi.cast(lltype.Signed, val)
-                else:
-                    val = rffi.cast(rffi.CArrayPtr(UTYPE), fieldptr)[0]
-                    val = rffi.cast(lltype.Signed, val)
-                # --- end of GC unsafe code ---
-                return val
-        else:
-            raise NotImplementedError("size = %d" % size)
+        return self.read_int_at_mem(struct, ofs, size, sign)
 
     @specialize.argtype(1)
-    def _base_do_getfield_r(self, struct, fielddescr):
+    def bh_getfield_gc_r(self, struct, fielddescr):
         ofs = self.unpack_fielddescr(fielddescr)
-        # --- start of GC unsafe code (no GC operation!) ---
-        fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
-        pval = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)[0]
-        pval = self._cast_int_to_gcref(pval)
-        # --- end of GC unsafe code ---
-        return pval
+        return self.read_ref_at_mem(struct, ofs)
 
     @specialize.argtype(1)
-    def _base_do_getfield_f(self, struct, fielddescr):
+    def bh_getfield_gc_f(self, struct, fielddescr):
         ofs = self.unpack_fielddescr(fielddescr)
-        # --- start of GC unsafe code (no GC operation!) ---
-        fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
-        fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0]
-        # --- end of GC unsafe code ---