[pypy-commit] pypy stmgc-c4: hg merge default
arigo
noreply at buildbot.pypy.org
Mon Sep 9 18:56:19 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c4
Changeset: r66866:781dce1d3438
Date: 2013-09-09 18:25 +0200
http://bitbucket.org/pypy/pypy/changeset/781dce1d3438/
Log: hg merge default
diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py
--- a/lib_pypy/_tkinter/__init__.py
+++ b/lib_pypy/_tkinter/__init__.py
@@ -22,6 +22,7 @@
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,
diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
--- a/lib_pypy/_tkinter/app.py
+++ b/lib_pypy/_tkinter/app.py
@@ -4,7 +4,23 @@
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):
@@ -37,17 +53,18 @@
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):
@@ -58,6 +75,8 @@
class TkApp(object):
+ _busywaitinterval = 0.02 # 20ms.
+
def __new__(cls, screenName, baseName, className,
interactive, wantobjects, wantTk, sync, use):
if not wantobjects:
@@ -73,6 +92,12 @@
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 = {}
@@ -133,6 +158,13 @@
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")
@@ -159,22 +191,25 @@
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)
@@ -183,9 +218,10 @@
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)
@@ -219,9 +255,10 @@
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")
@@ -229,7 +266,8 @@
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")
@@ -256,11 +294,12 @@
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:
@@ -280,17 +319,19 @@
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):
@@ -375,7 +416,10 @@
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
diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py
--- a/lib_pypy/_tkinter/tklib.py
+++ b/lib_pypy/_tkinter/tklib.py
@@ -19,6 +19,8 @@
#define TCL_EVAL_DIRECT ...
#define TCL_EVAL_GLOBAL ...
+#define TCL_DONT_WAIT ...
+
typedef unsigned short Tcl_UniChar;
typedef ... Tcl_Interp;
typedef ...* Tcl_ThreadId;
@@ -110,8 +112,8 @@
linklibs = ['tk85', 'tcl85']
libdirs = ['/usr/local/lib', '/usr/X11R6/lib']
else:
- incdirs=['/usr/include/tcl'],
- linklibs=['tcl', 'tk'],
+ incdirs=['/usr/include/tcl']
+ linklibs=['tcl', 'tk']
libdirs = []
tklib = tkffi.verify("""
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -373,73 +373,42 @@
@specialize.argtype(1)
def read_int_at_mem(self, gcref, ofs, size, sign):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- # --- 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)
def read_ref_at_mem(self, gcref, ofs):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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)
def write_ref_at_mem(self, gcref, ofs, newvalue):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- # --- 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):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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):
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- # --- 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)
# ____________________________________________________________
@@ -449,7 +418,7 @@
"""
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
@@ -476,9 +445,8 @@
def bh_arraylen_gc(self, array, arraydescr):
assert isinstance(arraydescr, ArrayDescr)
- array = self.gc_ll_descr.do_stm_barrier(array, 'R')
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):
@@ -499,8 +467,7 @@
@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)
@@ -520,231 +487,101 @@
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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'R')
- # --- 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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- # --- 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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- #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
- gcref = self.gc_ll_descr.do_stm_barrier(gcref, 'W')
- # --- 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):
- string = self.gc_ll_descr.do_stm_barrier(string, 'R')
s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
return len(s.chars)
def bh_unicodelen(self, string):
- string = self.gc_ll_descr.do_stm_barrier(string, 'R')
u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
return len(u.chars)
def bh_strgetitem(self, string, index):
- string = self.gc_ll_descr.do_stm_barrier(string, 'R')
s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
return ord(s.chars[index])
def bh_unicodegetitem(self, string, index):
- string = self.gc_ll_descr.do_stm_barrier(string, 'R')
u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), 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)
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'R')
- # --- 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)
+
+ def bh_getfield_gc_r(self, struct, fielddescr):
+ ofs = self.unpack_fielddescr(fielddescr)
+ return self.read_ref_at_mem(struct, ofs)
@specialize.argtype(1)
- def _base_do_getfield_r(self, struct, fielddescr):
+ def bh_getfield_gc_f(self, struct, fielddescr):
ofs = self.unpack_fielddescr(fielddescr)
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'R')
- # --- 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_float_at_mem(struct, ofs)
+
+ bh_getfield_raw_i = bh_getfield_gc_i
+ bh_getfield_raw_f = bh_getfield_gc_f
@specialize.argtype(1)
- def _base_do_getfield_f(self, struct, fielddescr):
+ def bh_setfield_gc_i(self, struct, newvalue, fielddescr):
+ ofs, size, _ = self.unpack_fielddescr_size(fielddescr)
+ self.write_int_at_mem(struct, ofs, size, newvalue)
+
+ def bh_setfield_gc_r(self, struct, newvalue, fielddescr):
ofs = self.unpack_fielddescr(fielddescr)
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'R')
- # --- 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 ---
- return fval
-
- bh_getfield_gc_i = _base_do_getfield_i
- bh_getfield_gc_r = _base_do_getfield_r
- bh_getfield_gc_f = _base_do_getfield_f
- bh_getfield_raw_i = _base_do_getfield_i
- bh_getfield_raw_r = _base_do_getfield_r
- bh_getfield_raw_f = _base_do_getfield_f
+ self.write_ref_at_mem(struct, ofs, newvalue)
@specialize.argtype(1)
- def _base_do_setfield_i(self, struct, newvalue, fielddescr):
- ofs, size, sign = self.unpack_fielddescr_size(fielddescr)
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'W')
- # --- start of GC unsafe code (no GC operation!) ---
- fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
- for TYPE, _, itemsize in unroll_basic_sizes:
- if size == itemsize:
- fieldptr = rffi.cast(rffi.CArrayPtr(TYPE), fieldptr)
- fieldptr[0] = rffi.cast(TYPE, newvalue)
- # --- end of GC unsafe code ---
- return
- else:
- raise NotImplementedError("size = %d" % size)
+ def bh_setfield_gc_f(self, struct, newvalue, fielddescr):
+ ofs = self.unpack_fielddescr(fielddescr)
+ self.write_float_at_mem(struct, ofs, newvalue)
- @specialize.argtype(1)
- def _base_do_setfield_r(self, struct, newvalue, fielddescr):
- ofs = self.unpack_fielddescr(fielddescr)
- assert lltype.typeOf(struct) is not lltype.Signed, (
- "can't handle write barriers for setfield_raw")
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'W')
- #self.gc_ll_descr.do_write_barrier(struct, newvalue)
- # --- start of GC unsafe code (no GC operation!) ---
- fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
- fieldptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), fieldptr)
- fieldptr[0] = self.cast_gcref_to_int(newvalue)
- # --- end of GC unsafe code ---
-
- @specialize.argtype(1)
- def _base_do_setfield_f(self, struct, newvalue, fielddescr):
- ofs = self.unpack_fielddescr(fielddescr)
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'W')
- # --- start of GC unsafe code (no GC operation!) ---
- fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs)
- fieldptr = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)
- fieldptr[0] = newvalue
- # --- end of GC unsafe code ---
-
- bh_setfield_gc_i = _base_do_setfield_i
- bh_setfield_gc_r = _base_do_setfield_r
- bh_setfield_gc_f = _base_do_setfield_f
- bh_setfield_raw_i = _base_do_setfield_i
- bh_setfield_raw_r = _base_do_setfield_r
- bh_setfield_raw_f = _base_do_setfield_f
+ bh_setfield_raw_i = bh_setfield_gc_i
+ bh_setfield_raw_f = bh_setfield_gc_f
def bh_raw_store_i(self, addr, offset, newvalue, descr):
- ofs, size, sign = self.unpack_arraydescr_size(descr)
- items = addr + offset
- for TYPE, _, itemsize in unroll_basic_sizes:
- if size == itemsize:
- items = rffi.cast(rffi.CArrayPtr(TYPE), items)
- items[0] = rffi.cast(TYPE, newvalue)
- break
+ ofs, size, _ = self.unpack_arraydescr_size(descr)
+ assert ofs == 0 # otherwise, 'descr' is not a raw length-less array
+ self.write_int_at_mem(addr, offset, size, newvalue)
def bh_raw_store_f(self, addr, offset, newvalue, descr):
- items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset)
- items[0] = newvalue
+ self.write_float_at_mem(addr, offset, newvalue)
def bh_raw_load_i(self, addr, offset, descr):
ofs, size, sign = self.unpack_arraydescr_size(descr)
@@ -752,8 +589,7 @@
return self.read_int_at_mem(addr, offset, size, sign)
def bh_raw_load_f(self, addr, offset, descr):
- items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), addr + offset)
- return items[0]
+ return self.read_float_at_mem(addr, offset)
def bh_new(self, sizedescr):
return self.gc_ll_descr.gc_malloc(sizedescr)
@@ -761,17 +597,13 @@
def bh_new_with_vtable(self, vtable, sizedescr):
res = self.gc_ll_descr.gc_malloc(sizedescr)
if self.vtable_offset is not None:
- assert not self.gc_ll_descr.stm
- res = self.gc_ll_descr.do_stm_barrier(res, 'W')
- as_array = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
- as_array[self.vtable_offset/WORD] = vtable
+ self.write_int_at_mem(res, self.vtable_offset, WORD, vtable)
return res
def bh_new_raw_buffer(self, size):
return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
def bh_classof(self, struct):
- struct = self.gc_ll_descr.do_stm_barrier(struct, 'R')
struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
return heaptracker.adr2int(result_adr)
@@ -786,25 +618,19 @@
return self.gc_ll_descr.gc_malloc_unicode(length)
def bh_strsetitem(self, string, index, newvalue):
- string = self.gc_ll_descr.do_stm_barrier(string, 'W')
s = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), string)
s.chars[index] = chr(newvalue)
def bh_unicodesetitem(self, string, index, newvalue):
- string = self.gc_ll_descr.do_stm_barrier(string, 'W')
u = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
u.chars[index] = unichr(newvalue)
def bh_copystrcontent(self, src, dst, srcstart, dststart, length):
- src = self.gc_ll_descr.do_stm_barrier(src, 'R')
- dst = self.gc_ll_descr.do_stm_barrier(dst, 'W')
src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), src)
dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.STR), dst)
rstr.copy_string_contents(src, dst, srcstart, dststart, length)
def bh_copyunicodecontent(self, src, dst, srcstart, dststart, length):
- src = self.gc_ll_descr.do_stm_barrier(src, 'R')
- dst = self.gc_ll_descr.do_stm_barrier(dst, 'W')
src = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), src)
dst = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), dst)
rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -740,7 +740,7 @@
for ofs in self.frame_depth_to_patch:
self._patch_frame_depth(ofs + rawstart, framedepth)
- def _check_frame_depth(self, mc, gcmap, expected_size=-1):
+ def _check_frame_depth(self, mc, gcmap):
""" check if the frame is of enough depth to follow this bridge.
Otherwise reallocate the frame in a helper.
There are other potential solutions
@@ -748,17 +748,11 @@
"""
descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu)
ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr)
- if expected_size == -1:
- mc.CMP_bi(ofs, 0xffffff)
- else:
- mc.CMP_bi(ofs, expected_size)
+ mc.CMP_bi(ofs, 0xffffff) # force writing 32 bit
stack_check_cmp_ofs = mc.get_relative_pos() - 4
mc.J_il8(rx86.Conditions['GE'], 0)
jg_location = mc.get_relative_pos()
- if expected_size == -1:
- mc.MOV_si(WORD, 0xffffff)
- else:
- mc.MOV_si(WORD, expected_size)
+ mc.MOV_si(WORD, 0xffffff) # force writing 32 bit
ofs2 = mc.get_relative_pos() - 4
self.push_gcmap(mc, gcmap, mov=True)
mc.CALL(imm(self._frame_realloc_slowpath))
diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -1119,7 +1119,8 @@
opname = hop.spaceop.opname
v_struct = hop.spaceop.args[0]
v_newvalue = hop.spaceop.args[-1]
- assert opname in ('setfield', 'setarrayitem', 'setinteriorfield')
+ assert opname in ('setfield', 'setarrayitem', 'setinteriorfield',
+ 'raw_store')
assert isinstance(v_newvalue.concretetype, lltype.Ptr)
# XXX for some GCs the skipping if the newvalue is a constant won't be
# ok
diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -330,6 +330,7 @@
hop.rename('bare_' + hop.spaceop.opname)
gct_setarrayitem = gct_setfield
gct_setinteriorfield = gct_setfield
+ gct_raw_store = gct_setfield
gct_getfield = default
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -149,6 +149,7 @@
@specialize.argtype(0)
+ at jit.elidable
def replace(input, sub, by, maxsplit=-1):
if isinstance(input, str):
assert isinstance(sub, str)
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -1025,6 +1025,10 @@
op_raw_load.need_result_type = True
def op_raw_store(self, addr, offset, value):
+ # XXX handle the write barrier by delegating to self.heap instead
+ self.op_bare_raw_store(addr, offset, value)
+
+ def op_bare_raw_store(self, addr, offset, value):
checkadr(addr)
ARGTYPE = lltype.typeOf(value)
if isinstance(offset, int):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -461,8 +461,9 @@
'raw_memclear': LLOp(),
'raw_memcopy': LLOp(),
'raw_memmove': LLOp(),
- 'raw_load': LLOp(sideeffects=False),
- 'raw_store': LLOp(),
+ 'raw_load': LLOp(sideeffects=False, canrun=True),
+ 'raw_store': LLOp(canrun=True),
+ 'bare_raw_store': LLOp(),
'stack_malloc': LLOp(), # mmh
'track_alloc_start': LLOp(),
'track_alloc_stop': LLOp(),
diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -678,6 +678,26 @@
def op_stm_get_tid(x):
raise NotImplementedError
+def op_raw_store(p, ofs, newvalue):
+ from rpython.rtyper.lltypesystem import rffi
+ TP = lltype.typeOf(p)
+ if TP != llmemory.Address:
+ assert TP == llmemory.GCREF
+ p = rffi.cast(llmemory.Address, p)
+ TVAL = lltype.typeOf(newvalue)
+ p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs)
+ p[0] = newvalue
+
+def op_raw_load(TVAL, p, ofs):
+ from rpython.rtyper.lltypesystem import rffi
+ TP = lltype.typeOf(p)
+ if TP != llmemory.Address:
+ assert TP == llmemory.GCREF
+ p = rffi.cast(llmemory.Address, p)
+ p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs)
+ return p[0]
+op_raw_load.need_result_type = True
+
# ____________________________________________________________
def get_op_impl(opname):
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -744,6 +744,7 @@
return (
'((%(typename)s) (((char *)%(addr)s) + %(offset)s))[0] = %(value)s;'
% locals())
+ OP_BARE_RAW_STORE = OP_RAW_STORE
def OP_RAW_LOAD(self, op):
addr = self.expr(op.args[0])
More information about the pypy-commit
mailing list