[pypy-commit] pypy default: a failing test for the signals_enabled context manager's fork logic
Author: Brian Kearns Branch: Changeset: r61304:320c4790eae6 Date: 2013-02-16 02:26 -0500 http://bitbucket.org/pypy/pypy/changeset/320c4790eae6/ Log:a failing test for the signals_enabled context manager's fork logic diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -1,5 +1,7 @@ import sys +from pypy.module.thread.test.support import GenericTestThread + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -11,7 +13,7 @@ # assert did not crash -class AppTestThreadSignal: +class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_enable_signals(self): @@ -48,6 +50,37 @@ finally: __pypy__.thread._signals_enter() +def test_thread_fork_signals(self): +import __pypy__ +import os, thread, signal + +if not hasattr(os, 'fork'): +skip("No fork on this platform") + +def fork(): +with __pypy__.thread.signals_enabled: +return os.fork() + +def threadfunction(): +pid = fork() +if pid == 0: +print 'in child' +# signal() only works from the 'main' thread +signal.signal(signal.SIGUSR1, signal.SIG_IGN) +os._exit(42) +else: +self.timeout_killer(pid, 5) +exitcode = os.waitpid(pid, 0)[1] +feedback.append(exitcode) + +feedback = [] +thread.start_new_thread(threadfunction, ()) +self.waitfor(lambda: feedback) +# if 0, an (unraisable) exception was raised from the forked thread. +# if 9, process was killed by timer. +# if 42<<8, os._exit(42) was correctly reached. +assert feedback == [42<<8] + class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -81,6 +81,16 @@ # (which are now dead); and for the current thread, force an # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( +""" +TODO: this logic is currently flawed as we need to differentiate +between: 1) fork while in a main thread, in which case old should +not be incremented + 2) fork while in a subthread that has an enable_threads +context but is not main (in which case old should be +incremented, as the thread should get a point for becoming +the new 'main', so it remains in the dict when all its +contexts exit) +""" ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled.clear() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix the failing test by still keeping track of mainthreadident so we know if
Author: Brian Kearns Branch: Changeset: r61305:2fe373e0724e Date: 2013-02-16 02:44 -0500 http://bitbucket.org/pypy/pypy/changeset/2fe373e0724e/ Log:fix the failing test by still keeping track of mainthreadident so we know if the forking thread should get an enable_signals point for becoming main diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -15,6 +15,7 @@ def _cleanup_(self): self._valuedict.clear() self._signalsenabled.clear() +self._mainthreadident = 0 self._mostrecentkey = 0# fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -35,6 +36,7 @@ if value is not None: if len(self._valuedict) == 0: self._signalsenabled[ident] = 1# the main thread is enabled +self._mainthreadident = ident self._valuedict[ident] = value else: try: @@ -81,19 +83,10 @@ # (which are now dead); and for the current thread, force an # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( -""" -TODO: this logic is currently flawed as we need to differentiate -between: 1) fork while in a main thread, in which case old should -not be incremented - 2) fork while in a subthread that has an enable_threads -context but is not main (in which case old should be -incremented, as the thread should get a point for becoming -the new 'main', so it remains in the dict when all its -contexts exit) -""" ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) +if ident is not self._mainthreadident: +self._mainthreadident = ident +old += 1 self._signalsenabled.clear() -if old == 0: -old = 1 self._signalsenabled[ident] = old ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: prevent signals from being disabled twice
Author: Brian Kearns Branch: Changeset: r61306:04926eb3ab15 Date: 2013-02-16 03:15 -0500 http://bitbucket.org/pypy/pypy/changeset/04926eb3ab15/ Log:prevent signals from being disabled twice diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,6 +3,18 @@ from pypy.module.thread.test.support import GenericTestThread +class TestThreadSignal: +spaceconfig = dict(usemodules=['__pypy__', 'thread']) + +def test_exit_twice(self, space): +from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter +signals_exit(space) +try: +raises(KeyError, signals_exit, space) +finally: +signals_enter(space) + + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -57,10 +57,7 @@ def disable_signals(self): ident = rthread.get_ident() -try: -new = self._signalsenabled[ident] - 1 -except KeyError: -return +new = self._signalsenabled[ident] - 1 if new > 0: self._signalsenabled[ident] = new else: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: clean up the thread's signals enabled count on thread exit
Author: Brian Kearns Branch: Changeset: r61307:0fb9480d9d6d Date: 2013-02-16 03:16 -0500 http://bitbucket.org/pypy/pypy/changeset/0fb9480d9d6d/ Log:clean up the thread's signals enabled count on thread exit diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -43,6 +43,10 @@ del self._valuedict[ident] except KeyError: pass +try: +del self._signalsenabled[ident] +except KeyError: +pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] cffi default: Moving the determination of the base integer type of an enum
Author: Armin Rigo Branch: Changeset: r1160:70927696eb9c Date: 2013-02-16 10:17 +0100 http://bitbucket.org/cffi/cffi/changeset/70927696eb9c/ Log:Moving the determination of the base integer type of an enum out of C code, into the 'cffi' package. This is work in progress; it should eventually permit the new test to fully pass. For now wrote a warning in the doc. diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4253,20 +4253,15 @@ char *ename; PyObject *enumerators, *enumvalues; PyObject *dict1 = NULL, *dict2 = NULL, *combined = NULL, *tmpkey = NULL; -ffi_type *ffitype; int name_size; -CTypeDescrObject *td; +CTypeDescrObject *td, *basetd; Py_ssize_t i, n; -struct aligncheck_int { char x; int y; }; -struct aligncheck_long { char x; long y; }; -long smallest_item = 0; -unsigned long largest_item = 0; -int size, flags; - -if (!PyArg_ParseTuple(args, "sO!O!:new_enum_type", + +if (!PyArg_ParseTuple(args, "sO!O!O!:new_enum_type", &ename, &PyTuple_Type, &enumerators, - &PyTuple_Type, &enumvalues)) + &PyTuple_Type, &enumvalues, + &CTypeDescr_Type, &basetd)) return NULL; n = PyTuple_GET_SIZE(enumerators); @@ -4276,6 +4271,12 @@ return NULL; } +if (!(basetd->ct_flags & (CT_PRIMITIVE_SIGNED|CT_PRIMITIVE_UNSIGNED))) { +PyErr_SetString(PyExc_TypeError, +"expected a primitive signed or unsigned base type"); +return NULL; +} + dict1 = PyDict_New(); if (dict1 == NULL) goto error; @@ -4284,8 +4285,7 @@ goto error; for (i=n; --i >= 0; ) { -long lvalue; -unsigned long ulvalue; +long long lvalue; PyObject *value = PyTuple_GET_ITEM(enumvalues, i); tmpkey = PyTuple_GET_ITEM(enumerators, i); Py_INCREF(tmpkey); @@ -4308,31 +4308,8 @@ goto error; } } -lvalue = PyLong_AsLong(value); -if (PyErr_Occurred()) { -PyErr_Clear(); -ulvalue = PyLong_AsUnsignedLong(value); -if (PyErr_Occurred()) { -PyErr_Format(PyExc_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - ename, PyText_AS_UTF8(tmpkey)); -goto error; -} -if (ulvalue > largest_item) -largest_item = ulvalue; -} -else { -if (lvalue < 0) { -if (lvalue < smallest_item) -smallest_item = lvalue; -} -else { -ulvalue = (unsigned long)lvalue; -if (ulvalue > largest_item) -largest_item = ulvalue; -} -} +if (convert_from_object((char*)&lvalue, basetd, value) < 0) +goto error; /* out-of-range or badly typed 'value' */ if (PyDict_SetItem(dict1, tmpkey, value) < 0) goto error; if (PyDict_SetItem(dict2, value, tmpkey) < 0) @@ -4341,32 +4318,6 @@ tmpkey = NULL; } -if (smallest_item < 0) { -flags = CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; -if (smallest_item == (int)smallest_item && - largest_item <= (unsigned long)INT_MAX) { -size = sizeof(int); -} -else if (largest_item <= (unsigned long)LONG_MAX) { -size = sizeof(long); -} -else { -PyErr_Format(PyExc_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", ename); -goto error; -} -} -else if (sizeof(unsigned int) < sizeof(unsigned long) && - largest_item == (unsigned int)largest_item) { -flags = CT_PRIMITIVE_UNSIGNED | CT_PRIMITIVE_FITS_LONG | CT_IS_ENUM; -size = sizeof(unsigned int); -} -else { -flags = CT_PRIMITIVE_UNSIGNED | CT_IS_ENUM; -size = sizeof(unsigned long); -} - combined = PyTuple_Pack(2, dict1, dict2); if (combined == NULL) goto error; @@ -4374,12 +4325,6 @@ Py_CLEAR(dict2); Py_CLEAR(dict1); -switch (size) { -case 4: ffitype = &ffi_type_sint32; break; -case 8: ffitype = &ffi_type_sint64; break; -default: Py_FatalError("'int' or 'long' is not 4 or 8 bytes"); return NULL; -} - name_size = strlen("enum ") + strlen(ename) + 1; td = ctypedescr_new(name_size); if (td == NULL) @@ -4388,11 +4333,10 @@ memcpy(td->ct_name, "enum ", strlen("enum ")); memcpy(td->ct_name + strlen("enum "), ename, name_size - strlen("enum ")); td->ct_
[pypy-commit] pypy default: Update to cffi/70927696eb9c
Author: Armin Rigo Branch: Changeset: r61308:c44d9205dbb4 Date: 2013-02-16 10:29 +0100 http://bitbucket.org/pypy/pypy/changeset/c44d9205dbb4/ Log:Update to cffi/70927696eb9c diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -264,8 +264,8 @@ # -@unwrap_spec(name=str) -def new_enum_type(space, name, w_enumerators, w_enumvalues): +@unwrap_spec(name=str, basectype=ctypeobj.W_CType) +def new_enum_type(space, name, w_enumerators, w_enumvalues, basectype): enumerators_w = space.fixedview(w_enumerators) enumvalues_w = space.fixedview(w_enumvalues) if len(enumerators_w) != len(enumvalues_w): @@ -273,53 +273,26 @@ space.wrap("tuple args must have the same size")) enumerators = [space.str_w(w) for w in enumerators_w] # -smallest_value = 0 -largest_value = r_uint(0) -i = 0 +if (not isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned) and +not isinstance(basectype, ctypeprim.W_CTypePrimitiveUnsigned)): +raise OperationError(space.w_TypeError, + space.wrap("expected a primitive signed or unsigned base type")) +# +lvalue = lltype.malloc(rffi.CCHARP.TO, basectype.size, flavor='raw') try: for w in enumvalues_w: -try: -ulvalue = space.uint_w(w) -except OperationError, e: -if not e.match(space, space.w_ValueError): -raise -lvalue = space.int_w(w) -if lvalue < smallest_value: -smallest_value = lvalue -else: -if ulvalue > largest_value: -largest_value = ulvalue -i += 1# 'i' is here for the exception case, see below -except OperationError, e: -if not e.match(space, space.w_OverflowError): -raise -raise operationerrfmt(space.w_OverflowError, - "enum '%s' declaration for '%s' does not fit " - "a long or unsigned long", - name, enumerators[i]) +# detects out-of-range or badly typed values +basectype.convert_from_object(lvalue, w) +finally: +lltype.free(lvalue, flavor='raw') # -if smallest_value < 0: -if (smallest_value >= intmask(most_neg_value_of(rffi.INT)) and - largest_value <= r_uint(most_pos_value_of(rffi.INT))): -size = rffi.sizeof(rffi.INT) -align = alignment(rffi.INT) -elif largest_value <= r_uint(most_pos_value_of(rffi.LONG)): -size = rffi.sizeof(rffi.LONG) -align = alignment(rffi.LONG) -else: -raise operationerrfmt(space.w_OverflowError, - "enum '%s' values don't all fit into either 'long' " - "or 'unsigned long'", name) +size = basectype.size +align = basectype.align +if isinstance(basectype, ctypeprim.W_CTypePrimitiveSigned): enumvalues = [space.int_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumSigned(space, name, size, align, enumerators, enumvalues) else: -if largest_value <= r_uint(most_pos_value_of(rffi.UINT)): -size = rffi.sizeof(rffi.UINT) -align = alignment(rffi.UINT) -else: -size = rffi.sizeof(rffi.ULONG) -align = alignment(rffi.ULONG) enumvalues = [space.uint_w(w) for w in enumvalues_w] ctype = ctypeenum.W_CTypeEnumUnsigned(space, name, size, align, enumerators, enumvalues) diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -1264,25 +1264,29 @@ py.test.raises(TypeError, callback, BFunc, cb, -42) def test_enum_type(): -BEnum = new_enum_type("foo", (), ()) +BUInt = new_primitive_type("unsigned int") +BEnum = new_enum_type("foo", (), (), BUInt) assert repr(BEnum) == "" assert BEnum.kind == "enum" assert BEnum.cname == "enum foo" assert BEnum.elements == {} # -BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20)) +BInt = new_primitive_type("int") +BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20), BInt) assert BEnum.kind == "enum" assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # 'elements' is not the real dict, but merely a copy BEnum.elements[2] = '??' assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'} # -BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5)) +BEnum = new_enum_type("bar",
[pypy-commit] pypy default: try to clean up more on fork
Author: Brian Kearns Branch: Changeset: r61309:8f52d162f0ee Date: 2013-02-16 04:27 -0500 http://bitbucket.org/pypy/pypy/changeset/8f52d162f0ee/ Log:try to clean up more on fork diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -85,9 +85,11 @@ # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() -old = self._signalsenabled.get(ident, 0) -if ident is not self._mainthreadident: -self._mainthreadident = ident -old += 1 -self._signalsenabled.clear() -self._signalsenabled[ident] = old +val = self.getvalue() +sig = self._signalsenabled.get(ident, 0) +if ident != self._mainthreadident: +sig += 1 +self._cleanup_() +self.setvalue(val) +self._signalsenabled[ident] = sig +self._mainthreadident = ident ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: mark these unroll safe also
Author: Brian Kearns Branch: Changeset: r61310:06d109391705 Date: 2013-02-16 04:28 -0500 http://bitbucket.org/pypy/pypy/changeset/06d109391705/ Log:mark these unroll safe also diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -255,6 +255,7 @@ l.reverse() result.append("".join(l)) +@jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(min(len(s), 8)): @@ -262,6 +263,7 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) +@jit.unroll_safe def unpack_float80(s, be): QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: wrap the exception in signals_exit
Author: Brian Kearns Branch: Changeset: r61311:46b70943f54b Date: 2013-02-16 04:28 -0500 http://bitbucket.org/pypy/pypy/changeset/46b70943f54b/ Log:wrap the exception in signals_exit diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True -def enable_signals(self): +def enable_signals(self, space): pass -def disable_signals(self): +def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): -space.threadlocals.enable_signals() +space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): -space.threadlocals.disable_signals() +space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: -spaceconfig = dict(usemodules=['__pypy__', 'thread']) - -def test_exit_twice(self, space): -from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter -signals_exit(space) -try: -raises(KeyError, signals_exit, space) -finally: -signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) +def test_exit_twice(self): +from __pypy__ import thread +thread._signals_exit() +try: +raises(KeyError, thread._signals_exit) +finally: +thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,5 @@ from rpython.rlib import rthread +from pypy.interpreter.error import OperationError class OSThreadLocals: @@ -54,14 +55,18 @@ def signals_enabled(self): return rthread.get_ident() in self._signalsenabled -def enable_signals(self): +def enable_signals(self, space): ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled[ident] = old + 1 -def disable_signals(self): +def disable_signals(self, space): ident = rthread.get_ident() -new = self._signalsenabled[ident] - 1 +try: +new = self._signalsenabled[ident] - 1 +except KeyError: +raise OperationError(space.w_KeyError, space.wrap( +"cannot disable signals in thread not enabled for signals")) if new > 0: self._signalsenabled[ident] = new else: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Move thread.atomic to __pypy__.thread.atomic.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61312:43ffd21dc40e Date: 2013-02-16 10:54 +0100 http://bitbucket.org/pypy/pypy/changeset/43ffd21dc40e/ Log:Move thread.atomic to __pypy__.thread.atomic. diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py --- a/pypy/module/__pypy__/__init__.py +++ b/pypy/module/__pypy__/__init__.py @@ -29,10 +29,16 @@ class ThreadModule(MixedModule): appleveldefs = { 'signals_enabled': 'app_signal.signals_enabled', +'atomic': 'app_atomic.atomic', +'exclusive_atomic':'app_atomic.exclusive_atomic', +'error': 'app_atomic.error', } interpleveldefs = { '_signals_enter': 'interp_signal.signals_enter', '_signals_exit': 'interp_signal.signals_exit', +'_atomic_enter': 'interp_atomic.atomic_enter', +'_exclusive_atomic_enter': 'interp_atomic.exclusive_atomic_enter', +'_atomic_exit':'interp_atomic.atomic_exit', } diff --git a/pypy/module/thread/app_atomic.py b/pypy/module/__pypy__/app_atomic.py rename from pypy/module/thread/app_atomic.py rename to pypy/module/__pypy__/app_atomic.py --- a/pypy/module/thread/app_atomic.py +++ b/pypy/module/__pypy__/app_atomic.py @@ -1,4 +1,5 @@ -import thread +from thread import error # re-exported +from __pypy__ import thread class Atomic(object): __enter__ = thread._atomic_enter diff --git a/pypy/module/thread/atomic.py b/pypy/module/__pypy__/interp_atomic.py rename from pypy/module/thread/atomic.py rename to pypy/module/__pypy__/interp_atomic.py diff --git a/pypy/module/thread/test/test_atomic.py b/pypy/module/__pypy__/test/test_atomic.py rename from pypy/module/thread/test/test_atomic.py rename to pypy/module/__pypy__/test/test_atomic.py --- a/pypy/module/thread/test/test_atomic.py +++ b/pypy/module/__pypy__/test/test_atomic.py @@ -5,7 +5,7 @@ class AppTestAtomic(GenericTestThread): def test_simple(self): -import thread +from __pypy__ import thread for atomic in thread.atomic, thread.exclusive_atomic: with atomic: pass @@ -16,20 +16,20 @@ pass def test_nest_composable_atomic(self): -import thread +from __pypy__ import thread with thread.atomic: with thread.atomic: pass def test_nest_composable_below_exclusive(self): -import thread +from __pypy__ import thread with thread.exclusive_atomic: with thread.atomic: with thread.atomic: pass def test_nest_exclusive_fails(self): -import thread +from __pypy__ import thread try: with thread.exclusive_atomic: with thread.exclusive_atomic: @@ -38,7 +38,7 @@ assert e.message == "exclusive_atomic block can't be entered inside another atomic block" def test_nest_exclusive_fails2(self): -import thread +from __pypy__ import thread try: with thread.atomic: with thread.exclusive_atomic: diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py --- a/pypy/module/thread/__init__.py +++ b/pypy/module/thread/__init__.py @@ -4,8 +4,6 @@ class Module(MixedModule): appleveldefs = { -'atomic': 'app_atomic.atomic', -'exclusive_atomic': 'app_atomic.exclusive_atomic', } interpleveldefs = { @@ -22,9 +20,6 @@ 'LockType': 'os_lock.Lock', '_local': 'os_local.Local', 'error': 'space.fromcache(error.Cache).w_error', -'_atomic_enter': 'atomic.atomic_enter', -'_exclusive_atomic_enter': 'atomic.exclusive_atomic_enter', -'_atomic_exit': 'atomic.atomic_exit', } def __init__(self, space, *args): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Fix this import.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61313:e1fb39f86281 Date: 2013-02-16 10:55 +0100 http://bitbucket.org/pypy/pypy/changeset/e1fb39f86281/ Log:Fix this import. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -15,7 +15,7 @@ import sys, thread, collections try: -from thread import atomic +from __pypy__.thread import atomic except ImportError: # Not a STM-enabled PyPy. We can still provide a version of 'atomic' # that is good enough for our purposes. With this limited version, ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy jitframe-on-heap: make viewcode here support ARM
Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61314:ea07028f1133 Date: 2013-02-16 12:21 +0200 http://bitbucket.org/pypy/pypy/changeset/ea07028f1133/ Log:make viewcode here support ARM diff --git a/rpython/jit/backend/x86/tool/viewcode.py b/rpython/jit/backend/x86/tool/viewcode.py --- a/rpython/jit/backend/x86/tool/viewcode.py +++ b/rpython/jit/backend/x86/tool/viewcode.py @@ -53,9 +53,10 @@ 'x86_32': 'i386', 'x86_64': 'x86-64', 'i386': 'i386', +'arm': 'arm', } cmd = find_objdump() -objdump = ('%(command)s -M %(backend)s -b binary -m i386 ' +objdump = ('%(command)s -M %(backend)s -b binary -m %(machine)s ' '--disassembler-options=intel-mnemonics ' '--adjust-vma=%(origin)d -D %(file)s') # @@ -67,6 +68,7 @@ 'file': tmpfile, 'origin': originaddr, 'backend': objdump_backend_option[backend_name], +'machine': 'i386' if backend_name != 'arm' else 'arm', }, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() assert not p.returncode, ('Encountered an error running objdump: %s' % ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy jitframe-on-heap: merge
Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61315:3cab31c2fdbd Date: 2013-02-16 12:56 +0200 http://bitbucket.org/pypy/pypy/changeset/3cab31c2fdbd/ Log:merge diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -349,8 +349,8 @@ fcond, resloc, (size, signed)) return cond -def _emit_call(self, adr, arglocs, fcond=c.AL, - resloc=None, result_info=(-1, -1)): +def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, +result_info=(-1, -1)): if self.cpu.use_hf_abi: stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) @@ -1102,28 +1102,37 @@ def imm(self, v): return imm(v) - + def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond): if len(arglocs) == 4: -[frame_loc, argloc, vloc, tmploc] = arglocs +[argloc, vloc, result_loc, tmploc] = arglocs else: -[frame_loc, argloc, tmploc] = arglocs +[argloc, result_loc, tmploc] = arglocs vloc = imm(0) -self.call_assembler(op, guard_op, frame_loc, argloc, vloc, tmploc) -xxx +self.call_assembler(op, guard_op, argloc, vloc, result_loc, tmploc) +self._emit_guard_may_force(guard_op, +regalloc._prepare_guard(guard_op), guard_op.numargs()) +return fcond + +def _call_assembler_emit_call(self, addr, argloc, resloc): +self._emit_call(addr, [argloc], resloc=resloc) + +def _call_assembler_emit_helper_call(self, addr, arglocs, resloc): +self._emit_call(addr, arglocs, resloc=resloc) def _call_assembler_check_descr(self, value, tmploc): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') self.mc.LDR_ri(r.ip.value, tmploc.value, imm=ofs) self.mc.CMP_ri(r.ip.value, imm=value) pos = self.mc.currpos() -self.mc.BPKT() +self.mc.BKPT() return pos def _call_assembler_patch_je(self, result_loc, jmp_location): pos = self.mc.currpos() -self.mc.BPKT() +self.mc.BKPT() +# pmc = OverwritingBuilder(self.mc, jmp_location, WORD) pmc.B_offs(self.mc.currpos(), c.EQ) return pos @@ -1146,71 +1155,31 @@ if kind == FLOAT: ofs = self.cpu.unpack_arraydescr(descr) assert check_imm_arg(ofs) -assert result_loc.is_reg() +assert result_loc.is_vfp_reg() # we always have a register here, since we have to sync them # before call_assembler -self.mc.VLDR(result_loc.value, xxx) -if not check_imm_arg(t): -self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) -self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value, - cond=fast_path_cond) -t = 0 +if not check_imm_arg(ofs): +self.mc.gen_load_int(r.ip.value, ofs) +self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value) +ofs = 0 base = r.ip else: base = r.r0 -self.mc.VLDR(resloc.value, base.value, imm=t, - cond=fast_path_cond) +self.mc.VLDR(result_loc.value, base.value, imm=ofs) else: -assert resloc is r.r0 -if kind == INT: -t = unpack_interiorfielddescr(descrs.as_int)[0] +assert result_loc is r.r0 +ofs = self.cpu.unpack_arraydescr(descr) +if not check_imm_arg(ofs): +self.mc.gen_load_int(r.ip.value, ofs) +self.mc.LDR_rr(result_loc.value, result_loc.value, r.ip.value) else: -t = unpack_interiorfielddescr(descrs.as_ref)[0] -if not check_imm_arg(t): -self.mc.gen_load_int(r.ip.value, t, cond=fast_path_cond) -self.mc.LDR_rr(resloc.value, resloc.value, r.ip.value, - cond=fast_path_cond) -else: -self.mc.LDR_ri(resloc.value, resloc.value, imm=t, - cond=fast_path_cond) -# jump to merge point -jmp_pos = self.mc.currpos() -self.mc.BKPT() +self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) -# Path B: use assembler helper -asm_helper_adr = self.cpu.cast_adr_to_in
[pypy-commit] pypy stm-thread-2: Untested so far: attempt to fix signals for stm
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61318:1bf6c8d6fe7b Date: 2013-02-16 11:35 +0100 http://bitbucket.org/pypy/pypy/changeset/1bf6c8d6fe7b/ Log:Untested so far: attempt to fix signals for stm diff --git a/pypy/module/signal/__init__.py b/pypy/module/signal/__init__.py --- a/pypy/module/signal/__init__.py +++ b/pypy/module/signal/__init__.py @@ -47,5 +47,10 @@ space.check_signal_action = interp_signal.CheckSignalAction(space) space.actionflag.register_periodic_action(space.check_signal_action, use_bytecode_counter=False) -space.actionflag.__class__ = interp_signal.SignalActionFlag +# +if space.config.translation.stm: +from pypy.module.signal.stmactionflag import SignalActionFlag +else: +from pypy.module.signal.actionflag import SignalActionFlag +space.actionflag.__class__ = SignalActionFlag # xxx yes I know the previous line is a hack diff --git a/pypy/module/signal/actionflag.py b/pypy/module/signal/actionflag.py new file mode 100644 --- /dev/null +++ b/pypy/module/signal/actionflag.py @@ -0,0 +1,33 @@ +from pypy.interpreter.executioncontext import AbstractActionFlag +from rpython.rlib import jit +from rpython.rlib.rsignal import pypysig_getaddr_occurred + + +class SignalActionFlag(AbstractActionFlag): +# This class uses the C-level pypysig_counter variable as the tick +# counter. The C-level signal handler will reset it to -1 whenever +# a signal is received. This causes CheckSignalAction.perform() to +# be called. + +def get_ticker(self): +p = pypysig_getaddr_occurred() +return p.c_value + +def reset_ticker(self, value): +p = pypysig_getaddr_occurred() +p.c_value = value + +def rearm_ticker(self): +p = pypysig_getaddr_occurred() +p.c_value = -1 + +def decrement_ticker(self, by): +p = pypysig_getaddr_occurred() +value = p.c_value +if self.has_bytecode_counter:# this 'if' is constant-folded +if jit.isconstant(by) and by == 0: +pass # normally constant-folded too +else: +value -= by +p.c_value = value +return value diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -4,8 +4,7 @@ import sys from pypy.interpreter.error import OperationError, exception_from_errno -from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag, -PeriodicAsyncAction) +from pypy.interpreter.executioncontext import AsyncAction, PeriodicAsyncAction from pypy.interpreter.gateway import unwrap_spec from rpython.rlib import jit, rposix, rgc @@ -18,36 +17,6 @@ WIN32 = sys.platform == 'win32' -class SignalActionFlag(AbstractActionFlag): -# This class uses the C-level pypysig_counter variable as the tick -# counter. The C-level signal handler will reset it to -1 whenever -# a signal is received. This causes CheckSignalAction.perform() to -# be called. - -def get_ticker(self): -p = pypysig_getaddr_occurred() -return p.c_value - -def reset_ticker(self, value): -p = pypysig_getaddr_occurred() -p.c_value = value - -def rearm_ticker(self): -p = pypysig_getaddr_occurred() -p.c_value = -1 - -def decrement_ticker(self, by): -p = pypysig_getaddr_occurred() -value = p.c_value -if self.has_bytecode_counter:# this 'if' is constant-folded -if jit.isconstant(by) and by == 0: -pass # normally constant-folded too -else: -value -= by -p.c_value = value -return value - - class CheckSignalAction(PeriodicAsyncAction): """An action that is automatically invoked when a signal is received.""" diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py new file mode 100644 --- /dev/null +++ b/pypy/module/signal/stmactionflag.py @@ -0,0 +1,28 @@ +from pypy.interpreter.executioncontext import AbstractActionFlag +from rpython.rlib import jit +from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred + + +class SignalActionFlag(AbstractActionFlag): +# This is mostly a copy of actionflag.py, but written in a way +# that doesn't force atomic transactions --- but isn't very JIT +# friendly yet. + +def get_ticker(self): +return pypysig_get_occurred() + +def reset_ticker(self, value): +pypysig_set_occurred(value) + +def rearm_ticker(self): +pypysig_set_occurred(-1) + +def decrement_ticker(self, by): +value = pypysig_get_occurred() +if self.has_bytecode_counter:# this 'if' is constant-folded +if jit.isconstant(by) and by == 0: +
[pypy-commit] pypy stm-thread-2: Fix
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61319:f7cc11bdaed8 Date: 2013-02-16 11:51 +0100 http://bitbucket.org/pypy/pypy/changeset/f7cc11bdaed8/ Log:Fix diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py --- a/pypy/module/signal/stmactionflag.py +++ b/pypy/module/signal/stmactionflag.py @@ -1,5 +1,6 @@ from pypy.interpreter.executioncontext import AbstractActionFlag from rpython.rlib import jit +from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred @@ -9,20 +10,28 @@ # friendly yet. def get_ticker(self): -return pypysig_get_occurred() +if we_are_translated(): +return pypysig_get_occurred() +else: +return 42 def reset_ticker(self, value): -pypysig_set_occurred(value) +if we_are_translated(): +pypysig_set_occurred(value) def rearm_ticker(self): -pypysig_set_occurred(-1) +if we_are_translated(): +pypysig_set_occurred(-1) def decrement_ticker(self, by): -value = pypysig_get_occurred() -if self.has_bytecode_counter:# this 'if' is constant-folded -if jit.isconstant(by) and by == 0: -pass # normally constant-folded too -else: -value -= by -pypysig_set_occurred(value) -return value +if we_are_translated(): +value = pypysig_get_occurred() +if self.has_bytecode_counter:# this 'if' is constant-folded +if jit.isconstant(by) and by == 0: +pass # normally constant-folded too +else: +value -= by +pypysig_set_occurred(value) +return value +else: +return 42 ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Don't name the SignalActionFlag explicitly here.
Author: Armin Rigo Branch: Changeset: r61316:e7bbbe5d09ce Date: 2013-02-16 11:15 +0100 http://bitbucket.org/pypy/pypy/changeset/e7bbbe5d09ce/ Log:Don't name the SignalActionFlag explicitly here. diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value -@staticmethod -def rearm_ticker(): +def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False -SignalActionFlag.rearm_ticker() +self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge heads
Author: Armin Rigo Branch: Changeset: r61320:95b58361ccf1 Date: 2013-02-16 12:19 +0100 http://bitbucket.org/pypy/pypy/changeset/95b58361ccf1/ Log:merge heads diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True -def enable_signals(self): +def enable_signals(self, space): pass -def disable_signals(self): +def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): -space.threadlocals.enable_signals() +space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): -space.threadlocals.disable_signals() +space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: -spaceconfig = dict(usemodules=['__pypy__', 'thread']) - -def test_exit_twice(self, space): -from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter -signals_exit(space) -try: -raises(KeyError, signals_exit, space) -finally: -signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) +def test_exit_twice(self): +from __pypy__ import thread +thread._signals_exit() +try: +raises(KeyError, thread._signals_exit) +finally: +thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,5 @@ from rpython.rlib import rthread +from pypy.interpreter.error import OperationError class OSThreadLocals: @@ -54,14 +55,18 @@ def signals_enabled(self): return rthread.get_ident() in self._signalsenabled -def enable_signals(self): +def enable_signals(self, space): ident = rthread.get_ident() old = self._signalsenabled.get(ident, 0) self._signalsenabled[ident] = old + 1 -def disable_signals(self): +def disable_signals(self, space): ident = rthread.get_ident() -new = self._signalsenabled[ident] - 1 +try: +new = self._signalsenabled[ident] - 1 +except KeyError: +raise OperationError(space.w_KeyError, space.wrap( +"cannot disable signals in thread not enabled for signals")) if new > 0: self._signalsenabled[ident] = new else: @@ -85,9 +90,11 @@ # enable_signals() if necessary. That's a hack but I cannot # figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() -old = self._signalsenabled.get(ident, 0) -if ident is not self._mainthreadident: -self._mainthreadident = ident -old += 1 -self._signalsenabled.clear() -self._signalsenabled[ident] = old +val = self.getvalue() +sig = self._signalsenabled.get(ident, 0) +if ident != self._mainthreadident: +sig += 1 +self._cleanup_() +self.setvalue(val) +self._signalsenabled[ident] = sig +self._mainthreadident = ident diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py --- a/rpython/rlib/rstruct/ieee.py +++ b/rpython/rlib/rstruct/ieee.py @@ -255,6 +255,7 @@ l.reverse() result.append("".join(l)) +@jit.unroll_safe def unpack_float(s, be): unsigned = r_ulonglong(0) for i in range(min(len(s), 8)): @@ -262,6 +263,7 @@ unsigned |= r_ulonglong(c) << (i * 8) return float_unpack(unsigned, len(s)) +@jit.unroll_safe def unpack_float80(s, be): QQ = [r_ulonglong(0), r_ulonglong(0)] for i in range(8): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: hg merge default
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61317:8eedaf9d0459 Date: 2013-02-16 11:17 +0100 http://bitbucket.org/pypy/pypy/changeset/8eedaf9d0459/ Log:hg merge default diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -19,7 +19,7 @@ .. branch: numpypy-longdouble Long double support for numpypy .. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of +Convert real, imag from ufuncs to views. This involves the beginning of view() functionality .. branch: signatures @@ -57,7 +57,11 @@ .. branch: cleanup-tests Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -+one directory for reduced confusion and so they all run nightly. +one directory for reduced confusion and so they all run nightly. .. branch: unquote-faster .. branch: urlparse-unquote-faster + +.. branch: signal-and-thread +Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a +non-main thread to enable the processing of signal handlers in that thread. diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -1,5 +1,19 @@ import sys +from pypy.module.thread.test.support import GenericTestThread + + +class TestThreadSignal: +spaceconfig = dict(usemodules=['__pypy__', 'thread']) + +def test_exit_twice(self, space): +from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter +signals_exit(space) +try: +raises(KeyError, signals_exit, space) +finally: +signals_enter(space) + class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -11,7 +25,76 @@ # assert did not crash -class AppTestThreadSignal: +class AppTestThreadSignal(GenericTestThread): +spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) + +def test_enable_signals(self): +import __pypy__, thread, signal, time + +def subthread(): +try: +with __pypy__.thread.signals_enabled: +thread.interrupt_main() +for i in range(10): +print 'x' +time.sleep(0.1) +except BaseException, e: +interrupted.append(e) +finally: +done.append(None) + +# This is normally called by app_main.py +signal.signal(signal.SIGINT, signal.default_int_handler) + +for i in range(10): +__pypy__.thread._signals_exit() +try: +done = [] +interrupted = [] +thread.start_new_thread(subthread, ()) +for i in range(10): +if len(done): break +print '.' +time.sleep(0.1) +assert len(done) == 1 +assert len(interrupted) == 1 +assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__ +finally: +__pypy__.thread._signals_enter() + +def test_thread_fork_signals(self): +import __pypy__ +import os, thread, signal + +if not hasattr(os, 'fork'): +skip("No fork on this platform") + +def fork(): +with __pypy__.thread.signals_enabled: +return os.fork() + +def threadfunction(): +pid = fork() +if pid == 0: +print 'in child' +# signal() only works from the 'main' thread +signal.signal(signal.SIGUSR1, signal.SIG_IGN) +os._exit(42) +else: +self.timeout_killer(pid, 5) +exitcode = os.waitpid(pid, 0)[1] +feedback.append(exitcode) + +feedback = [] +thread.start_new_thread(threadfunction, ()) +self.waitfor(lambda: feedback) +# if 0, an (unraisable) exception was raised from the forked thread. +# if 9, process was killed by timer. +# if 42<<8, os._exit(42) was correctly reached. +assert feedback == [42<<8] + + +class AppTestThreadSignalLock: spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal']) def setup_class(cls): @@ -22,11 +105,11 @@ def test_enable_signals(self): import __pypy__, thread, signal, time -# + interrupted = [] lock = thread.allocate_lock() lock.acquire() -# + def subthread(): try: time.sleep(0.25) @@ -34,8 +117,9 @@ thread.interrupt_main() except BaseException, e: interrupted.append(e) -lock.release() -# +finally: +lock.release() +
[pypy-commit] pypy stm-thread-2: Probably fix stm_PtrEq, to never cause transaction aborts.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61321:effc55eb6a11 Date: 2013-02-16 15:43 +0100 http://bitbucket.org/pypy/pypy/changeset/effc55eb6a11/ Log:Probably fix stm_PtrEq, to never cause transaction aborts. diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c --- a/rpython/translator/stm/src_stm/et.c +++ b/rpython/translator/stm/src_stm/et.c @@ -676,22 +676,95 @@ // -inline static gcptr GlobalizeForComparison(struct tx_descriptor *d, gcptr P) +inline static _Bool _PtrEq_Globals(gcptr G1, gcptr G2) { - if (P != NULL && (P->h_tid & (GCFLAG_GLOBAL | GCFLAG_LOCAL_COPY))) + /* This is a bit lengthy, but (probably) efficient: the idea is to + check if G1 and G2 are pointers in the same chained list of globals + or not. Assumes no partial sharing in the chained lists. Works by + trying to search forward with S1, starting from G1, if it reaches + G2; and conversely with S2, starting from G2, if it reaches G1. */ + gcptr S1 = G1, S2 = G2; + volatile revision_t *vp; + revision_t v; + + while (1) { - if (P->h_tid & GCFLAG_GLOBAL) -P = LatestGlobalRevision(d, P, NULL, 0); - else -P = (gcptr)P->h_revision; // LOCAL_COPY: return the original global obj + if (S2 == G1) +return 1; + + /* move forward S1 */ + vp = (volatile revision_t *)&S1->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. +goto s1_end; // "doesn't have a more recent revision" + S1 = (gcptr)v; + + if (S1 == G2) +return 1; + + /* move forward S2 */ + vp = (volatile revision_t *)&S2->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. +goto s2_end; // "doesn't have a more recent revision" + S2 = (gcptr)v; } - return P; + + s1_end: + while (1) +{ + /* move forward S2 */ + vp = (volatile revision_t *)&S2->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. +return 0; // "doesn't have a more recent revision" + S2 = (gcptr)v; + + if (S2 == G1) +return 1; +} + + s2_end: + while (1) +{ + /* move forward S1 */ + vp = (volatile revision_t *)&S1->h_revision; + v = *vp; + if (v & 1) // "is not a pointer", i.e. +return 0; // "doesn't have a more recent revision" + S1 = (gcptr)v; + + if (S1 == G2) +return 1; +} } _Bool stm_PtrEq(gcptr P1, gcptr P2) { - struct tx_descriptor *d = thread_descriptor; - return GlobalizeForComparison(d, P1) == GlobalizeForComparison(d, P2); + if (P1 == P2) +return 1; + else if (P1 == NULL || P2 == NULL) /* and not P1 == P2 == NULL */ +return 0; + + if (P1->h_tid & GCFLAG_GLOBAL) +{ + if (P2->h_tid & GCFLAG_GLOBAL) +return _PtrEq_Globals(P1, P2); + else if (P2->h_tid & GCFLAG_LOCAL_COPY) +return _PtrEq_Globals(P1, (gcptr)P2->h_revision); + else +return 0; /* P1 is global, P2 is new */ +} + /* P1 is local, i.e. either new or a local copy */ + if (P2->h_tid & GCFLAG_GLOBAL) +{ + if (P1->h_tid & GCFLAG_LOCAL_COPY) +return _PtrEq_Globals((gcptr)P1->h_revision, P2); + else +return 0; /* P1 is new, P2 is global */ +} + /* P1 and P2 are both locals (and P1 != P2) */ + return 0; } // ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Argh. Disable this cache if we are running with stm.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61322:b692761b4013 Date: 2013-02-16 15:58 +0100 http://bitbucket.org/pypy/pypy/changeset/b692761b4013/ Log:Argh. Disable this cache if we are running with stm. diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py --- a/pypy/module/thread/os_local.py +++ b/pypy/module/thread/os_local.py @@ -19,6 +19,7 @@ @jit.dont_look_inside def __init__(self, space, initargs): +self.space = space self.initargs = initargs self.dicts = {} # mapping ExecutionContexts to the wraped dict # The app-level __init__() will be called by the general @@ -31,11 +32,16 @@ self.dicts[ec] = w_dict self._register_in_ec(ec) # cache the last seen dict, works because we are protected by the GIL -self.last_dict = w_dict -self.last_ec = ec +if self.can_cache(): +self.last_dict = w_dict +self.last_ec = ec + +def can_cache(self): +# can't cache with STM! The cache causes conflicts +return not self.space.config.translation.stm def _register_in_ec(self, ec): -if not ec.space.config.translation.rweakref: +if not self.space.config.translation.rweakref: return# without weakrefs, works but 'dicts' is never cleared if ec._thread_local_objs is None: ec._thread_local_objs = WRefShrinkList() @@ -44,7 +50,7 @@ @jit.dont_look_inside def create_new_dict(self, ec): # create a new dict for this thread -space = ec.space +space = self.space w_dict = space.newdict(instance=True) self.dicts[ec] = w_dict # call __init__ @@ -63,14 +69,15 @@ def getdict(self, space): ec = space.getexecutioncontext() -if ec is self.last_ec: +if self.can_cache() and ec is self.last_ec: return self.last_dict try: w_dict = self.dicts[ec] except KeyError: w_dict = self.create_new_dict(ec) -self.last_ec = ec -self.last_dict = w_dict +if self.can_cache(): +self.last_ec = ec +self.last_dict = w_dict return w_dict def descr_local__new__(space, w_subtype, __args__): diff --git a/pypy/module/thread/test/test_local.py b/pypy/module/thread/test/test_local.py --- a/pypy/module/thread/test/test_local.py +++ b/pypy/module/thread/test/test_local.py @@ -128,6 +128,7 @@ class config: class translation: rweakref = True +stm = False class FakeEC: def __init__(self, space): @@ -158,4 +159,3 @@ l.dicts = "nope" assert l.getdict(space) is d1 l.dicts = dicts - ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Needs a become_inevitable()
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61323:d3c03a277e35 Date: 2013-02-16 16:09 +0100 http://bitbucket.org/pypy/pypy/changeset/d3c03a277e35/ Log:Needs a become_inevitable() diff --git a/pypy/module/signal/stmactionflag.py b/pypy/module/signal/stmactionflag.py --- a/pypy/module/signal/stmactionflag.py +++ b/pypy/module/signal/stmactionflag.py @@ -1,5 +1,5 @@ from pypy.interpreter.executioncontext import AbstractActionFlag -from rpython.rlib import jit +from rpython.rlib import jit, rstm from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rsignal import pypysig_get_occurred, pypysig_set_occurred @@ -17,6 +17,12 @@ def reset_ticker(self, value): if we_are_translated(): +# explicit manipulation of the counter needs to turn the +# transaction inevitable. We don't turn it inevitable in +# decrement_ticker() or if a real signal is received, but +# we turn it inevitable when this condition is detected +# and we reset a value >= 0. +rstm.become_inevitable() pypysig_set_occurred(value) def rearm_ticker(self): ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Kill the section about signals.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61324:a821fcfdb066 Date: 2013-02-16 16:14 +0100 http://bitbucket.org/pypy/pypy/changeset/a821fcfdb066/ Log:Kill the section about signals. diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -3,32 +3,6 @@ -signal module: plan: - -signal handler: - -d = main thread's thread_descriptor -d->reads_size_limit = GOT_SIGNAL ( = -1) -this makes stm_should_break_transaction(d) return 1 - - -def _runs_normal_handler(): -if rstm.should_break_transaction(): -if d->reads_size_limit == GOT_SIGNAL: -checksignals() -return not rstm.should_break_transaction() -return False -return True - - -def checksignals(): -if d->reads_size_limit == GOT_SIGNAL: -turn inevitable -reset d->reads_size_limit -handle the signal - - - after an abort, keep old global_to_local and access it using special code ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: Use __pypy__.thread.signals_enabled here.
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61325:92cea4991f95 Date: 2013-02-16 16:14 +0100 http://bitbucket.org/pypy/pypy/changeset/92cea4991f95/ Log:Use __pypy__.thread.signals_enabled here. diff --git a/lib_pypy/transaction.py b/lib_pypy/transaction.py --- a/lib_pypy/transaction.py +++ b/lib_pypy/transaction.py @@ -29,6 +29,17 @@ _atomic_global_lock.release() atomic = _Atomic() +try: +from __pypy__.thread import signals_enabled +except ImportError: +# Not a PyPy at all. +class _SignalsEnabled(object): +def __enter__(self): +pass +def __exit__(self, *args): +pass +signals_enabled = _SignalsEnabled() + def set_num_threads(num): """Set the number of threads to use.""" @@ -114,11 +125,7 @@ thread.start_new_thread(self._run_thread, ()) # now wait. When we manage to acquire the following lock, then # we are finished. -try: -acquire = self.lock_if_released_then_finished.acquire_interruptible -except AttributeError: # not on pypy-stm -acquire = self.lock_if_released_then_finished.acquire -acquire() +self.lock_if_released_then_finished.acquire() def teardown(self): self.in_transaction = False @@ -203,13 +210,14 @@ def _do_it((f, args, kwds), got_exception): # this is a staticmethod in order to make sure that we don't # accidentally use 'self' in the atomic block. -with atomic: -if got_exception: -return# return early if already an exception to reraise -try: -f(*args, **kwds) -except: -got_exception[:] = sys.exc_info() +try: +with signals_enabled: +with atomic: +if got_exception: +return# return early if already an exc. to reraise +f(*args, **kwds) +except: +got_exception[:] = sys.exc_info() _thread_pool = _ThreadPool() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Kill the _signalsenabled dictionary. Replace it by a value directly
Author: Armin Rigo Branch: Changeset: r61326:5f7c2b2fcddd Date: 2013-02-16 17:33 +0100 http://bitbucket.org/pypy/pypy/changeset/5f7c2b2fcddd/ Log:Kill the _signalsenabled dictionary. Replace it by a value directly on the ExecutionContext. This avoids stm issues. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,5 +1,9 @@ from rpython.rlib import rthread -from pypy.interpreter.error import OperationError +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -10,12 +14,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} -self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() -self._signalsenabled.clear() self._mainthreadident = 0 self._mostrecentkey = 0# fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -36,7 +38,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: -self._signalsenabled[ident] = 1# the main thread is enabled +value._signals_enabled = 1# the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -44,33 +46,25 @@ del self._valuedict[ident] except KeyError: pass -try: -del self._signalsenabled[ident] -except KeyError: -pass # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): -return rthread.get_ident() in self._signalsenabled +ec = self.getvalue() +return ec._signals_enabled def enable_signals(self, space): -ident = rthread.get_ident() -old = self._signalsenabled.get(ident, 0) -self._signalsenabled[ident] = old + 1 +ec = self.getvalue() +ec._signals_enabled += 1 def disable_signals(self, space): -ident = rthread.get_ident() -try: -new = self._signalsenabled[ident] - 1 -except KeyError: -raise OperationError(space.w_KeyError, space.wrap( -"cannot disable signals in thread not enabled for signals")) -if new > 0: -self._signalsenabled[ident] = new -else: -del self._signalsenabled[ident] +ec = self.getvalue() +new = ec._signals_enabled - 1 +if new < 0: +raise wrap_thread_error(space, +"cannot disable signals in thread not enabled for signals") +ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,16 +79,10 @@ def reinit_threads(self, space): "Called in the child process after a fork()" -# clear the _signalsenabled dictionary for all other threads -# (which are now dead); and for the current thread, force an -# enable_signals() if necessary. That's a hack but I cannot -# figure out a non-hackish way to handle thread+signal+fork :-( ident = rthread.get_ident() -val = self.getvalue() -sig = self._signalsenabled.get(ident, 0) +ec = self.getvalue() if ident != self._mainthreadident: -sig += 1 +ec._signals_enabled += 1 self._cleanup_() -self.setvalue(val) -self._signalsenabled[ident] = sig +self.setvalue(ec) self._mainthreadident = ident ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy stm-thread-2: hg merge default
Author: Armin Rigo Branch: stm-thread-2 Changeset: r61327:65ec96e15463 Date: 2013-02-16 17:34 +0100 http://bitbucket.org/pypy/pypy/changeset/65ec96e15463/ Log:hg merge default diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -20,10 +20,10 @@ def signals_enabled(self): return True -def enable_signals(self): +def enable_signals(self, space): pass -def disable_signals(self): +def disable_signals(self, space): pass def getallvalues(self): diff --git a/pypy/module/__pypy__/interp_signal.py b/pypy/module/__pypy__/interp_signal.py --- a/pypy/module/__pypy__/interp_signal.py +++ b/pypy/module/__pypy__/interp_signal.py @@ -1,6 +1,6 @@ def signals_enter(space): -space.threadlocals.enable_signals() +space.threadlocals.enable_signals(space) def signals_exit(space, w_ignored1=None, w_ignored2=None, w_ignored3=None): -space.threadlocals.disable_signals() +space.threadlocals.disable_signals(space) diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -3,18 +3,6 @@ from pypy.module.thread.test.support import GenericTestThread -class TestThreadSignal: -spaceconfig = dict(usemodules=['__pypy__', 'thread']) - -def test_exit_twice(self, space): -from pypy.module.__pypy__.interp_signal import signals_exit, signals_enter -signals_exit(space) -try: -raises(KeyError, signals_exit, space) -finally: -signals_enter(space) - - class AppTestMinimal: spaceconfig = dict(usemodules=['__pypy__']) @@ -28,6 +16,14 @@ class AppTestThreadSignal(GenericTestThread): spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) +def test_exit_twice(self): +from __pypy__ import thread +thread._signals_exit() +try: +raises(KeyError, thread._signals_exit) +finally: +thread._signals_enter() + def test_enable_signals(self): import __pypy__, thread, signal, time diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,4 +1,9 @@ from rpython.rlib import rthread +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -11,12 +16,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} -self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() -self._signalsenabled.clear() self._mainthreadident = 0 if self.can_cache: self._mostrecentkey = 0# fast minicaching for the common case @@ -39,7 +42,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: -self._signalsenabled[ident] = 1# the main thread is enabled +value._signals_enabled = 1# the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -47,30 +50,26 @@ del self._valuedict[ident] except KeyError: pass -try: -del self._signalsenabled[ident] -except KeyError: -pass if self.can_cache: # update the minicache to prevent it from containing an outdated value self._mostrecentkey = ident self._mostrecentvalue = value def signals_enabled(self): -return rthread.get_ident() in self._signalsenabled +ec = self.getvalue() +return ec._signals_enabled -def enable_signals(self): -ident = rthread.get_ident() -old = self._signalsenabled.get(ident, 0) -self._signalsenabled[ident] = old + 1 +def enable_signals(self, space): +ec = self.getvalue() +ec._signals_enabled += 1 -def disable_signals(self): -ident = rthread.get_ident() -new = self._signalsenabled[ident] - 1 -if new > 0: -self._signalsenabled[ident] = new -else: -del self._signalsenabled[ident] +def disable_signals(self, space): +ec = self.getvalue() +new = ec._signals_enabled - 1 +if new < 0: +raise wrap_thread_error(space, +"cannot disable signals in thread not enabled for signals") +ec._signals_enabled = new def getallvalues(self): return self._valuedict @@ -85,14 +84,1
[pypy-commit] pypy default: (alex, arigo) Make sure this value is immutable, otherwise traces are suboptimal
Author: Alex Gaynor Branch: Changeset: r61328:f8fe57996da9 Date: 2013-02-16 10:48 -0800 http://bitbucket.org/pypy/pypy/changeset/f8fe57996da9/ Log:(alex, arigo) Make sure this value is immutable, otherwise traces are suboptimal diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() -# Precompute what arguments need to be copied into cellvars -self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! -argvars = self.co_varnames + +# Precompute what arguments need to be copied into cellvars +args_as_cellvars = [] +argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i -while len(self._args_as_cellvars) <= i: -self._args_as_cellvars.append(-1) # pad -self._args_as_cellvars[i] = j +while len(args_as_cellvars) <= i: +args_as_cellvars.append(-1) # pad +args_as_cellvars[i] = j +self._args_as_cellvars = args_as_cellvars[:] +else: +self._args_as_cellvars = [] self._compute_flatcall() ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix
Author: Maciej Fijalkowski Branch: Changeset: r61329:9c21a81579d9 Date: 2013-02-16 11:09 + http://bitbucket.org/pypy/pypy/changeset/9c21a81579d9/ Log:fix diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -395,13 +395,18 @@ assert not int_between(1, 2, 2) assert not int_between(1, 1, 1) +U1 = r_ulonglong(0x0102030405060708L) +U2 = r_ulonglong(0x0807060504030201L) +S1 = r_longlong(0x0102030405060708L) +S2 = r_longlong(0x0807060504030201L) + def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 -assert byteswap(r_ulonglong(0x0102030405060708L)) == r_ulonglong(0x0807060504030201L) -assert byteswap(r_longlong(0x0102030405060708L)) == r_longlong(0x0807060504030201L) +assert byteswap(U1) == U2 +assert byteswap(S1) == S2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.01 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: merge
Author: Maciej Fijalkowski Branch: Changeset: r61330:36e9ac53a32b Date: 2013-02-16 21:46 +0100 http://bitbucket.org/pypy/pypy/changeset/36e9ac53a32b/ Log:merge diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -53,16 +53,17 @@ kwargname = None return Signature(argnames, varargname, kwargname) + class PyCode(eval.Code): "CPython-style code objects." _immutable_ = True _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]", - "co_freevars[*]", "co_cellvars[*]"] + "co_freevars[*]", "co_cellvars[*]", "_args_as_cellvars[*]"] def __init__(self, space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False, magic = default_magic): + hidden_applevel=False, magic=default_magic): """Initialize a new code object from parameters given by the pypy compiler""" self.space = space @@ -89,8 +90,6 @@ def _initialize(self): self._init_flags() -# Precompute what arguments need to be copied into cellvars -self._args_as_cellvars = [] if self.co_cellvars: argcount = self.co_argcount @@ -108,16 +107,22 @@ # produced by CPython are loaded by PyPy. Note that CPython # contains the following bad-looking nested loops at *every* # function call! -argvars = self.co_varnames + +# Precompute what arguments need to be copied into cellvars +args_as_cellvars = [] +argvars = self.co_varnames cellvars = self.co_cellvars for i in range(len(cellvars)): cellname = cellvars[i] for j in range(argcount): if cellname == argvars[j]: # argument j has the same name as the cell var i -while len(self._args_as_cellvars) <= i: -self._args_as_cellvars.append(-1) # pad -self._args_as_cellvars[i] = j +while len(args_as_cellvars) <= i: +args_as_cellvars.append(-1) # pad +args_as_cellvars[i] = j +self._args_as_cellvars = args_as_cellvars[:] +else: +self._args_as_cellvars = [] self._compute_flatcall() diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -32,8 +32,7 @@ p = pypysig_getaddr_occurred() p.c_value = value -@staticmethod -def rearm_ticker(): +def rearm_ticker(self): p = pypysig_getaddr_occurred() p.c_value = -1 @@ -71,7 +70,7 @@ if self.fire_in_another_thread: if self.space.threadlocals.signals_enabled(): self.fire_in_another_thread = False -SignalActionFlag.rearm_ticker() +self.space.actionflag.rearm_ticker() # this occurs when we just switched to the main thread # and there is a signal pending: we force the ticker to # -1, which should ensure perform() is called quickly. diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -1,5 +1,9 @@ from rpython.rlib import rthread -from pypy.interpreter.error import OperationError +from pypy.module.thread.error import wrap_thread_error +from pypy.interpreter.executioncontext import ExecutionContext + + +ExecutionContext._signals_enabled = 0 # default value class OSThreadLocals: @@ -10,12 +14,10 @@ def __init__(self): self._valuedict = {} # {thread_ident: ExecutionContext()} -self._signalsenabled = {} # {thread_ident: number-of-times} self._cleanup_() def _cleanup_(self): self._valuedict.clear() -self._signalsenabled.clear() self._mainthreadident = 0 self._mostrecentkey = 0# fast minicaching for the common case self._mostrecentvalue = None # fast minicaching for the common case @@ -36,7 +38,7 @@ ident = rthread.get_ident() if value is not None: if len(self._valuedict) == 0: -self._signalsenabled[ident] = 1# the main thread is enabled +value._signals_enabled = 1# the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value else: @@ -44,33 +46,25 @@ del self._valuedict[ident] except KeyError:
[pypy-commit] pypy jitframe-on-heap: cleanup
Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61331:c56108e2bdc3 Date: 2013-02-16 23:11 +0200 http://bitbucket.org/pypy/pypy/changeset/c56108e2bdc3/ Log:cleanup diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -1158,22 +1158,12 @@ assert result_loc.is_vfp_reg() # we always have a register here, since we have to sync them # before call_assembler -if not check_imm_arg(ofs): -self.mc.gen_load_int(r.ip.value, ofs) -self.mc.ADD_rr(r.ip.value, r.r0.value, r.ip.value) -ofs = 0 -base = r.ip -else: -base = r.r0 -self.mc.VLDR(result_loc.value, base.value, imm=ofs) +self.mc.VLDR(result_loc.value, r.r0.value, imm=ofs) else: assert result_loc is r.r0 ofs = self.cpu.unpack_arraydescr(descr) -if not check_imm_arg(ofs): -self.mc.gen_load_int(r.ip.value, ofs) -self.mc.LDR_rr(result_loc.value, result_loc.value, r.ip.value) -else: -self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) +assert check_imm_arg(ofs) +self.mc.LDR_ri(result_loc.value, result_loc.value, imm=ofs) def _call_assembler_patch_jmp(self, jmp_location): # merge point ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: make this test failure more obvious
Author: Brian Kearns Branch: Changeset: r61332:b5e96acf8bd1 Date: 2013-02-16 05:39 -0500 http://bitbucket.org/pypy/pypy/changeset/b5e96acf8bd1/ Log:make this test failure more obvious diff --git a/pypy/module/test_lib_pypy/numpypy/test_numpy.py b/pypy/module/test_lib_pypy/numpypy/test_numpy.py --- a/pypy/module/test_lib_pypy/numpypy/test_numpy.py +++ b/pypy/module/test_lib_pypy/numpypy/test_numpy.py @@ -10,9 +10,21 @@ import numpy # works after 'numpypy' has been imported def test_min_max_after_import(self): +import __builtin__ + from numpypy import * +assert min is __builtin__.min +assert max is __builtin__.max + assert min(1, 100) == 1 assert min(100, 1) == 1 assert max(1, 100) == 100 assert max(100, 1) == 100 + +assert min(4, 3, 2, 1) == 1 +assert max(1, 2, 3, 4) == 4 + +from numpypy import min, max +assert min is not __builtin__.min +assert max is not __builtin__.max ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix the test: this now raises a thread.error
Author: Brian Kearns Branch: Changeset: r61333:b53715e21d4d Date: 2013-02-16 16:09 -0500 http://bitbucket.org/pypy/pypy/changeset/b53715e21d4d/ Log:fix the test: this now raises a thread.error diff --git a/pypy/module/__pypy__/test/test_signal.py b/pypy/module/__pypy__/test/test_signal.py --- a/pypy/module/__pypy__/test/test_signal.py +++ b/pypy/module/__pypy__/test/test_signal.py @@ -17,12 +17,12 @@ spaceconfig = dict(usemodules=['__pypy__', 'thread', 'signal', 'time']) def test_exit_twice(self): -from __pypy__ import thread -thread._signals_exit() +import __pypy__, thread +__pypy__.thread._signals_exit() try: -raises(KeyError, thread._signals_exit) +raises(thread.error, __pypy__.thread._signals_exit) finally: -thread._signals_enter() +__pypy__.thread._signals_enter() def test_enable_signals(self): import __pypy__, thread, signal, time ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: fix thread+fork+signals after _signalsenabled dict removal
Author: Brian Kearns Branch: Changeset: r61334:6bf80dae95f7 Date: 2013-02-16 16:19 -0500 http://bitbucket.org/pypy/pypy/changeset/6bf80dae95f7/ Log:fix thread+fork+signals after _signalsenabled dict removal diff --git a/pypy/module/thread/threadlocals.py b/pypy/module/thread/threadlocals.py --- a/pypy/module/thread/threadlocals.py +++ b/pypy/module/thread/threadlocals.py @@ -37,7 +37,7 @@ def setvalue(self, value): ident = rthread.get_ident() if value is not None: -if len(self._valuedict) == 0: +if self._mainthreadident == 0: value._signals_enabled = 1# the main thread is enabled self._mainthreadident = ident self._valuedict[ident] = value @@ -84,5 +84,5 @@ if ident != self._mainthreadident: ec._signals_enabled += 1 self._cleanup_() +self._mainthreadident = ident self.setvalue(ec) -self._mainthreadident = ident ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: 2to3, fix fix fix
Author: Philip Jenvey Branch: py3k Changeset: r61335:2664c3cf8d21 Date: 2013-02-16 13:17 -0800 http://bitbucket.org/pypy/pypy/changeset/2664c3cf8d21/ Log:2to3, fix fix fix diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -689,7 +689,7 @@ executable = sys.pypy_find_executable(executable) stdlib_path = sys.pypy_find_stdlib(executable) if stdlib_path is None: -print >> sys.stderr, STDLIB_WARNING +print(STDLIB_WARNING, file=sys.stderr) else: sys.path[:] = stdlib_path # from this point on, we are free to use all the unicode stuff we want, diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py --- a/pypy/interpreter/test2/test_app_main.py +++ b/pypy/interpreter/test2/test_app_main.py @@ -187,7 +187,6 @@ def test_sysflags(self): flags = ( ("debug", "-d", "1"), -("py3k_warning", "-3", "1"), ("division_warning", "-Qwarn", "1"), ("division_warning", "-Qwarnall", "2"), ("division_new", "-Qnew", "1"), @@ -215,9 +214,9 @@ run_command='pass', **expected) def test_sysflags_envvar(self, monkeypatch): -monkeypatch.setenv('PYTHONNOUSERSITE', '1') expected = {"no_user_site": True} -self.check(['-c', 'pass'], {}, sys_argv=['-c'], run_command='pass', **expected) +self.check(['-c', 'pass'], {'PYTHONNOUSERSITE': '1'}, sys_argv=['-c'], + run_command='pass', **expected) class TestInteraction: @@ -251,10 +250,10 @@ child.logfile = sys.stdout return child -def spawn(self, argv): +def spawn(self, argv, env=None): # make sure that when we do 'import pypy' we get the correct package with setpythonpath(): -return self._spawn(python3, [app_main] + argv) +return self._spawn(python3, [app_main] + argv, env=env) def test_interactive(self): child = self.spawn([]) @@ -362,6 +361,7 @@ child.expect(re.escape(repr('NameError'))) def test_atexit(self): +skip("Python3 atexit is a builtin module") child = self.spawn([]) child.expect('>>> ') child.sendline('def f(): print("foobye")') @@ -399,7 +399,7 @@ child.expect('Traceback') child.expect('NameError') -def test_pythonstartup_file1(self, monkeypatch): +def test_pythonstartup_file1(self, monkeypatch, demo_script): monkeypatch.setenv('PYTHONPATH', None) monkeypatch.setenv('PYTHONSTARTUP', demo_script) child = self.spawn([]) @@ -413,7 +413,7 @@ child.expect('Traceback') child.expect('NameError') -def test_pythonstartup_file2(self, monkeypatch): +def test_pythonstartup_file2(self, monkeypatch, crashing_demo_script): monkeypatch.setenv('PYTHONPATH', None) monkeypatch.setenv('PYTHONSTARTUP', crashing_demo_script) child = self.spawn([]) @@ -447,8 +447,8 @@ def test_python_path_keeps_duplicates(self): old = os.environ.get('PYTHONPATH', '') try: -os.environ['PYTHONPATH'] = 'foobarbaz:foobarbaz' -child = self.spawn(['-c', 'import sys; print sys.path']) +child = self.spawn(['-c', 'import sys; print(sys.path)'], + env={'PYTHONPATH': 'foobarbaz:foobarbaz'}) child.expect(r"\['', 'foobarbaz', 'foobarbaz', ") finally: os.environ['PYTHONPATH'] = old @@ -457,7 +457,7 @@ old = os.environ.get('PYTHONPATH', '') try: os.environ['PYTHONPATH'] = 'foobarbaz' -child = self.spawn(['-E', '-c', 'import sys; print sys.path']) +child = self.spawn(['-E', '-c', 'import sys; print(sys.path)']) from pexpect import EOF index = child.expect(['foobarbaz', EOF]) assert index == 1 # no foobarbaz @@ -742,10 +742,11 @@ print 'POPEN:', cmdline child_in, child_out_err = os.popen4(cmdline) data = child_out_err.read(11) -assert data == '\x00[STDERR]\n\x00'# from stderr +# Py3 is always at least line buffered +assert data == '\x00(STDOUT)\n\x00'# from stdout child_in.close() data = child_out_err.read(11) -assert data == '\x00(STDOUT)\n\x00'# from stdout +assert data == '\x00[STDERR]\n\x00'# from stderr child_out_err.close() def test_non_interactive_stdout_unbuffered(self, monkeypatch): @@ -758,7 +759,7 @@ time.sleep(1) # stdout flushed automatically here """) -cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path) +cmdline = '%s -E "%s" %s' % (python3, app_main, path) print 'POPEN:', cmdline child_in, child_out_err = os.popen4(cmdline)
[pypy-commit] pypy jitframe-on-heap: disable debug when we're translated
Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61336:b41f1cbf3d8f Date: 2013-02-16 23:35 +0200 http://bitbucket.org/pypy/pypy/changeset/b41f1cbf3d8f/ Log:disable debug when we're translated diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -69,6 +69,8 @@ def setup(self, looptoken): assert self.memcpy_addr != 0, 'setup_once() not called?' +if we_are_translated(): +self.debug = False self.current_clt = looptoken.compiled_loop_token self.mc = ARMv7Builder() self.pending_guards = [] ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: update sys.flags: add quiet, remove others
Author: Philip Jenvey Branch: py3k Changeset: r61337:60025b983898 Date: 2013-02-16 14:38 -0800 http://bitbucket.org/pypy/pypy/changeset/60025b983898/ Log:update sys.flags: add quiet, remove others diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py --- a/lib_pypy/_pypy_interact.py +++ b/lib_pypy/_pypy_interact.py @@ -4,7 +4,7 @@ import os -def interactive_console(mainmodule=None): +def interactive_console(mainmodule=None, quiet=False): # set sys.{ps1,ps2} just before invoking the interactive interpreter. This # mimics what CPython does in pythonrun.c if not hasattr(sys, 'ps1'): @@ -12,17 +12,18 @@ if not hasattr(sys, 'ps2'): sys.ps2 = ' ' # -try: -from _pypy_irc_topic import some_topic -text = "And now for something completely different: ``%s''" % ( -some_topic(),) -while len(text) >= 80: -i = text[:80].rfind(' ') -print(text[:i]) -text = text[i+1:] -print(text) -except ImportError: -pass +if not quiet: +try: +from _pypy_irc_topic import some_topic +text = "And now for something completely different: ``%s''" % ( +some_topic(),) +while len(text) >= 80: +i = text[:80].rfind(' ') +print(text[:i]) +text = text[i+1:] +print(text) +except ImportError: +pass # try: if not os.isatty(sys.stdin.fileno()): diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -299,9 +299,7 @@ # Order is significant! sys_flags = ( "debug", -"py3k_warning", "division_warning", -"division_new", "inspect", "interactive", "optimize", @@ -309,10 +307,9 @@ "no_user_site", "no_site", "ignore_environment", -"tabcheck", "verbose", -"unicode", "bytes_warning", +"quiet", "hash_randomization", ) @@ -327,16 +324,6 @@ def simple_option(options, name, iterargv): options[name] += 1 -def div_option(options, div, iterargv): -if div == "warn": -options["division_warning"] = 1 -elif div == "warnall": -options["division_warning"] = 2 -elif div == "new": -options["division_new"] = 1 -elif div != "old": -raise CommandLineError("invalid division option: %r" % (div,)) - def c_option(options, runcmd, iterargv): options["run_command"] = runcmd return ['-c'] + list(iterargv) @@ -362,11 +349,10 @@ 'R': (simple_option, 'hash_randomization'), 's': (simple_option, 'no_user_site'), 'S': (simple_option, 'no_site'), -'t': (simple_option, 'tabcheck'), -'U': (simple_option, 'unicode'), 'u': (simple_option, 'unbuffered'), 'b': (simple_option, 'bytes_warning'), 'v': (simple_option, 'verbose'), +'q': (simple_option, 'quiet'), # more complex options 'c': (c_option,Ellipsis), '?': (print_help, None), @@ -376,7 +362,6 @@ 'W': (W_option,Ellipsis), 'V': (print_version, None), '--version': (print_version, None), -'Q': (div_option, Ellipsis), '--info':(print_info, None), '--jit': (set_jit_option, Ellipsis), '--':(end_options, None), @@ -465,13 +450,8 @@ if we_are_translated(): flags = [options[flag] for flag in sys_flags] sys.flags = type(sys.flags)(flags) -sys.py3kwarning = bool(sys.flags.py3k_warning) sys.dont_write_bytecode = bool(sys.flags.dont_write_bytecode) -if sys.py3kwarning: -print("Warning: pypy does not implement py3k warnings", - file=sys.stderr) - ##if not we_are_translated(): ##for key in sorted(options): ##print '%40s: %s' % (key, options[key]) @@ -493,6 +473,7 @@ warnoptions, unbuffered, ignore_environment, + quiet, **ignored): # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package @@ -577,9 +558,11 @@ sys.path.insert(0, '') if interactive or sys.stdin.isatty(): -# If stdin is a tty or if "-i" is specified, we print -# a banner and run $PYTHONSTARTUP. -print_banner() +# If stdin is a tty or if "-i" is specified, we print a +# banner (unless "-q" was specified) and run +# $PYTHONSTARTUP. +if not quiet: +print_banner() python_startup = readenv and os.getenv('PYTHONSTARTUP') if python_startup: try: @@ -655,7 +638,7 @@ int
[pypy-commit] pypy jitframe-on-heap: disable the debug to have less assembler to read
Author: Maciej Fijalkowski Branch: jitframe-on-heap Changeset: r61338:4c8a7712012c Date: 2013-02-17 00:43 +0200 http://bitbucket.org/pypy/pypy/changeset/4c8a7712012c/ Log:disable the debug to have less assembler to read diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -42,7 +42,7 @@ class AssemblerARM(ResOpAssembler): -debug = True +debug = False def __init__(self, cpu, translate_support_code=False): ResOpAssembler.__init__(self, cpu, translate_support_code) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: try to fix test_rarithmetic again, this time on 64bit
Author: Brian Kearns Branch: Changeset: r61339:e589c0ef83d7 Date: 2013-02-16 19:50 -0500 http://bitbucket.org/pypy/pypy/changeset/e589c0ef83d7/ Log:try to fix test_rarithmetic again, this time on 64bit diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -15,7 +15,6 @@ #print machbits - class Test_r_int: def test__add__(self): self.binary_test(lambda x, y: x + y) @@ -57,7 +56,7 @@ res = f(arg) cmp = f(r_int(arg)) assert res == cmp - + def binary_test(self, f, rargs = None): if not rargs: rargs = (-10, -1, 3, 55) @@ -118,7 +117,7 @@ res = f(arg) & maxint_mask cmp = f(r_uint(arg)) assert res == cmp - + def binary_test(self, f, rargs = None, translated=False): mask = maxint_mask if not rargs: @@ -243,7 +242,7 @@ except OverflowError: pass else: -assert False +assert False try: ovfcheck(x+x) except OverflowError: @@ -261,7 +260,7 @@ except OverflowError: pass else: -assert False +assert False def test_ovfcheck_float_to_int(): assert ovfcheck_float_to_int(1.0) == 1 @@ -395,18 +394,17 @@ assert not int_between(1, 2, 2) assert not int_between(1, 1, 1) -U1 = r_ulonglong(0x0102030405060708L) -U2 = r_ulonglong(0x0807060504030201L) -S1 = r_longlong(0x0102030405060708L) -S2 = r_longlong(0x0807060504030201L) +# these can't be prebuilt on 32bit +L1 = 0x0102030405060708L +L2 = 0x0807060504030201L def test_byteswap(): from rpython.rtyper.lltypesystem import rffi, lltype - + assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.USHORT, 0x0102))) == 0x0201 assert rffi.cast(lltype.Signed, byteswap(rffi.cast(rffi.INT, 0x01020304))) == 0x04030201 -assert byteswap(U1) == U2 -assert byteswap(S1) == S2 +assert byteswap(rffi.cast(rffi.LONGLONG, L1)) == L2 +assert byteswap(rffi.cast(rffi.ULONGLONG, L1)) == L2 assert ((byteswap(2.3) - 1.903598566252326e+185) / 1e185) < 0.01 assert (rffi.cast(lltype.Float, byteswap(rffi.cast(lltype.SingleFloat, 2.3))) - 4.173496037651603e-08) < 1e-16 ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy jitframe-on-heap: refactor load, store and move helper methods.
Author: David Schneider Branch: jitframe-on-heap Changeset: r61340:413242473067 Date: 2013-02-17 02:56 +0100 http://bitbucket.org/pypy/pypy/changeset/413242473067/ Log:refactor load, store and move helper methods. Use imm offsets for VLDR and VSTR if possible diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -949,47 +949,8 @@ faildescr._arm_failure_recovery_block = 0 # regalloc support -def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): -if target.is_vfp_reg(): -return self._load_vfp_reg(mc, target, base, ofs, cond) -elif target.is_reg(): -return self._load_core_reg(mc, target, base, ofs, cond) - -def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): -if check_imm_arg(ofs): -mc.VLDR(target.value, base.value, imm=ofs, cond=cond) -else: -mc.gen_load_int(helper.value, ofs) -mc.VLDR(target.value, base.value, helper.value, cond=cond) - -def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): -if check_imm_arg(ofs): -mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) -else: -mc.gen_load_int(helper.value, ofs) -mc.LDR_rr(target.value, base.value, helper.value, cond=cond) - -def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): -if source.is_vfp_reg(): -return self._store_vfp_reg(mc, source, base, ofs, cond) -else: -return self._store_core_reg(mc, source, base, ofs, cond) - -def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): -if check_imm_arg(ofs): -mc.VSTR(source.value, base.value, imm=ofs, cond=cond) -else: -mc.gen_load_int(helper.value, ofs) -mc.VSTR(source.value, base.value, helper.value, cond=cond) - -def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): -if check_imm_arg(ofs): -mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) -else: -gen_load_int(helper.value, ofs) -mc.STR_rr(source.value, base.value, helper.value, cond=cond) - def load(self, loc, value): +"""load an immediate value into a register""" assert (loc.is_reg() and value.is_imm() or loc.is_vfp_reg() and value.is_imm_float()) if value.is_imm(): @@ -998,6 +959,48 @@ self.mc.gen_load_int(r.ip.value, value.getint()) self.mc.VLDR(loc.value, r.ip.value) +def load_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): +if target.is_vfp_reg(): +return self._load_vfp_reg(mc, target, base, ofs, cond, helper) +elif target.is_reg(): +return self._load_core_reg(mc, target, base, ofs, cond, helper) + +def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): +if check_imm_arg(ofs): +mc.VLDR(target.value, base.value, imm=ofs, cond=cond) +else: +mc.gen_load_int(helper.value, ofs, cond=cond) +mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) +mc.VLDR(target.value, helper.value, cond=cond) + +def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip): +if check_imm_arg(ofs): +mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond) +else: +mc.gen_load_int(helper.value, ofs, cond=cond) +mc.LDR_rr(target.value, base.value, helper.value, cond=cond) + +def store_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): +if source.is_vfp_reg(): +return self._store_vfp_reg(mc, source, base, ofs, cond, helper) +else: +return self._store_core_reg(mc, source, base, ofs, cond, helper) + +def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): +if check_imm_arg(ofs): +mc.VSTR(source.value, base.value, imm=ofs, cond=cond) +else: +mc.gen_load_int(helper.value, ofs, cond=cond) +mc.ADD_rr(helper.value, base.value, helper.value, cond=cond) +mc.VSTR(source.value, helper.value, cond=cond) + +def _store_core_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip): +if check_imm_arg(ofs): +mc.STR_ri(source.value, base.value, imm=ofs, cond=cond) +else: +mc.gen_load_int(helper.value, ofs, cond=cond) +mc.STR_rr(source.value, base.value, helper.value, cond=cond) + def _mov_imm_to_loc(self, prev_loc, loc, cond=c.AL): if not loc.is_reg() and not (loc.is_stack() and loc.type != FLOAT): raise AssertionError("invalid target for move from imm value") @@ -1025,15 +1028,12 @@ else: temp = r.ip
[pypy-commit] pypy jitframe-on-heap: fix for call_assembler with floats. The offset calculation for the arguments to call_assembler in rewrite.py assumes a double-word aligned JITFRAME
Author: David Schneider Branch: jitframe-on-heap Changeset: r61341:017892f48c74 Date: 2013-02-17 02:59 +0100 http://bitbucket.org/pypy/pypy/changeset/017892f48c74/ Log:fix for call_assembler with floats. The offset calculation for the arguments to call_assembler in rewrite.py assumes a double-word aligned JITFRAME diff --git a/rpython/jit/backend/arm/arch.py b/rpython/jit/backend/arm/arch.py --- a/rpython/jit/backend/arm/arch.py +++ b/rpython/jit/backend/arm/arch.py @@ -17,4 +17,4 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 11 + 16 * 2 # 11 GPR + 16 VFP Regs (64bit) +JITFRAME_FIXED_SIZE = 12 + 16 * 2 # 11 GPR + one word to keep alignment + 16 VFP Regs (64bit) diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py --- a/rpython/jit/backend/llsupport/rewrite.py +++ b/rpython/jit/backend/llsupport/rewrite.py @@ -179,6 +179,9 @@ for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) +# XXX +# this calculation breaks for floats on 32 bit if +# base_ofs of JITFRAME + index * 8 is not double-word aligned index = index_list[i] // itemsize # index is in bytes self.newops.append(ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: remove some dead imports, some PEP8, general cleanups
Author: Alex Gaynor Branch: Changeset: r61342:5d31d8fd913b Date: 2013-02-16 21:12 -0800 http://bitbucket.org/pypy/pypy/changeset/5d31d8fd913b/ Log:remove some dead imports, some PEP8, general cleanups diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py --- a/rpython/rtyper/annlowlevel.py +++ b/rpython/rtyper/annlowlevel.py @@ -2,18 +2,18 @@ The code needed to flow and annotate low-level helpers -- the ll_*() functions """ -import types -from rpython.tool.sourcetools import valid_identifier from rpython.annotator import model as annmodel from rpython.annotator.policy import AnnotatorPolicy, Sig from rpython.annotator.specialize import flatten_star_args +from rpython.flowspace.model import Constant +from rpython.rlib.objectmodel import specialize +from rpython.rtyper import extregistry from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.ootypesystem import ootype -from rpython.rtyper import extregistry -from rpython.flowspace.model import Constant +from rpython.rtyper.rmodel import warning +from rpython.tool.sourcetools import valid_identifier from rpython.translator.simplify import get_functype -from rpython.rtyper.rmodel import warning -from rpython.rlib.objectmodel import specialize + class KeyComp(object): def __init__(self, val): @@ -34,7 +34,7 @@ if compact is None: s = repr(val) else: -s = compact() +s = compact() return s + 'Const' __repr__ = __str__ @@ -90,7 +90,7 @@ args_s[:] = [l2a(a2l(s)) for s in args_s] return LowLevelAnnotatorPolicy.default_specialize(funcdesc, args_s) specialize__semierased = staticmethod(specialize__semierased) - + specialize__ll = default_specialize def specialize__ll_and_arg(funcdesc, args_s, *argindices): @@ -103,7 +103,7 @@ def annotate_lowlevel_helper(annotator, ll_function, args_s, policy=None): if policy is None: -policy= LowLevelAnnotatorPolicy() +policy = LowLevelAnnotatorPolicy() return annotator.annotate_helper(ll_function, args_s, policy) # ___ @@ -380,7 +380,7 @@ else: FUNC = F.TO resultcls = annmodel.SomePtr - + args_s = [annmodel.lltype_to_annotation(T) for T in FUNC.ARGS] key = (llhelper, s_callable.const) s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s) @@ -603,7 +603,7 @@ assert s.islower() def expand(s_self, *args_s): assert isinstance(s_self, annmodel.SomePtr) -return getattr(s_self.ll_ptrtype.TO, s.upper()) +return getattr(s_self.ll_ptrtype.TO, s.upper()) return expand def typemeth_placeholder_sigarg(s): @@ -622,10 +622,10 @@ def expand(s_TYPE, *args_s): assert isinstance(s_TYPE, annmodel.SomePBC) assert s_TYPE.is_constant() -return getattr(s_TYPE.const, s.upper()) +return getattr(s_TYPE.const, s.upper()) return expand - + class ADTInterface(object): def __init__(self, base, sigtemplates): diff --git a/rpython/rtyper/exceptiondata.py b/rpython/rtyper/exceptiondata.py --- a/rpython/rtyper/exceptiondata.py +++ b/rpython/rtyper/exceptiondata.py @@ -1,6 +1,6 @@ -from rpython.rtyper import rclass from rpython.annotator import model as annmodel from rpython.rlib import rstackovf +from rpython.rtyper import rclass # the exceptions that can be implicitely raised by some operations @@ -38,16 +38,16 @@ r_instance = rclass.getinstancerepr(rtyper, None) r_type.setup() r_instance.setup() -self.r_exception_type = r_type +self.r_exception_type = r_type self.r_exception_value = r_instance -self.lltype_of_exception_type = r_type.lowleveltype +self.lltype_of_exception_type = r_type.lowleveltype self.lltype_of_exception_value = r_instance.lowleveltype self.rtyper = rtyper def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper for cls in self.standardexceptions: -classdef = bk.getuniqueclassdef(cls) +bk.getuniqueclassdef(cls) def finish(self, rtyper): bk = rtyper.annotator.bookkeeper diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -1,17 +1,20 @@ -from rpython.flowspace.model import FunctionGraph, Constant, Variable, c_last_exception -from rpython.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong, r_longlonglong -from rpython.rlib.rarithmetic import r_ulonglong, is_valid_int -from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap -from rpython.rtyper.lltypesystem import rclass +import cStringIO +import os +import sys +import traceback + +import p