Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r90647:7c1314187e2f Date: 2017-03-13 08:50 +0100 http://bitbucket.org/pypy/pypy/changeset/7c1314187e2f/
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 @@ -200,3 +200,5 @@ asmgcc---close enough that we can now make shadowstack the default even on Linux. This should remove a whole class of rare bugs introduced by asmgcc. + +.. branch: fniephaus/fix-typo-1488123166752 diff --git a/pypy/module/_minimal_curses/__init__.py b/pypy/module/_minimal_curses/__init__.py --- a/pypy/module/_minimal_curses/__init__.py +++ b/pypy/module/_minimal_curses/__init__.py @@ -10,7 +10,6 @@ py.test.skip("no _curses or _minimal_curses module") # no _curses at all from pypy.interpreter.mixedmodule import MixedModule -from pypy.module._minimal_curses import fficurses # for side effects class Module(MixedModule): diff --git a/pypy/module/_minimal_curses/fficurses.py b/pypy/module/_minimal_curses/fficurses.py --- a/pypy/module/_minimal_curses/fficurses.py +++ b/pypy/module/_minimal_curses/fficurses.py @@ -1,11 +1,8 @@ -""" The ffi for rpython, need to be imported for side effects +""" The ffi for rpython """ from rpython.rtyper.lltypesystem import rffi -from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.tool import rffi_platform -from rpython.rtyper.extfunc import register_external -from pypy.module._minimal_curses import interp_curses from rpython.translator.tool.cbuild import ExternalCompilationInfo # We cannot trust ncurses5-config, it's broken in various ways in @@ -58,86 +55,73 @@ eci = guess_eci() -INT = rffi.INT -INTP = lltype.Ptr(lltype.Array(INT, hints={'nolength':True})) -c_setupterm = rffi.llexternal('setupterm', [rffi.CCHARP, INT, INTP], INT, - compilation_info=eci) -c_tigetstr = rffi.llexternal('tigetstr', [rffi.CCHARP], rffi.CCHARP, - compilation_info=eci) -c_tparm = rffi.llexternal('tparm', [rffi.CCHARP, INT, INT, INT, INT, INT, - INT, INT, INT, INT], rffi.CCHARP, - compilation_info=eci) +# We should not use this 'eci' directly because it causes the #include +# of term.h to appear in all generated C sources, and term.h contains a +# poisonous quantity of #defines for common lower-case names like +# 'buttons' or 'lines' (!!!). It is basically dangerous to include +# term.h in any C source file that may contain unrelated source code. -ERR = rffi.CConstant('ERR', lltype.Signed) -OK = rffi.CConstant('OK', lltype.Signed) +include_lines = '\n'.join(['#include <%s>' % _incl for _incl in eci.includes]) +eci = eci.copy_without('includes') -def curses_setupterm(term, fd): - intp = lltype.malloc(INTP.TO, 1, flavor='raw') - err = rffi.cast(lltype.Signed, c_setupterm(term, fd, intp)) - try: - if err == ERR: - errret = rffi.cast(lltype.Signed, intp[0]) - if errret == 0: - msg = "setupterm: could not find terminal" - elif errret == -1: - msg = "setupterm: could not find terminfo database" - else: - msg = "setupterm: unknown error" - raise interp_curses.curses_error(msg) - interp_curses.module_info.setupterm_called = True - finally: - lltype.free(intp, flavor='raw') -def curses_setupterm_null_llimpl(fd): - curses_setupterm(lltype.nullptr(rffi.CCHARP.TO), fd) +eci = eci.merge(ExternalCompilationInfo( + post_include_bits=[ + "RPY_EXTERN char *rpy_curses_setupterm(char *, int);\n" + "RPY_EXTERN char *rpy_curses_tigetstr(char *);\n" + "RPY_EXTERN char *rpy_curses_tparm(char *, int, int, int, int," + " int, int, int, int, int);" + ], + separate_module_sources=[""" -def curses_setupterm_llimpl(term, fd): - ll_s = rffi.str2charp(term) - try: - curses_setupterm(ll_s, fd) - finally: - rffi.free_charp(ll_s) +%(include_lines)s -register_external(interp_curses._curses_setupterm_null, - [int], llimpl=curses_setupterm_null_llimpl, - export_name='_curses.setupterm_null') -register_external(interp_curses._curses_setupterm, - [str, int], llimpl=curses_setupterm_llimpl, - export_name='_curses.setupterm') +RPY_EXTERN +char *rpy_curses_setupterm(char *term, int fd) +{ + int errret = -42; + if (setupterm(term, fd, &errret) == ERR) { + switch (errret) { + case 0: + return "setupterm: could not find terminal"; + case -1: + return "setupterm: could not find terminfo database"; + default: + return "setupterm: unknown error"; + } + } + return NULL; +} -def check_setup_invoked(): - if not interp_curses.module_info.setupterm_called: - raise interp_curses.curses_error("must call (at least) setupterm() first") +RPY_EXTERN +char *rpy_curses_tigetstr(char *capname) +{ + char *res = tigetstr(capname); + if (res == (char *)-1) + res = NULL; + return res; +} -def tigetstr_llimpl(cap): - check_setup_invoked() - ll_cap = rffi.str2charp(cap) - try: - ll_res = c_tigetstr(ll_cap) - num = lltype.cast_ptr_to_int(ll_res) - if num == 0 or num == -1: - raise interp_curses.TermError() - res = rffi.charp2str(ll_res) - return res - finally: - rffi.free_charp(ll_cap) +RPY_EXTERN +char *rpy_curses_tparm(char *str, int x0, int x1, int x2, int x3, + int x4, int x5, int x6, int x7, int x8) +{ + return tparm(str, x0, x1, x2, x3, x4, x5, x6, x7, x8); +} -register_external(interp_curses._curses_tigetstr, [str], str, - export_name='_curses.tigetstr', llimpl=tigetstr_llimpl) +""" % globals()])) -def tparm_llimpl(s, args): - check_setup_invoked() - l = [0, 0, 0, 0, 0, 0, 0, 0, 0] - for i in range(min(len(args), 9)): - l[i] = args[i] - ll_s = rffi.str2charp(s) - # XXX nasty trick stolen from CPython - ll_res = c_tparm(ll_s, l[0], l[1], l[2], l[3], l[4], l[5], l[6], - l[7], l[8]) - rffi.free_charp(ll_s) - res = rffi.charp2str(ll_res) - return res -register_external(interp_curses._curses_tparm, [str, [int]], str, - export_name='_curses.tparm', llimpl=tparm_llimpl) +rpy_curses_setupterm = rffi.llexternal( + "rpy_curses_setupterm", [rffi.CCHARP, rffi.INT], rffi.CCHARP, + compilation_info=eci) +rpy_curses_tigetstr = rffi.llexternal( + "rpy_curses_tigetstr", [rffi.CCHARP], rffi.CCHARP, + compilation_info=eci) + +rpy_curses_tparm = rffi.llexternal( + "rpy_curses_tparm", [rffi.CCHARP, rffi.INT, rffi.INT, rffi.INT, rffi.INT, + rffi.INT, rffi.INT, rffi.INT, rffi.INT, rffi.INT], + rffi.CCHARP, + compilation_info=eci) diff --git a/pypy/module/_minimal_curses/interp_curses.py b/pypy/module/_minimal_curses/interp_curses.py --- a/pypy/module/_minimal_curses/interp_curses.py +++ b/pypy/module/_minimal_curses/interp_curses.py @@ -1,44 +1,24 @@ - from pypy.interpreter.gateway import unwrap_spec from pypy.interpreter.error import OperationError -from pypy.module._minimal_curses import _curses +from pypy.module._minimal_curses import fficurses +from rpython.rtyper.lltypesystem import lltype, rffi + class ModuleInfo: - def __init__(self): + def __init__(self, space): self.setupterm_called = False -module_info = ModuleInfo() +def check_setup_invoked(space): + if not space.fromcache(ModuleInfo).setupterm_called: + raise curses_error(space, "must call (at least) setupterm() first") -class curses_error(Exception): - def __init__(self, msg): - self.msg = msg -from rpython.annotator.classdesc import FORCE_ATTRIBUTES_INTO_CLASSES -from rpython.annotator.model import SomeString - -# this is necessary due to annmixlevel -FORCE_ATTRIBUTES_INTO_CLASSES[curses_error] = {'msg': SomeString()} - -def convert_error(space, error): - msg = error.msg +def curses_error(space, errmsg): w_module = space.getbuiltinmodule('_minimal_curses') w_exception_class = space.getattr(w_module, space.newtext('error')) - w_exception = space.call_function(w_exception_class, space.newtext(msg)) + w_exception = space.call_function(w_exception_class, space.newtext(errmsg)) return OperationError(w_exception_class, w_exception) -def _curses_setupterm_null(fd): - # NOT_RPYTHON - try: - _curses.setupterm(None, fd) - except _curses.error as e: - raise curses_error(e.args[0]) - -def _curses_setupterm(termname, fd): - # NOT_RPYTHON - try: - _curses.setupterm(termname, fd) - except _curses.error as e: - raise curses_error(e.args[0]) @unwrap_spec(fd=int) def setupterm(space, w_termname=None, fd=-1): @@ -47,48 +27,47 @@ space.newtext('stdout')) fd = space.int_w(space.call_function(space.getattr(w_stdout, space.newtext('fileno')))) - try: - if space.is_none(w_termname): - _curses_setupterm_null(fd) - else: - _curses_setupterm(space.text_w(w_termname), fd) - except curses_error as e: - raise convert_error(space, e) + if space.is_none(w_termname): + termname = None + else: + termname = space.text_w(w_termname) -class TermError(Exception): - pass + with rffi.scoped_str2charp(termname) as ll_term: + fd = rffi.cast(rffi.INT, fd) + ll_errmsg = fficurses.rpy_curses_setupterm(ll_term, fd) + if ll_errmsg: + raise curses_error(space, rffi.charp2str(ll_errmsg)) -def _curses_tigetstr(capname): - # NOT_RPYTHON - try: - res = _curses.tigetstr(capname) - except _curses.error as e: - raise curses_error(e.args[0]) - if res is None: - raise TermError - return res - -def _curses_tparm(s, args): - # NOT_RPYTHON - try: - return _curses.tparm(s, *args) - except _curses.error as e: - raise curses_error(e.args[0]) + space.fromcache(ModuleInfo).setupterm_called = True @unwrap_spec(capname='text') def tigetstr(space, capname): - try: - result = _curses_tigetstr(capname) - except TermError: - return space.w_None - except curses_error as e: - raise convert_error(space, e) - return space.newbytes(result) + check_setup_invoked(space) + with rffi.scoped_str2charp(capname) as ll_capname: + ll_result = fficurses.rpy_curses_tigetstr(ll_capname) + if ll_result: + return space.newbytes(rffi.charp2str(ll_result)) + else: + return space.w_None @unwrap_spec(s='bufferstr') def tparm(space, s, args_w): + check_setup_invoked(space) args = [space.int_w(a) for a in args_w] - try: - return space.newbytes(_curses_tparm(s, args)) - except curses_error as e: - raise convert_error(space, e) + # nasty trick stolen from CPython + x0 = args[0] if len(args) > 0 else 0 + x1 = args[1] if len(args) > 1 else 0 + x2 = args[2] if len(args) > 2 else 0 + x3 = args[3] if len(args) > 3 else 0 + x4 = args[4] if len(args) > 4 else 0 + x5 = args[5] if len(args) > 5 else 0 + x6 = args[6] if len(args) > 6 else 0 + x7 = args[7] if len(args) > 7 else 0 + x8 = args[8] if len(args) > 8 else 0 + with rffi.scoped_str2charp(s) as ll_str: + ll_result = fficurses.rpy_curses_tparm(ll_str, x0, x1, x2, x3, + x4, x5, x6, x7, x8) + if ll_result: + return space.newbytes(rffi.charp2str(ll_result)) + else: + raise curses_error(space, "tparm() returned NULL") diff --git a/pypy/module/_minimal_curses/test/test_curses.py b/pypy/module/_minimal_curses/test/test_curses.py --- a/pypy/module/_minimal_curses/test/test_curses.py +++ b/pypy/module/_minimal_curses/test/test_curses.py @@ -76,19 +76,27 @@ """ def test_csetupterm(self): from rpython.translator.c.test.test_genc import compile - from pypy.module._minimal_curses import interp_curses + from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.module._minimal_curses import fficurses + def runs_setupterm(): - interp_curses._curses_setupterm_null(1) + null = lltype.nullptr(rffi.CCHARP.TO) + fficurses.rpy_curses_setupterm(null, 1) fn = compile(runs_setupterm, []) fn() def test_ctgetstr(self): from rpython.translator.c.test.test_genc import compile - from pypy.module._minimal_curses import interp_curses + from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.module._minimal_curses import fficurses + def runs_ctgetstr(): - interp_curses._curses_setupterm("xterm", 1) - return interp_curses._curses_tigetstr('cup') + with rffi.scoped_str2charp("xterm") as ll_term: + fficurses.rpy_curses_setupterm(ll_term, 1) + with rffi.scoped_str2charp("cup") as ll_capname: + ll = fficurses.rpy_curses_tigetstr(ll_capname) + return rffi.charp2str(ll) fn = compile(runs_ctgetstr, []) res = fn() @@ -96,11 +104,16 @@ def test_ctparm(self): from rpython.translator.c.test.test_genc import compile - from pypy.module._minimal_curses import interp_curses + from rpython.rtyper.lltypesystem import lltype, rffi + from pypy.module._minimal_curses import fficurses + def runs_tparm(): - interp_curses._curses_setupterm("xterm", 1) - cup = interp_curses._curses_tigetstr('cup') - return interp_curses._curses_tparm(cup, [5, 3]) + with rffi.scoped_str2charp("xterm") as ll_term: + fficurses.rpy_curses_setupterm(ll_term, 1) + with rffi.scoped_str2charp("cup") as ll_capname: + cup = fficurses.rpy_curses_tigetstr(ll_capname) + res = fficurses.rpy_curses_tparm(cup, 5, 3, 0, 0, 0, 0, 0, 0, 0) + return rffi.charp2str(res) fn = compile(runs_tparm, []) res = fn() diff --git a/pypy/module/cpyext/include/pymem.h b/pypy/module/cpyext/include/pymem.h --- a/pypy/module/cpyext/include/pymem.h +++ b/pypy/module/cpyext/include/pymem.h @@ -60,6 +60,25 @@ #define PyMem_Del PyMem_Free #define PyMem_DEL PyMem_FREE + +/* From CPython 3.6, with a different goal. _PyTraceMalloc_Track() + * is equivalent to __pypy__.add_memory_pressure(size); it works with + * or without the GIL. _PyTraceMalloc_Untrack() is an empty stub. + * You can check if these functions are available by using: + * + * #if defined(PYPY_TRACEMALLOC) || \ + * (PY_VERSION_HEX >= 0x03060000 && !defined(Py_LIMITED_API)) + */ +#define PYPY_TRACEMALLOC 1 + +typedef unsigned int _PyTraceMalloc_domain_t; + +PyAPI_FUNC(int) _PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain, + uintptr_t ptr, size_t size); +PyAPI_FUNC(int) _PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain, + uintptr_t ptr); + + #ifdef __cplusplus } #endif 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 @@ -457,3 +457,8 @@ with rffi.scoped_nonmovingbuffer(data) as buf: fwrite(buf, 1, count, fp) return 0 + +@cpython_api([lltype.Signed], lltype.Void) +def _PyPyGC_AddMemoryPressure(space, report): + from rpython.rlib import rgc + rgc.add_memory_pressure(report) diff --git a/pypy/module/cpyext/src/pymem.c b/pypy/module/cpyext/src/pymem.c --- a/pypy/module/cpyext/src/pymem.c +++ b/pypy/module/cpyext/src/pymem.c @@ -84,3 +84,46 @@ { free(ptr); } + +int _PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain, + uintptr_t ptr, size_t size) +{ + /* to avoid acquiring/releasing the GIL too often, only do it + if the total reported size exceeds 64KB. */ + static volatile long unreported_size = 0; + long prev, next, report; + + size += sizeof(long); + /* ^^^ to account for some alignment. Important, otherwise we'd + * collect sizes of, say, 1-bytes mallocs in 1-bytes increment */ + + retry: + report = 0; + prev = unreported_size; + next = prev + size; + if (next >= 65536) { + report = next; + next = 0; + } + if (prev != next) { +#ifdef _WIN32 + if (InterlockedCompareExchange(&unreported_size, next, prev) != prev) + goto retry; +#else + if (!__sync_bool_compare_and_swap(&unreported_size, prev, next)) + goto retry; +#endif + } + + if (report) { + PyGILState_STATE state = PyGILState_Ensure(); + _PyPyGC_AddMemoryPressure(report); + PyGILState_Release(state); + } +} + +int _PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain, + uintptr_t ptr) +{ + /* nothing */ +} diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -191,10 +191,40 @@ class AppTestObject(AppTestCpythonExtensionBase): def setup_class(cls): + from rpython.rlib import rgc + from pypy.interpreter import gateway + AppTestCpythonExtensionBase.setup_class.im_func(cls) tmpname = str(py.test.ensuretemp('out', dir=0)) cls.w_tmpname = cls.space.wrap(tmpname) + if not cls.runappdirect: + cls.total_mem = 0 + def add_memory_pressure(estimate): + assert estimate >= 0 + cls.total_mem += estimate + cls.orig_add_memory_pressure = [rgc.add_memory_pressure] + rgc.add_memory_pressure = add_memory_pressure + + def _reset_memory_pressure(space): + cls.total_mem = 0 + cls.w_reset_memory_pressure = cls.space.wrap( + gateway.interp2app(_reset_memory_pressure)) + + def _cur_memory_pressure(space): + return space.newint(cls.total_mem) + cls.w_cur_memory_pressure = cls.space.wrap( + gateway.interp2app(_cur_memory_pressure)) + else: + def _skip_test(*ignored): + pytest.skip("not for -A testing") + cls.w_reset_memory_pressure = _skip_test + + def teardown_class(cls): + from rpython.rlib import rgc + if hasattr(cls, 'orig_add_memory_pressure'): + [rgc.add_memory_pressure] = cls.orig_add_memory_pressure + def test_object_malloc(self): module = self.import_extension('foo', [ ("malloctest", "METH_NOARGS", @@ -310,6 +340,31 @@ assert type(module.asbytes(sub1(b''))) is bytes assert type(module.asbytes(sub2(b''))) is sub2 + def test_add_memory_pressure(self): + self.reset_memory_pressure() # for the potential skip + module = self.import_extension('foo', [ + ("foo", "METH_O", + """ + _PyTraceMalloc_Track(0, 0, PyInt_AsLong(args) - sizeof(long)); + Py_INCREF(Py_None); + return Py_None; + """)]) + self.reset_memory_pressure() + module.foo(42) + assert self.cur_memory_pressure() == 0 + module.foo(65000 - 42) + assert self.cur_memory_pressure() == 0 + module.foo(536) + assert self.cur_memory_pressure() == 65536 + module.foo(40000) + assert self.cur_memory_pressure() == 65536 + module.foo(40000) + assert self.cur_memory_pressure() == 65536 + 80000 + module.foo(35000) + assert self.cur_memory_pressure() == 65536 + 80000 + module.foo(35000) + assert self.cur_memory_pressure() == 65536 + 80000 + 70000 + class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase): """ PyBuffer_FillInfo populates the fields of a Py_buffer from its arguments. diff --git a/pypy/sandbox/test/test_pypy_interact.py b/pypy/sandbox/test/test_pypy_interact.py --- a/pypy/sandbox/test/test_pypy_interact.py +++ b/pypy/sandbox/test/test_pypy_interact.py @@ -74,7 +74,8 @@ def setup_module(mod): - t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True) + t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True, + lldebug=True) mod.executable = str(t.compile()) diff --git a/rpython/translator/c/src/stacklet/stacklet.c b/rpython/translator/c/src/stacklet/stacklet.c --- a/rpython/translator/c/src/stacklet/stacklet.c +++ b/rpython/translator/c/src/stacklet/stacklet.c @@ -16,6 +16,7 @@ * can redefine it to upwards growing, 1. */ #define STACK_DIRECTION 0 +#define STATIC_NOINLINE __attribute__((noinline)) static #include "src/stacklet/slp_platformselect.h" @@ -56,11 +57,6 @@ stacklet_thread_handle stack_thrd; /* the thread where the stacklet is */ }; -void *(*_stacklet_switchstack)(void*(*)(void*, void*), - void*(*)(void*, void*), void*) = NULL; -void (*_stacklet_initialstub)(struct stacklet_thread_s *, - stacklet_run_fn, void *) = NULL; - struct stacklet_thread_s { struct stacklet_s *g_stack_chain_head; /* NULL <=> running main */ char *g_current_stack_stop; @@ -252,8 +248,17 @@ return EMPTY_STACKLET_HANDLE; } -static void g_initialstub(struct stacklet_thread_s *thrd, - stacklet_run_fn run, void *run_arg) +STATIC_NOINLINE +void *_stacklet_switchstack(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) +{ + return slp_switch(save_state, restore_state, extra); +} + +STATIC_NOINLINE +void g_initialstub(struct stacklet_thread_s *thrd, + stacklet_run_fn run, void *run_arg) { struct stacklet_s *result; @@ -284,13 +289,6 @@ { struct stacklet_thread_s *thrd; - if (_stacklet_switchstack == NULL) { - /* set up the following global with an indirection, which is needed - to prevent any inlining */ - _stacklet_initialstub = g_initialstub; - _stacklet_switchstack = slp_switch; - } - thrd = malloc(sizeof(struct stacklet_thread_s)); if (thrd != NULL) memset(thrd, 0, sizeof(struct stacklet_thread_s)); @@ -311,7 +309,7 @@ thrd->g_current_stack_stop = ((char *)&stackmarker) + 1; thrd->g_current_stack_marker = (char *)&stackmarker; - _stacklet_initialstub(thrd, run, run_arg); + g_initialstub(thrd, run, run_arg); return thrd->g_source; } diff --git a/rpython/translator/c/src/stacklet/switch_x64_msvc.h b/rpython/translator/c/src/stacklet/switch_x64_msvc.h --- a/rpython/translator/c/src/stacklet/switch_x64_msvc.h +++ b/rpython/translator/c/src/stacklet/switch_x64_msvc.h @@ -5,3 +5,5 @@ void *(*restore_state)(void*, void*), void *extra); +#undef STATIC_NOINLINE +#define STATIC_NOINLINE static __declspec(noinline) diff --git a/rpython/translator/c/src/stacklet/switch_x86_msvc.h b/rpython/translator/c/src/stacklet/switch_x86_msvc.h --- a/rpython/translator/c/src/stacklet/switch_x86_msvc.h +++ b/rpython/translator/c/src/stacklet/switch_x86_msvc.h @@ -5,6 +5,9 @@ void *(*restore_state)(void*, void*), void *extra); +#undef STATIC_NOINLINE +#define STATIC_NOINLINE static __declspec(noinline) + #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/rpython/translator/sandbox/test/test_sandbox.py b/rpython/translator/sandbox/test/test_sandbox.py --- a/rpython/translator/sandbox/test/test_sandbox.py +++ b/rpython/translator/sandbox/test/test_sandbox.py @@ -37,9 +37,9 @@ write_message(g, result, resulttype) g.flush() -def compile(f, gc='ref'): +def compile(f, gc='ref', **kwds): t = Translation(f, backend='c', sandbox=True, gc=gc, - check_str_without_nul=True) + check_str_without_nul=True, **kwds) return str(t.compile()) def run_in_subprocess(exe): @@ -198,7 +198,7 @@ l.append("x" * int(argv[2])) return int(len(l) > 1000) - exe = compile(entry_point, gc='hybrid') + exe = compile(entry_point, gc='hybrid', lldebug=True) pipe = subprocess.Popen([exe, '10', '10000'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) g = pipe.stdin diff --git a/rpython/translator/tool/cbuild.py b/rpython/translator/tool/cbuild.py --- a/rpython/translator/tool/cbuild.py +++ b/rpython/translator/tool/cbuild.py @@ -334,3 +334,9 @@ d['separate_module_files'] = () d['separate_module_sources'] = () return ExternalCompilationInfo(**d) + + def copy_without(self, *names): + d = self._copy_attributes() + for name in names: + del d[name] + return ExternalCompilationInfo(**d) diff --git a/testrunner/app_level_tests.py b/testrunner/app_level_tests.py new file mode 100755 --- /dev/null +++ b/testrunner/app_level_tests.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +""" +This is what the buildbot runs to execute the app-level tests +on top of pypy-c. +""" + +import sys, os +import subprocess + +rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) +os.environ['PYTHONPATH'] = rootdir +os.environ['PYTEST_PLUGINS'] = '' + +popen = subprocess.Popen( + [sys.executable, "testrunner/runner.py", + "--logfile=pytest-A.log", + "--config=pypy/pytest-A.cfg", + "--config=pypy/pytest-A.py", + "--config=~/machine-A_cfg.py", + "--root=pypy", "--timeout=3600", + ] + sys.argv[1:], + cwd=rootdir) + +try: + ret = popen.wait() +except KeyboardInterrupt: + popen.kill() + print "\ninterrupted" + ret = 1 + +sys.exit(ret) diff --git a/testrunner/lib_python_tests.py b/testrunner/lib_python_tests.py new file mode 100755 --- /dev/null +++ b/testrunner/lib_python_tests.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +""" +This is what the buildbot runs to execute the lib-python tests +on top of pypy-c. +""" + +import sys, os +import subprocess + +rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) +os.environ['PYTHONPATH'] = rootdir +os.environ['PYTEST_PLUGINS'] = '' + +popen = subprocess.Popen( + [sys.executable, "pypy/test_all.py", + "--pypy=pypy/goal/pypy3-c", + "--timeout=3600", + "--resultlog=cpython.log", "lib-python", + ] + sys.argv[1:], + cwd=rootdir) + +try: + ret = popen.wait() +except KeyboardInterrupt: + popen.kill() + print "\ninterrupted" + ret = 1 + +sys.exit(ret) diff --git a/testrunner/pypyjit_tests.py b/testrunner/pypyjit_tests.py new file mode 100755 --- /dev/null +++ b/testrunner/pypyjit_tests.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +""" +This is what the buildbot runs to execute the pypyjit tests +on top of pypy-c. +""" + +import sys, os +import subprocess + +rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) +os.environ['PYTHONPATH'] = rootdir +os.environ['PYTEST_PLUGINS'] = '' + +popen = subprocess.Popen( + [sys.executable, "pypy/test_all.py", + "--pypy=pypy/goal/pypy3-c", + "--resultlog=pypyjit_new.log", + "pypy/module/pypyjit/test_pypy_c", + ] + sys.argv[1:], + cwd=rootdir) + +try: + ret = popen.wait() +except KeyboardInterrupt: + popen.kill() + print "\ninterrupted" + ret = 1 + +sys.exit(ret) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit