[pypy-commit] pypy guard-compatible: merge default
cfbolz
pypy.commits at gmail.com
Fri Mar 25 17:15:40 EDT 2016
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: guard-compatible
Changeset: r83375:ba422164355b
Date: 2016-03-25 09:25 +0100
http://bitbucket.org/pypy/pypy/changeset/ba422164355b/
Log: merge default
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -19,3 +19,4 @@
850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0
5f8302b8bf9f53056e40426f10c72151564e5b19 release-4.0.1
246c9cf22037b11dc0e8c29ce3f291d3b8c5935a release-5.0
+bbd45126bc691f669c4ebdfbd74456cd274c6b92 release-5.0.1
diff --git a/pypy/doc/config/translation.gc.txt b/pypy/doc/config/translation.gc.txt
--- a/pypy/doc/config/translation.gc.txt
+++ b/pypy/doc/config/translation.gc.txt
@@ -1,24 +1,26 @@
Choose the Garbage Collector used by the translated program.
-The good performing collectors are "hybrid" and "minimark".
-The default is "minimark".
+The recommended default is "incminimark".
- "ref": reference counting. Takes very long to translate and the result is
- slow.
+ slow. Used only for tests. Don't use it for real RPython programs.
- - "marksweep": naive mark & sweep.
+ - "none": no GC. Leaks everything. Don't use it for real RPython
+ programs: the rate of leaking is immense.
- "semispace": a copying semi-space GC.
- "generation": a generational GC using the semi-space GC for the
older generation.
- - "boehm": use the Boehm conservative GC.
-
- "hybrid": a hybrid collector of "generation" together with a
mark-n-sweep old space
- - "markcompact": a slow, but memory-efficient collector,
- influenced e.g. by Smalltalk systems.
+ - "boehm": use the Boehm conservative GC.
- "minimark": a generational mark-n-sweep collector with good
performance. Includes page marking for large arrays.
+
+ - "incminimark": like minimark, but adds incremental major
+ collections. Seems to come with no performance drawback over
+ "minimark", so it is the default. A few recent features of PyPy
+ (like cpyext) are only working with this GC.
diff --git a/pypy/doc/extradoc.rst b/pypy/doc/extradoc.rst
--- a/pypy/doc/extradoc.rst
+++ b/pypy/doc/extradoc.rst
@@ -80,7 +80,7 @@
.. _How to *not* write Virtual Machines for Dynamic Languages: https://bitbucket.org/pypy/extradoc/raw/tip/talk/dyla2007/dyla.pdf
.. _`Tracing the Meta-Level: PyPy's Tracing JIT Compiler`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/icooolps2009/bolz-tracing-jit.pdf
.. _`Faster than C#: Efficient Implementation of Dynamic Languages on .NET`: https://bitbucket.org/pypy/extradoc/raw/tip/talk/icooolps2009-dotnet/cli-jit.pdf
-.. _Automatic JIT Compiler Generation with Runtime Partial Evaluation: http://wwwold.cobra.cs.uni-duesseldorf.de/thesis/final-master.pdf
+.. _Automatic JIT Compiler Generation with Runtime Partial Evaluation: http://stups.hhu.de/mediawiki/images/b/b9/Master_bolz.pdf
.. _`RPython: A Step towards Reconciling Dynamically and Statically Typed OO Languages`: http://www.disi.unige.it/person/AnconaD/papers/DynamicLanguages_abstracts.html#AACM-DLS07
.. _EU Reports: index-report.html
.. _Hardware Transactional Memory Support for Lightweight Dynamic Language Evolution: http://sabi.net/nriley/pubs/dls6-riley.pdf
diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
.. toctree::
+ release-5.0.1.rst
release-5.0.0.rst
release-4.0.1.rst
release-4.0.0.rst
diff --git a/pypy/doc/release-5.0.1.rst b/pypy/doc/release-5.0.1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-5.0.1.rst
@@ -0,0 +1,40 @@
+==========
+PyPy 5.0.1
+==========
+
+We have released a bugfix for PyPy 5.0, after reports that the newly released
+`lxml 3.6.0`_, which now supports PyPy 5.0 +, can `crash on large files`_.
+Thanks to those who reported the crash. Please update, downloads are available
+at pypy.org/download.html
+
+.. _`lxml 3.6.0`: https://pypi.python.org/pypi/lxml/3.6.0
+.. _`crash on large files`: https://bitbucket.org/pypy/pypy/issues/2260
+
+The changes between PyPy 5.0 and 5.0.1 are only two bug fixes: one in
+cpyext, which fixes notably (but not only) lxml; and another for a
+corner case of the JIT.
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`PyPy and CPython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+We also welcome developers of other
+`dynamic languages`_ to see what RPython can do for them.
+
+This release supports **x86** machines on most common operating systems
+(Linux 32/64, Mac OS X 64, Windows 32, OpenBSD, FreeBSD),
+newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, and the
+big- and little-endian variants of **PPC64** running Linux.
+
+.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://pypyjs.org
+
+Please update, and continue to help us make PyPy better.
+
+Cheers
+
+The PyPy Team
+
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -327,7 +327,7 @@
# XXX possibly adapt options using modules
failures = create_cffi_import_libraries(exename, options, basedir)
# if failures, they were already printed
- print >> sys.stderr, str(exename),'successfully built, but errors while building the above modules will be ignored'
+ print >> sys.stderr, str(exename),'successfully built (errors, if any, while building the above modules are ignored)'
driver.task_build_cffi_imports = types.MethodType(task_build_cffi_imports, driver)
driver.tasks['build_cffi_imports'] = driver.task_build_cffi_imports, [compile_goal]
driver.default_goal = 'build_cffi_imports'
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -419,7 +419,10 @@
self.wait_for_thread_shutdown()
w_exitfunc = self.sys.getdictvalue(self, 'exitfunc')
if w_exitfunc is not None:
- self.call_function(w_exitfunc)
+ try:
+ self.call_function(w_exitfunc)
+ except OperationError as e:
+ e.write_unraisable(self, 'sys.exitfunc == ', w_exitfunc)
from pypy.interpreter.module import Module
for w_mod in self.builtin_modules.values():
if isinstance(w_mod, Module) and w_mod.startup_called:
diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -416,3 +416,14 @@
i -= 1
assert i >= 0
gc.collect()
+
+ def test_exitfunc_catches_exceptions(self):
+ from pypy.tool.pytest.objspace import maketestobjspace
+ space = maketestobjspace()
+ space.appexec([], """():
+ import sys
+ sys.exitfunc = lambda: this_is_an_unknown_name
+ """)
+ space.finish()
+ # assert that we reach this point without getting interrupted
+ # by the OperationError(NameError)
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -124,7 +124,7 @@
s = rffi.charp2str(ptr)
else:
s = rffi.charp2strn(ptr, length)
- return space.wrap(s)
+ return space.wrapbytes(s)
#
# pointer to a wchar_t: builds and returns a unicode
if self.is_unichar_ptr_or_array():
@@ -372,15 +372,15 @@
rffi_fclose(self.llf)
-def prepare_file_argument(space, fileobj):
- fileobj.direct_flush()
- if fileobj.cffi_fileobj is None:
- fd = fileobj.direct_fileno()
+def prepare_file_argument(space, w_fileobj):
+ w_fileobj.direct_flush()
+ if w_fileobj.cffi_fileobj is None:
+ fd = w_fileobj.direct_fileno()
if fd < 0:
raise OperationError(space.w_ValueError,
space.wrap("file has no OS file descriptor"))
try:
- fileobj.cffi_fileobj = CffiFileObj(fd, fileobj.mode)
+ w_fileobj.cffi_fileobj = CffiFileObj(fd, w_fileobj.mode)
except OSError, e:
raise wrap_oserror(space, e)
- return rffi.cast(rffi.CCHARP, fileobj.cffi_fileobj.llf)
+ return rffi.cast(rffi.CCHARP, w_fileobj.cffi_fileobj.llf)
diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py
--- a/pypy/module/_vmprof/test/test__vmprof.py
+++ b/pypy/module/_vmprof/test/test__vmprof.py
@@ -72,9 +72,9 @@
def test_enable_ovf(self):
import _vmprof
- raises(_vmprof.VMProfError, _vmprof.enable, 999, 0)
- raises(_vmprof.VMProfError, _vmprof.enable, 999, -2.5)
- raises(_vmprof.VMProfError, _vmprof.enable, 999, 1e300)
- raises(_vmprof.VMProfError, _vmprof.enable, 999, 1e300 * 1e300)
+ raises(_vmprof.VMProfError, _vmprof.enable, 2, 0)
+ raises(_vmprof.VMProfError, _vmprof.enable, 2, -2.5)
+ raises(_vmprof.VMProfError, _vmprof.enable, 2, 1e300)
+ raises(_vmprof.VMProfError, _vmprof.enable, 2, 1e300 * 1e300)
NaN = (1e300*1e300) / (1e300*1e300)
- raises(_vmprof.VMProfError, _vmprof.enable, 999, NaN)
+ raises(_vmprof.VMProfError, _vmprof.enable, 2, NaN)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -833,14 +833,14 @@
modulename = py.path.local(eci.libraries[-1])
def dealloc_trigger():
- from pypy.module.cpyext.pyobject import _Py_Dealloc
+ from pypy.module.cpyext.pyobject import decref
print 'dealloc_trigger...'
while True:
ob = rawrefcount.next_dead(PyObject)
if not ob:
break
print ob
- _Py_Dealloc(space, ob)
+ decref(space, ob)
print 'dealloc_trigger DONE'
return "RETRY"
rawrefcount.init(dealloc_trigger)
diff --git a/pypy/module/cpyext/bytesobject.py b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -1,4 +1,4 @@
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, oefmt
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
@@ -80,7 +80,8 @@
buflen = length + 1
py_str.c_size = length
py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
return py_str
def string_attach(space, py_obj, w_obj):
@@ -133,8 +134,14 @@
if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
pass # typecheck returned "ok" without forcing 'ref' at all
elif not PyString_Check(space, ref): # otherwise, use the alternate way
- raise OperationError(space.w_TypeError, space.wrap(
- "PyString_AsString only support strings"))
+ from pypy.module.cpyext.unicodeobject import (
+ PyUnicode_Check, _PyUnicode_AsDefaultEncodedString)
+ if PyUnicode_Check(space, ref):
+ ref = _PyUnicode_AsDefaultEncodedString(space, ref, lltype.nullptr(rffi.CCHARP.TO))
+ else:
+ raise oefmt(space.w_TypeError,
+ "expected string or Unicode object, %T found",
+ from_ref(space, ref))
ref_str = rffi.cast(PyStringObject, ref)
if not ref_str.c_buffer:
# copy string buffer
@@ -146,8 +153,14 @@
@cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1)
def PyString_AsStringAndSize(space, ref, buffer, length):
if not PyString_Check(space, ref):
- raise OperationError(space.w_TypeError, space.wrap(
- "PyString_AsStringAndSize only support strings"))
+ from pypy.module.cpyext.unicodeobject import (
+ PyUnicode_Check, _PyUnicode_AsDefaultEncodedString)
+ if PyUnicode_Check(space, ref):
+ ref = _PyUnicode_AsDefaultEncodedString(space, ref, lltype.nullptr(rffi.CCHARP.TO))
+ else:
+ raise oefmt(space.w_TypeError,
+ "expected string or Unicode object, %T found",
+ from_ref(space, ref))
ref_str = rffi.cast(PyStringObject, ref)
if not ref_str.c_buffer:
# copy string buffer
diff --git a/pypy/module/cpyext/include/unicodeobject.h b/pypy/module/cpyext/include/unicodeobject.h
--- a/pypy/module/cpyext/include/unicodeobject.h
+++ b/pypy/module/cpyext/include/unicodeobject.h
@@ -20,8 +20,12 @@
typedef struct {
PyObject_HEAD
- Py_UNICODE *buffer;
+ Py_UNICODE *str;
Py_ssize_t size;
+ long hash; /* Hash value; -1 if not set */
+ PyObject *defenc; /* (Default) Encoded version as Python
+ string, or NULL; this is used for
+ implementing the buffer protocol */
} PyUnicodeObject;
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -17,7 +17,8 @@
@cpython_api([Py_ssize_t], rffi.VOIDP)
def PyObject_MALLOC(space, size):
return lltype.malloc(rffi.VOIDP.TO, size,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
@cpython_api([rffi.VOIDP], lltype.Void)
def PyObject_FREE(space, ptr):
diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py
--- a/pypy/module/cpyext/pyobject.py
+++ b/pypy/module/cpyext/pyobject.py
@@ -50,7 +50,8 @@
size += itemcount * pytype.c_tp_itemsize
assert size >= rffi.sizeof(PyObject.TO)
buf = lltype.malloc(rffi.VOIDP.TO, size,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
pyobj = rffi.cast(PyObject, buf)
pyobj.c_ob_refcnt = 1
pyobj.c_ob_type = pytype
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -147,10 +147,10 @@
"""
def perform(self, executioncontext, frame):
- from pypy.module.cpyext.pyobject import PyObject, _Py_Dealloc
+ from pypy.module.cpyext.pyobject import PyObject, decref
while True:
py_obj = rawrefcount.next_dead(PyObject)
if not py_obj:
break
- _Py_Dealloc(self.space, py_obj)
+ decref(self.space, py_obj)
diff --git a/pypy/module/cpyext/test/test_bytesobject.py b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -139,6 +139,44 @@
])
module.getstring()
+ def test_py_string_as_string_Unicode(self):
+ module = self.import_extension('foo', [
+ ("getstring_unicode", "METH_NOARGS",
+ """
+ Py_UNICODE chars[] = {'t', 'e', 's', 't'};
+ PyObject* u1 = PyUnicode_FromUnicode(chars, 4);
+ char *buf;
+ buf = PyString_AsString(u1);
+ if (buf == NULL)
+ return NULL;
+ if (buf[3] != 't') {
+ PyErr_SetString(PyExc_AssertionError, "Bad conversion");
+ return NULL;
+ }
+ Py_DECREF(u1);
+ Py_INCREF(Py_None);
+ return Py_None;
+ """),
+ ("getstringandsize_unicode", "METH_NOARGS",
+ """
+ Py_UNICODE chars[] = {'t', 'e', 's', 't'};
+ PyObject* u1 = PyUnicode_FromUnicode(chars, 4);
+ char *buf;
+ Py_ssize_t len;
+ if (PyString_AsStringAndSize(u1, &buf, &len) < 0)
+ return NULL;
+ if (len != 4) {
+ PyErr_SetString(PyExc_AssertionError, "Bad Length");
+ return NULL;
+ }
+ Py_DECREF(u1);
+ Py_INCREF(Py_None);
+ return Py_None;
+ """),
+ ])
+ module.getstring_unicode()
+ module.getstringandsize_unicode()
+
def test_format_v(self):
module = self.import_extension('foo', [
("test_string_format_v", "METH_VARARGS",
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -24,7 +24,7 @@
if(PyUnicode_GetSize(s) == 11) {
result = 1;
}
- if(s->ob_type->tp_basicsize != sizeof(void*)*5)
+ if(s->ob_type->tp_basicsize != sizeof(void*)*7)
result = 0;
Py_DECREF(s);
return PyBool_FromLong(result);
@@ -66,6 +66,7 @@
c = PyUnicode_AsUnicode(s);
c[0] = 'a';
c[1] = 0xe9;
+ c[2] = 0x00;
c[3] = 'c';
return s;
"""),
@@ -74,7 +75,35 @@
assert len(s) == 4
assert s == u'a�\x00c'
+ def test_hash(self):
+ module = self.import_extension('foo', [
+ ("test_hash", "METH_VARARGS",
+ '''
+ PyObject* obj = (PyTuple_GetItem(args, 0));
+ long hash = ((PyUnicodeObject*)obj)->hash;
+ return PyLong_FromLong(hash);
+ '''
+ ),
+ ])
+ res = module.test_hash(u"xyz")
+ assert res == hash(u'xyz')
+ def test_default_encoded_string(self):
+ module = self.import_extension('foo', [
+ ("test_default_encoded_string", "METH_O",
+ '''
+ PyObject* result = _PyUnicode_AsDefaultEncodedString(args, "replace");
+ Py_INCREF(result);
+ return result;
+ '''
+ ),
+ ])
+ res = module.test_default_encoded_string(u"xyz")
+ assert isinstance(res, str)
+ assert res == 'xyz'
+ res = module.test_default_encoded_string(u"caf\xe9")
+ assert isinstance(res, str)
+ assert res == 'caf?'
class TestUnicode(BaseApiTest):
def test_unicodeobject(self, space, api):
@@ -155,22 +184,22 @@
def test_unicode_resize(self, space, api):
py_uni = new_empty_unicode(space, 10)
ar = lltype.malloc(PyObjectP.TO, 1, flavor='raw')
- py_uni.c_buffer[0] = u'a'
- py_uni.c_buffer[1] = u'b'
- py_uni.c_buffer[2] = u'c'
+ py_uni.c_str[0] = u'a'
+ py_uni.c_str[1] = u'b'
+ py_uni.c_str[2] = u'c'
ar[0] = rffi.cast(PyObject, py_uni)
api.PyUnicode_Resize(ar, 3)
py_uni = rffi.cast(PyUnicodeObject, ar[0])
assert py_uni.c_size == 3
- assert py_uni.c_buffer[1] == u'b'
- assert py_uni.c_buffer[3] == u'\x00'
+ assert py_uni.c_str[1] == u'b'
+ assert py_uni.c_str[3] == u'\x00'
# the same for growing
ar[0] = rffi.cast(PyObject, py_uni)
api.PyUnicode_Resize(ar, 10)
py_uni = rffi.cast(PyUnicodeObject, ar[0])
assert py_uni.c_size == 10
- assert py_uni.c_buffer[1] == 'b'
- assert py_uni.c_buffer[10] == '\x00'
+ assert py_uni.c_str[1] == 'b'
+ assert py_uni.c_str[10] == '\x00'
Py_DecRef(space, ar[0])
lltype.free(ar, flavor='raw')
diff --git a/pypy/module/cpyext/tupleobject.py b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -59,7 +59,8 @@
py_tup = rffi.cast(PyTupleObject, py_obj)
py_tup.c_ob_item = lltype.malloc(ObjectItems, length,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
py_tup.c_ob_size = length
return py_tup
@@ -70,7 +71,8 @@
"""
items_w = space.fixedview(w_obj)
l = len(items_w)
- p = lltype.malloc(ObjectItems, l, flavor='raw')
+ p = lltype.malloc(ObjectItems, l, flavor='raw',
+ add_memory_pressure=True)
i = 0
try:
while i < l:
@@ -177,7 +179,8 @@
ref = rffi.cast(PyTupleObject, ref)
oldsize = ref.c_ob_size
oldp = ref.c_ob_item
- newp = lltype.malloc(ObjectItems, newsize, zero=True, flavor='raw')
+ newp = lltype.malloc(ObjectItems, newsize, zero=True, flavor='raw',
+ add_memory_pressure=True)
try:
if oldsize < newsize:
to_cp = oldsize
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -421,7 +421,8 @@
Py_DecRef(space, w_metatype)
heaptype = lltype.malloc(PyHeapTypeObject.TO,
- flavor='raw', zero=True)
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
pto = heaptype.c_ht_type
pto.c_ob_refcnt = 1
pto.c_ob_type = metatype
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -22,7 +22,8 @@
PyUnicodeObjectStruct = lltype.ForwardReference()
PyUnicodeObject = lltype.Ptr(PyUnicodeObjectStruct)
PyUnicodeObjectFields = (PyObjectFields +
- (("buffer", rffi.CWCHARP), ("size", Py_ssize_t)))
+ (("str", rffi.CWCHARP), ("size", Py_ssize_t),
+ ("hash", rffi.LONG), ("defenc", PyObject)))
cpython_struct("PyUnicodeObject", PyUnicodeObjectFields, PyUnicodeObjectStruct)
@bootstrap_function
@@ -54,15 +55,20 @@
buflen = length + 1
py_uni.c_size = length
- py_uni.c_buffer = lltype.malloc(rffi.CWCHARP.TO, buflen,
- flavor='raw', zero=True)
+ py_uni.c_str = lltype.malloc(rffi.CWCHARP.TO, buflen,
+ flavor='raw', zero=True,
+ add_memory_pressure=True)
+ py_uni.c_hash = -1
+ py_uni.c_defenc = lltype.nullptr(PyObject.TO)
return py_uni
def unicode_attach(space, py_obj, w_obj):
"Fills a newly allocated PyUnicodeObject with a unicode string"
py_unicode = rffi.cast(PyUnicodeObject, py_obj)
py_unicode.c_size = len(space.unicode_w(w_obj))
- py_unicode.c_buffer = lltype.nullptr(rffi.CWCHARP.TO)
+ py_unicode.c_str = lltype.nullptr(rffi.CWCHARP.TO)
+ py_unicode.c_hash = space.hash_w(w_obj)
+ py_unicode.c_defenc = lltype.nullptr(PyObject.TO)
def unicode_realize(space, py_obj):
"""
@@ -70,17 +76,20 @@
be modified after this call.
"""
py_uni = rffi.cast(PyUnicodeObject, py_obj)
- s = rffi.wcharpsize2unicode(py_uni.c_buffer, py_uni.c_size)
+ s = rffi.wcharpsize2unicode(py_uni.c_str, py_uni.c_size)
w_obj = space.wrap(s)
+ py_uni.c_hash = space.hash_w(w_obj)
track_reference(space, py_obj, w_obj)
return w_obj
@cpython_api([PyObject], lltype.Void, header=None)
def unicode_dealloc(space, py_obj):
py_unicode = rffi.cast(PyUnicodeObject, py_obj)
- if py_unicode.c_buffer:
- lltype.free(py_unicode.c_buffer, flavor="raw")
+ if py_unicode.c_str:
+ lltype.free(py_unicode.c_str, flavor="raw")
from pypy.module.cpyext.object import PyObject_dealloc
+ if py_unicode.c_defenc:
+ PyObject_dealloc(space, py_unicode.c_defenc)
PyObject_dealloc(space, py_obj)
@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
@@ -204,12 +213,12 @@
"""Return a pointer to the internal Py_UNICODE buffer of the object. ref
has to be a PyUnicodeObject (not checked)."""
ref_unicode = rffi.cast(PyUnicodeObject, ref)
- if not ref_unicode.c_buffer:
+ if not ref_unicode.c_str:
# Copy unicode buffer
w_unicode = from_ref(space, ref)
u = space.unicode_w(w_unicode)
- ref_unicode.c_buffer = rffi.unicode2wcharp(u)
- return ref_unicode.c_buffer
+ ref_unicode.c_str = rffi.unicode2wcharp(u)
+ return ref_unicode.c_str
@cpython_api([PyObject], rffi.CWCHARP)
def PyUnicode_AsUnicode(space, ref):
@@ -240,7 +249,7 @@
string may or may not be 0-terminated. It is the responsibility of the caller
to make sure that the wchar_t string is 0-terminated in case this is
required by the application."""
- c_buffer = PyUnicode_AS_UNICODE(space, rffi.cast(PyObject, ref))
+ c_str = PyUnicode_AS_UNICODE(space, rffi.cast(PyObject, ref))
c_size = ref.c_size
# If possible, try to copy the 0-termination as well
@@ -250,7 +259,7 @@
i = 0
while i < size:
- buf[i] = c_buffer[i]
+ buf[i] = c_str[i]
i += 1
if size > c_size:
@@ -342,8 +351,15 @@
return PyUnicode_FromUnicode(space, wchar_p, length)
@cpython_api([PyObject, CONST_STRING], PyObject)
-def _PyUnicode_AsDefaultEncodedString(space, w_unicode, errors):
- return PyUnicode_AsEncodedString(space, w_unicode, lltype.nullptr(rffi.CCHARP.TO), errors)
+def _PyUnicode_AsDefaultEncodedString(space, ref, errors):
+ # Returns a borrowed reference.
+ py_uni = rffi.cast(PyUnicodeObject, ref)
+ if not py_uni.c_defenc:
+ py_uni.c_defenc = make_ref(
+ space, PyUnicode_AsEncodedString(
+ space, ref,
+ lltype.nullptr(rffi.CCHARP.TO), errors))
+ return py_uni.c_defenc
@cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, CONST_STRING], PyObject)
def PyUnicode_Decode(space, s, size, encoding, errors):
@@ -443,7 +459,7 @@
def PyUnicode_Resize(space, ref, newsize):
# XXX always create a new string so far
py_uni = rffi.cast(PyUnicodeObject, ref[0])
- if not py_uni.c_buffer:
+ if not py_uni.c_str:
raise OperationError(space.w_SystemError, space.wrap(
"PyUnicode_Resize called on already created string"))
try:
@@ -457,7 +473,7 @@
if oldsize < newsize:
to_cp = oldsize
for i in range(to_cp):
- py_newuni.c_buffer[i] = py_uni.c_buffer[i]
+ py_newuni.c_str[i] = py_uni.c_str[i]
Py_DecRef(space, ref[0])
ref[0] = rffi.cast(PyObject, py_newuni)
return 0
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -109,7 +109,7 @@
import marshal, stat, struct, os, imp
code = py.code.Source(p.join("x.py").read()).compile()
s3 = marshal.dumps(code)
- s2 = struct.pack("i", os.stat(str(p.join("x.py")))[stat.ST_MTIME])
+ s2 = struct.pack("<i", os.stat(str(p.join("x.py")))[stat.ST_MTIME])
p.join("x.pyc").write(imp.get_magic() + s2 + s3, mode='wb')
else:
w = space.wrap
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -502,29 +502,34 @@
return W_NDimArray(self.implementation.transpose(self, axes))
def descr_transpose(self, space, args_w):
- if len(args_w) == 1 and space.isinstance_w(args_w[0], space.w_tuple):
- args_w = space.fixedview(args_w[0])
- if (len(args_w) == 0 or
- len(args_w) == 1 and space.is_none(args_w[0])):
+ if len(args_w) == 0 or len(args_w) == 1 and space.is_none(args_w[0]):
return self.descr_get_transpose(space)
else:
- if len(args_w) != self.ndims():
- raise oefmt(space.w_ValueError, "axes don't match array")
- axes = []
- axes_seen = [False] * self.ndims()
- for w_arg in args_w:
- try:
- axis = support.index_w(space, w_arg)
- except OperationError:
- raise oefmt(space.w_TypeError, "an integer is required")
- if axis < 0 or axis >= self.ndims():
- raise oefmt(space.w_ValueError, "invalid axis for this array")
- if axes_seen[axis] is True:
- raise oefmt(space.w_ValueError, "repeated axis in transpose")
- axes.append(axis)
- axes_seen[axis] = True
- return self.descr_get_transpose(space, axes)
+ if len(args_w) > 1:
+ axes = args_w
+ else: # Iterable in the only argument (len(arg_w) == 1 and arg_w[0] is not None)
+ axes = space.fixedview(args_w[0])
+ axes = self._checked_axes(axes, space)
+ return self.descr_get_transpose(space, axes)
+
+ def _checked_axes(self, axes_raw, space):
+ if len(axes_raw) != self.ndims():
+ raise oefmt(space.w_ValueError, "axes don't match array")
+ axes = []
+ axes_seen = [False] * self.ndims()
+ for elem in axes_raw:
+ try:
+ axis = support.index_w(space, elem)
+ except OperationError:
+ raise oefmt(space.w_TypeError, "an integer is required")
+ if axis < 0 or axis >= self.ndims():
+ raise oefmt(space.w_ValueError, "invalid axis for this array")
+ if axes_seen[axis] is True:
+ raise oefmt(space.w_ValueError, "repeated axis in transpose")
+ axes.append(axis)
+ axes_seen[axis] = True
+ return axes
@unwrap_spec(axis1=int, axis2=int)
def descr_swapaxes(self, space, axis1, axis2):
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2960,6 +2960,36 @@
assert (a.transpose() == b).all()
assert (a.transpose(None) == b).all()
+ def test_transpose_arg_tuple(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose((1, 2, 0))
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
+ def test_transpose_arg_list(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose([1, 2, 0])
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
+ def test_transpose_arg_array(self):
+ import numpy as np
+ a = np.arange(24).reshape(2, 3, 4)
+ transpose_args = a.transpose(1, 2, 0)
+
+ transpose_test = a.transpose(np.array([1, 2, 0]))
+
+ assert transpose_test.shape == (3, 4, 2)
+ assert (transpose_args == transpose_test).all()
+
def test_transpose_error(self):
import numpy as np
a = np.arange(24).reshape(2, 3, 4)
@@ -2968,6 +2998,11 @@
raises(ValueError, a.transpose, 1, 0, 1)
raises(TypeError, a.transpose, 1, 0, '2')
+ def test_transpose_unexpected_argument(self):
+ import numpy as np
+ a = np.array([[1, 2], [3, 4], [5, 6]])
+ raises(TypeError, 'a.transpose(axes=(1,2,0))')
+
def test_flatiter(self):
from numpy import array, flatiter, arange, zeros
a = array([[10, 30], [40, 60]])
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -287,8 +287,7 @@
t = thread.start_new_thread(pollster.poll, ())
try:
time.sleep(0.3)
- # TODO restore print '', if this is not the reason
- for i in range(5): print 'release gil select' # to release GIL untranslated
+ for i in range(5): print '', # to release GIL untranslated
# trigger ufds array reallocation
for fd in rfds:
pollster.unregister(fd)
diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py
--- a/pypy/module/thread/test/test_lock.py
+++ b/pypy/module/thread/test/test_lock.py
@@ -3,7 +3,7 @@
import sys, os
from pypy.module.thread.test.support import GenericTestThread
from rpython.translator.c.test.test_genc import compile
-import platform
+from platform import machine
class AppTestLock(GenericTestThread):
@@ -64,8 +64,7 @@
else:
assert self.runappdirect, "missing lock._py3k_acquire()"
- @py.test.mark.xfail(platform.machine() == 's390x',
- reason='may fail this test under heavy load')
+ @py.test.mark.xfail(machine()=='s390x', reason='may fail under heavy load')
def test_ping_pong(self):
# The purpose of this test is that doing a large number of ping-pongs
# between two threads, using locks, should complete in a reasonable
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -185,14 +185,6 @@
cache[name, index] = attr
return attr
- @jit.elidable
- def _get_cache_attr(self, name, index):
- key = name, index
- # this method is not actually elidable, but it's fine anyway
- if self.cache_attrs is not None:
- return self.cache_attrs.get(key, None)
- return None
-
def add_attr(self, obj, name, index, w_value):
self._reorder_and_add(obj, name, index, w_value)
if not jit.we_are_jitted():
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -1,9 +1,9 @@
# Edit these appropriately before running this script
maj=5
min=0
-rev=0
+rev=1
branchname=release-$maj.x # ==OR== release-$maj.$min.x
-tagname=release-$maj.$min # ==OR== release-$maj.$min.$rev
+tagname=release-$maj.$min.$rev
# This script will download latest builds from the buildmaster, rename the top
# level directory, and repackage ready to be uploaded to bitbucket. It will also
# download source, assuming a tag for the release already exists, and repackage them.
diff --git a/rpython/jit/backend/detect_cpu.py b/rpython/jit/backend/detect_cpu.py
--- a/rpython/jit/backend/detect_cpu.py
+++ b/rpython/jit/backend/detect_cpu.py
@@ -66,6 +66,7 @@
'x86_64': MODEL_X86,
'amd64': MODEL_X86, # freebsd
'AMD64': MODEL_X86, # win64
+ 'armv8l': MODEL_ARM, # 32-bit ARMv8
'armv7l': MODEL_ARM,
'armv6l': MODEL_ARM,
'arm': MODEL_ARM, # freebsd
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -792,11 +792,13 @@
return []
# check for _immutable_fields_ hints
immut = v_inst.concretetype.TO._immutable_field(c_fieldname.value)
+ need_live = False
if immut:
if (self.callcontrol is not None and
self.callcontrol.could_be_green_field(v_inst.concretetype.TO,
c_fieldname.value)):
pure = '_greenfield'
+ need_live = True
else:
pure = '_pure'
else:
@@ -823,10 +825,12 @@
descr1 = self.cpu.fielddescrof(
v_inst.concretetype.TO,
quasiimmut.get_mutate_field_name(c_fieldname.value))
- op1 = [SpaceOperation('-live-', [], None),
+ return [SpaceOperation('-live-', [], None),
SpaceOperation('record_quasiimmut_field',
[v_inst, descr, descr1], None),
op1]
+ if need_live:
+ return [SpaceOperation('-live-', [], None), op1]
return op1
def rewrite_op_setfield(self, op, override_type=None):
diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -1029,7 +1029,8 @@
v1 = varoftype(lltype.Ptr(S))
v2 = varoftype(lltype.Char)
op = SpaceOperation('getfield', [v1, Constant('x', lltype.Void)], v2)
- op1 = Transformer(FakeCPU(), FakeCC()).rewrite_operation(op)
+ op0, op1 = Transformer(FakeCPU(), FakeCC()).rewrite_operation(op)
+ assert op0.opname == '-live-'
assert op1.opname == 'getfield_gc_i_greenfield'
assert op1.args == [v1, ('fielddescr', S, 'x')]
assert op1.result == v2
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2929,10 +2929,19 @@
ll_assert(rc < int(REFCNT_FROM_PYPY_LIGHT * 0.99),
"refcount underflow from REFCNT_FROM_PYPY_LIGHT?")
rc -= REFCNT_FROM_PYPY
- self._pyobj(pyobject).ob_refcnt = rc
self._pyobj(pyobject).ob_pypy_link = 0
if rc == 0:
self.rrc_dealloc_pending.append(pyobject)
+ # an object with refcnt == 0 cannot stay around waiting
+ # for its deallocator to be called. Some code (lxml)
+ # expects that tp_dealloc is called immediately when
+ # the refcnt drops to 0. If it isn't, we get some
+ # uncleared raw pointer that can still be used to access
+ # the object; but (PyObject *)raw_pointer is then bogus
+ # because after a Py_INCREF()/Py_DECREF() on it, its
+ # tp_dealloc is also called!
+ rc = 1
+ self._pyobj(pyobject).ob_refcnt = rc
_rrc_free._always_inline_ = True
def rrc_major_collection_trace(self):
diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py
--- a/rpython/memory/gc/test/test_rawrefcount.py
+++ b/rpython/memory/gc/test/test_rawrefcount.py
@@ -174,7 +174,7 @@
p1 = check_alive(0)
self._collect(major=True, expected_trigger=1)
py.test.raises(RuntimeError, "p1.x") # dead
- assert r1.ob_refcnt == 0
+ assert r1.ob_refcnt == 1 # in the pending list
assert r1.ob_pypy_link == 0
assert self.gc.rawrefcount_next_dead() == r1addr
assert self.gc.rawrefcount_next_dead() == llmemory.NULL
@@ -197,7 +197,7 @@
assert p1.x == 42
self._collect(major=True, expected_trigger=1)
py.test.raises(RuntimeError, "p1.x") # dead
- assert r1.ob_refcnt == 0
+ assert r1.ob_refcnt == 1
assert r1.ob_pypy_link == 0
assert self.gc.rawrefcount_next_dead() == r1addr
self.gc.check_no_more_rawrefcount_state()
@@ -214,7 +214,7 @@
else:
self._collect(major=False, expected_trigger=1)
py.test.raises(RuntimeError, "p1.x") # dead
- assert r1.ob_refcnt == 0
+ assert r1.ob_refcnt == 1
assert r1.ob_pypy_link == 0
assert self.gc.rawrefcount_next_dead() == r1addr
self.gc.check_no_more_rawrefcount_state()
@@ -252,7 +252,7 @@
self._collect(major=True, expected_trigger=1)
else:
self._collect(major=False, expected_trigger=1)
- assert r1.ob_refcnt == 0 # refcnt dropped to 0
+ assert r1.ob_refcnt == 1 # refcnt 1, in the pending list
assert r1.ob_pypy_link == 0 # detached
assert self.gc.rawrefcount_next_dead() == r1addr
self.gc.check_no_more_rawrefcount_state()
@@ -277,7 +277,7 @@
assert self.trigger == []
self._collect(major=True, expected_trigger=1)
py.test.raises(RuntimeError, "p1.x") # dead
- assert r1.ob_refcnt == 0
+ assert r1.ob_refcnt == 1
assert r1.ob_pypy_link == 0
assert self.gc.rawrefcount_next_dead() == r1addr
self.gc.check_no_more_rawrefcount_state()
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1099,6 +1099,14 @@
of JIT running like JIT loops compiled, aborts etc.
An instance of this class will be available as policy.jithookiface.
"""
+ # WARNING: You should make a single prebuilt instance of a subclass
+ # of this class. You can, before translation, initialize some
+ # attributes on this instance, and then read or change these
+ # attributes inside the methods of the subclass. But this prebuilt
+ # instance *must not* be seen during the normal annotation/rtyping
+ # of the program! A line like ``pypy_hooks.foo = ...`` must not
+ # appear inside your interpreter's RPython code.
+
def on_abort(self, reason, jitdriver, greenkey, greenkey_repr, logops, operations):
""" A hook called each time a loop is aborted with jitdriver and
greenkey where it started, reason is a string why it got aborted
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -72,6 +72,12 @@
return p
def next_dead(OB_PTR_TYPE):
+ """NOT_RPYTHON. When the GC runs, it finds some pyobjs to be dead
+ but cannot immediately dispose of them (it doesn't know how to call
+ e.g. tp_dealloc(), and anyway calling it immediately would cause all
+ sorts of bugs). So instead, it stores them in an internal list,
+ initially with refcnt == 1. This pops the next item off this list.
+ """
if len(_d_list) == 0:
return lltype.nullptr(OB_PTR_TYPE.TO)
ob = _d_list.pop()
@@ -136,6 +142,7 @@
ob.c_ob_refcnt -= REFCNT_FROM_PYPY
ob.c_ob_pypy_link = 0
if ob.c_ob_refcnt == 0:
+ ob.c_ob_refcnt = 1
_d_list.append(ob)
return None
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -22,6 +22,22 @@
from rpython.rlib import rwin32
from rpython.rlib.rwin32file import make_win32_traits
+class CConfig:
+ _compilation_info_ = ExternalCompilationInfo(
+ includes=['sys/stat.h',
+ 'unistd.h',
+ 'fcntl.h'],
+ )
+ for _name in """fchdir fchmod fchmodat fchown fchownat fexecve fdopendir
+ fpathconf fstat fstatat fstatvfs ftruncate futimens futimes
+ futimesat linkat lchflags lchmod lchown lstat lutimes
+ mkdirat mkfifoat mknodat openat readlinkat renameat
+ symlinkat unlinkat utimensat""".split():
+ locals()['HAVE_%s' % _name.upper()] = rffi_platform.Has(_name)
+cConfig = rffi_platform.configure(CConfig)
+globals().update(cConfig)
+
+
class CConstantErrno(CConstant):
# these accessors are used when calling get_errno() or set_errno()
# on top of CPython
@@ -1024,6 +1040,13 @@
if not win32traits.MoveFile(path1, path2):
raise rwin32.lastSavedWindowsError()
+ at specialize.argtype(0, 1)
+def replace(path1, path2):
+ if os.name == 'nt':
+ raise NotImplementedError(
+ 'On windows, os.replace() should overwrite the destination')
+ return rename(path1, path2)
+
#___________________________________________________________________
c_mkfifo = external('mkfifo', [rffi.CCHARP, rffi.MODE_T], rffi.INT,
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -9,7 +9,6 @@
from rpython.rtyper.tool import rffi_platform
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.objectmodel import register_replacement_for
-from rpython.rlib import jit
from rpython.rlib.rarithmetic import intmask, UINT_MAX
from rpython.rlib import rposix
@@ -170,28 +169,30 @@
[lltype.Signed, lltype.Ptr(TIMESPEC)],
rffi.INT, releasegil=False,
compilation_info=eci_with_lrt)
-else:
+if need_rusage:
RUSAGE = RUSAGE
RUSAGE_SELF = RUSAGE_SELF or 0
c_getrusage = external('getrusage',
[rffi.INT, lltype.Ptr(RUSAGE)],
- lltype.Void,
+ rffi.INT,
releasegil=False)
+def win_perf_counter():
+ a = lltype.malloc(A, flavor='raw')
+ if state.divisor == 0.0:
+ QueryPerformanceCounter(a)
+ state.counter_start = a[0]
+ QueryPerformanceFrequency(a)
+ state.divisor = float(a[0])
+ QueryPerformanceCounter(a)
+ diff = a[0] - state.counter_start
+ lltype.free(a, flavor='raw')
+ return float(diff) / state.divisor
+
@replace_time_function('clock')
- at jit.dont_look_inside # the JIT doesn't like FixedSizeArray
def clock():
if _WIN32:
- a = lltype.malloc(A, flavor='raw')
- if state.divisor == 0.0:
- QueryPerformanceCounter(a)
- state.counter_start = a[0]
- QueryPerformanceFrequency(a)
- state.divisor = float(a[0])
- QueryPerformanceCounter(a)
- diff = a[0] - state.counter_start
- lltype.free(a, flavor='raw')
- return float(diff) / state.divisor
+ return win_perf_counter()
elif CLOCK_PROCESS_CPUTIME_ID is not None:
with lltype.scoped_alloc(TIMESPEC) as a:
c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a)
diff --git a/rpython/rlib/rvmprof/src/vmprof_common.h b/rpython/rlib/rvmprof/src/vmprof_common.h
--- a/rpython/rlib/rvmprof/src/vmprof_common.h
+++ b/rpython/rlib/rvmprof/src/vmprof_common.h
@@ -24,14 +24,14 @@
char padding[sizeof(long) - 1];
char marker;
long count, depth;
- void *stack[];
+ intptr_t stack[];
} prof_stacktrace_s;
RPY_EXTERN
char *vmprof_init(int fd, double interval, char *interp_name)
{
- if (interval < 1e-6 || interval >= 1.0)
+ if (!(interval >= 1e-6 && interval < 1.0)) /* also if it is NaN */
return "bad value for 'interval'";
prepare_interval_usec = (int)(interval * 1000000.0);
diff --git a/rpython/rlib/rvmprof/src/vmprof_config.h b/rpython/rlib/rvmprof/src/vmprof_config.h
--- a/rpython/rlib/rvmprof/src/vmprof_config.h
+++ b/rpython/rlib/rvmprof/src/vmprof_config.h
@@ -1,6 +1,10 @@
#define HAVE_SYS_UCONTEXT_H
-#if defined(__FreeBSD__)
-#define PC_FROM_UCONTEXT uc_mcontext.mc_rip
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ #ifdef __i386__
+ #define PC_FROM_UCONTEXT uc_mcontext.mc_eip
+ #else
+ #define PC_FROM_UCONTEXT uc_mcontext.mc_rip
+ #endif
#elif defined( __APPLE__)
#if ((ULONG_MAX) == (UINT_MAX))
#define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip
@@ -8,10 +12,10 @@
#define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip
#endif
#elif defined(__arm__)
-#define PC_FROM_UCONTEXT uc_mcontext.arm_ip
+ #define PC_FROM_UCONTEXT uc_mcontext.arm_ip
#elif defined(__linux) && defined(__i386) && defined(__GNUC__)
-#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP]
+ #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP]
#else
-/* linux, gnuc */
-#define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP]
+ /* linux, gnuc */
+ #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP]
#endif
diff --git a/rpython/rlib/rvmprof/src/vmprof_main_win32.h b/rpython/rlib/rvmprof/src/vmprof_main_win32.h
--- a/rpython/rlib/rvmprof/src/vmprof_main_win32.h
+++ b/rpython/rlib/rvmprof/src/vmprof_main_win32.h
@@ -101,7 +101,7 @@
depth = get_stack_trace(p->vmprof_tl_stack,
stack->stack, MAX_STACK_DEPTH-2, ctx.Eip);
stack->depth = depth;
- stack->stack[depth++] = (void*)p->thread_ident;
+ stack->stack[depth++] = p->thread_ident;
stack->count = 1;
stack->marker = MARKER_STACKTRACE;
ResumeThread(hThread);
diff --git a/rpython/rlib/test/test_rawrefcount.py b/rpython/rlib/test/test_rawrefcount.py
--- a/rpython/rlib/test/test_rawrefcount.py
+++ b/rpython/rlib/test/test_rawrefcount.py
@@ -116,7 +116,7 @@
assert rawrefcount.next_dead(PyObject) == lltype.nullptr(PyObjectS)
assert rawrefcount._o_list == []
assert wr_p() is None
- assert ob.c_ob_refcnt == 0
+ assert ob.c_ob_refcnt == 1 # from the pending list
assert ob.c_ob_pypy_link == 0
lltype.free(ob, flavor='raw')
@@ -173,7 +173,7 @@
assert rawrefcount._d_list == [ob]
assert rawrefcount._p_list == []
assert wr_p() is None
- assert ob.c_ob_refcnt == 0
+ assert ob.c_ob_refcnt == 1 # from _d_list
assert ob.c_ob_pypy_link == 0
lltype.free(ob, flavor='raw')
diff --git a/rpython/tool/runsubprocess.py b/rpython/tool/runsubprocess.py
--- a/rpython/tool/runsubprocess.py
+++ b/rpython/tool/runsubprocess.py
@@ -20,6 +20,8 @@
def _run(executable, args, env, cwd):
# note that this function can be *overridden* below
# in some cases!
+ if sys.platform == 'win32':
+ executable = executable.replace('/','\\')
if isinstance(args, str):
args = str(executable) + ' ' + args
shell = True
diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c
--- a/rpython/translator/c/src/thread_pthread.c
+++ b/rpython/translator/c/src/thread_pthread.c
@@ -37,7 +37,7 @@
# define THREAD_STACK_SIZE 0 /* use default stack size */
# endif
-# if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
+# if (defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
/* The default stack size for new threads on OSX is small enough that
* we'll get hard crashes instead of 'maximum recursion depth exceeded'
* exceptions.
@@ -84,7 +84,7 @@
if (tss != 0)
pthread_attr_setstacksize(&attrs, tss);
#endif
-#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) && !defined(__FreeBSD__)
+#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) && !(defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
#endif
More information about the pypy-commit
mailing list