[pypy-commit] pypy fast-gil: hg merge default
arigo
noreply at buildbot.pypy.org
Wed Jun 25 19:34:10 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: fast-gil
Changeset: r72229:ed9493101461
Date: 2014-06-25 19:33 +0200
http://bitbucket.org/pypy/pypy/changeset/ed9493101461/
Log: hg merge default
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
@@ -1906,3 +1906,60 @@
p = lib.f2(42)
x = lib.f1(p)
assert x == 42
+
+def _run_in_multiple_threads(test1):
+ test1()
+ import sys
+ try:
+ import thread
+ except ImportError:
+ import _thread as thread
+ errors = []
+ def wrapper(lock):
+ try:
+ test1()
+ except:
+ errors.append(sys.exc_info())
+ lock.release()
+ locks = []
+ for i in range(10):
+ _lock = thread.allocate_lock()
+ _lock.acquire()
+ thread.start_new_thread(wrapper, (_lock,))
+ locks.append(_lock)
+ for _lock in locks:
+ _lock.acquire()
+ if errors:
+ raise errors[0][1]
+
+def test_errno_working_even_with_pypys_jit():
+ ffi = FFI()
+ ffi.cdef("int f(int);")
+ lib = ffi.verify("""
+ #include <errno.h>
+ int f(int x) { return (errno = errno + x); }
+ """)
+ @_run_in_multiple_threads
+ def test1():
+ ffi.errno = 0
+ for i in range(10000):
+ e = lib.f(1)
+ assert e == i + 1
+ assert ffi.errno == e
+ for i in range(10000):
+ ffi.errno = i
+ e = lib.f(42)
+ assert e == i + 42
+
+def test_getlasterror_working_even_with_pypys_jit():
+ if sys.platform != 'win32':
+ py.test.skip("win32-only test")
+ ffi = FFI()
+ ffi.cdef("void SetLastError(DWORD);")
+ lib = ffi.dlopen("Kernel32.dll")
+ @_run_in_multiple_threads
+ def test1():
+ for i in range(10000):
+ n = (1 << 29) + i
+ lib.SetLastError(n)
+ assert ffi.getwinerror()[0] == n
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -16,7 +16,7 @@
class ModuleCell(W_Root):
- def __init__(self, w_value=None):
+ def __init__(self, w_value):
self.w_value = w_value
def __repr__(self):
@@ -49,17 +49,24 @@
return self.erase({})
def mutated(self):
+ # A mutation means changing an existing key to point to a new value.
+ # A value is either a regular wrapped object, or a ModuleCell if we
+ # detect mutations. It means that each existing key can only trigger
+ # a mutation at most once.
self.version = VersionTag()
- def getdictvalue_no_unwrapping(self, w_dict, key):
+ def dictvalue_no_unwrapping(self, w_dict, key):
# NB: it's important to promote self here, so that self.version is a
# no-op due to the quasi-immutable field
self = jit.promote(self)
- return self._getdictvalue_no_unwrapping_pure(self.version, w_dict, key)
+ return self._dictvalue_no_unwrapping_pure(self.version, w_dict, key)
@jit.elidable_promote('0,1,2')
- def _getdictvalue_no_unwrapping_pure(self, version, w_dict, key):
- return self.unerase(w_dict.dstorage).get(key, None)
+ def _dictvalue_no_unwrapping_pure(self, version, w_dict, key):
+ # may raise KeyError. If it does, then the JIT is prevented from
+ # considering this function as elidable. This is what lets us add
+ # new keys to the dictionary without changing the version.
+ return self.unerase(w_dict.dstorage)[key]
def setitem(self, w_dict, w_key, w_value):
space = self.space
@@ -70,17 +77,20 @@
w_dict.setitem(w_key, w_value)
def setitem_str(self, w_dict, key, w_value):
- cell = self.getdictvalue_no_unwrapping(w_dict, key)
- if isinstance(cell, ModuleCell):
- cell.w_value = w_value
- return
- if cell is not None:
+ try:
+ cell = self.dictvalue_no_unwrapping(w_dict, key)
+ except KeyError:
+ pass
+ else:
+ if isinstance(cell, ModuleCell):
+ cell.w_value = w_value
+ return
# If the new value and the current value are the same, don't
# create a level of indirection, or mutate the version.
if self.space.is_w(w_value, cell):
return
w_value = ModuleCell(w_value)
- self.mutated()
+ self.mutated()
self.unerase(w_dict.dstorage)[key] = w_value
def setdefault(self, w_dict, w_key, w_default):
@@ -130,7 +140,10 @@
return w_dict.getitem(w_key)
def getitem_str(self, w_dict, key):
- cell = self.getdictvalue_no_unwrapping(w_dict, key)
+ try:
+ cell = self.dictvalue_no_unwrapping(w_dict, key)
+ except KeyError:
+ return None
return unwrap_cell(cell)
def w_keys(self, w_dict):
diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py
--- a/pypy/objspace/std/test/test_celldict.py
+++ b/pypy/objspace/std/test/test_celldict.py
@@ -21,27 +21,27 @@
w_key = self.FakeString(key)
d.setitem(w_key, 1)
v2 = strategy.version
- assert v1 is not v2
+ assert v1 is v2 # doesn't change when adding new keys
assert d.getitem(w_key) == 1
- assert d.strategy.getdictvalue_no_unwrapping(d, key) == 1
+ assert d.strategy.dictvalue_no_unwrapping(d, key) == 1
d.setitem(w_key, 2)
v3 = strategy.version
assert v2 is not v3
assert d.getitem(w_key) == 2
- assert d.strategy.getdictvalue_no_unwrapping(d, key).w_value == 2
+ assert d.strategy.dictvalue_no_unwrapping(d, key).w_value == 2
d.setitem(w_key, 3)
v4 = strategy.version
assert v3 is v4
assert d.getitem(w_key) == 3
- assert d.strategy.getdictvalue_no_unwrapping(d, key).w_value == 3
+ assert d.strategy.dictvalue_no_unwrapping(d, key).w_value == 3
d.delitem(w_key)
v5 = strategy.version
assert v5 is not v4
assert d.getitem(w_key) is None
- assert d.strategy.getdictvalue_no_unwrapping(d, key) is None
+ py.test.raises(KeyError, d.strategy.dictvalue_no_unwrapping, d, key)
def test_same_key_set_twice(self):
strategy = ModuleDictStrategy(space)
@@ -52,7 +52,7 @@
x = object()
d.setitem("a", x)
v2 = strategy.version
- assert v1 is not v2
+ assert v1 is v2
d.setitem("a", x)
v3 = strategy.version
assert v2 is v3
More information about the pypy-commit
mailing list