Author: Ronan Lamy <ronan.l...@gmail.com> Branch: py3.5 Changeset: r93107:3e868c28555c Date: 2017-11-21 01:59 +0000 http://bitbucket.org/pypy/pypy/changeset/3e868c28555c/
Log: hg merge default diff --git a/lib-python/2.7/test/test_urllib2net.py b/lib-python/2.7/test/test_urllib2net.py --- a/lib-python/2.7/test/test_urllib2net.py +++ b/lib-python/2.7/test/test_urllib2net.py @@ -286,7 +286,7 @@ self.assertEqual(u.fp._sock.fp._sock.gettimeout(), 120) u.close() - FTP_HOST = 'ftp://ftp.debian.org/debian/' + FTP_HOST = 'ftp://www.pythontest.net/' def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) 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 @@ -20,3 +20,9 @@ .. branch: run-extra-tests Run extra_tests/ in buildbot + +.. branch: vmprof-0.4.10 +Upgrade the _vmprof backend to vmprof 0.4.10 + +.. branch: fix-vmprof-stacklet-switch +Fix a vmprof+continulets (i.e. greenelts, eventlet, gevent, ...) diff --git a/pypy/module/_continuation/test/test_stacklet.py b/pypy/module/_continuation/test/test_stacklet.py --- a/pypy/module/_continuation/test/test_stacklet.py +++ b/pypy/module/_continuation/test/test_stacklet.py @@ -8,6 +8,35 @@ cls.w_translated = cls.space.wrap( os.path.join(os.path.dirname(__file__), 'test_translated.py')) + cls.w_stack = cls.space.appexec([], """(): + import sys + def stack(f=None): + ''' + get the call-stack of the caller or the specified frame + ''' + if f is None: + f = sys._getframe(1) + res = [] + seen = set() + while f: + if f in seen: + # frame cycle + res.append('...') + break + if f.f_code.co_name == 'runtest': + # if we are running with -A, cut all the stack above + # the test function + break + seen.add(f) + res.append(f.f_code.co_name) + f = f.f_back + #print res + return res + return stack + """) + if cls.runappdirect: + # make sure that "self.stack" does not pass the self + cls.w_stack = staticmethod(cls.w_stack.im_func) def test_new_empty(self): from _continuation import continulet @@ -339,17 +368,24 @@ def test_f_back(self): import sys from _continuation import continulet + stack = self.stack # def bar(c): + assert stack() == ['bar', 'foo', 'test_f_back'] c.switch(sys._getframe(0)) c.switch(sys._getframe(0).f_back) c.switch(sys._getframe(1)) + # + assert stack() == ['bar', 'foo', 'main', 'test_f_back'] c.switch(sys._getframe(1).f_back) + # + assert stack() == ['bar', 'foo', 'main2', 'test_f_back'] assert sys._getframe(2) is f3_foo.f_back c.switch(sys._getframe(2)) def foo(c): bar(c) # + assert stack() == ['test_f_back'] c = continulet(foo) f1_bar = c.switch() assert f1_bar.f_code.co_name == 'bar' @@ -358,14 +394,20 @@ f3_foo = c.switch() assert f3_foo is f2_foo assert f1_bar.f_back is f3_foo + # def main(): f4_main = c.switch() assert f4_main.f_code.co_name == 'main' assert f3_foo.f_back is f1_bar # not running, so a loop + assert stack() == ['main', 'test_f_back'] + assert stack(f1_bar) == ['bar', 'foo', '...'] + # def main2(): f5_main2 = c.switch() assert f5_main2.f_code.co_name == 'main2' assert f3_foo.f_back is f1_bar # not running, so a loop + assert stack(f1_bar) == ['bar', 'foo', '...'] + # main() main2() res = c.switch() diff --git a/pypy/module/_continuation/test/test_translated.py b/pypy/module/_continuation/test/test_translated.py --- a/pypy/module/_continuation/test/test_translated.py +++ b/pypy/module/_continuation/test/test_translated.py @@ -5,6 +5,7 @@ py.test.skip("to run on top of a translated pypy-c") import sys, random +from rpython.tool.udir import udir # ____________________________________________________________ @@ -92,6 +93,33 @@ from pypy.conftest import option if not option.runappdirect: py.test.skip("meant only for -A run") + cls.w_vmprof_file = cls.space.wrap(str(udir.join('profile.vmprof'))) + + def test_vmprof(self): + """ + The point of this test is to check that we do NOT segfault. In + particular, we need to ensure that vmprof does not sample the stack in + the middle of a switch, else we read nonsense. + """ + try: + import _vmprof + except ImportError: + py.test.skip("no _vmprof") + # + def switch_forever(c): + while True: + c.switch() + # + f = open(self.vmprof_file, 'w+b') + _vmprof.enable(f.fileno(), 1/250.0, False, False, False, False) + c = _continuation.continulet(switch_forever) + for i in range(10**7): + if i % 100000 == 0: + print i + c.switch() + _vmprof.disable() + f.close() + def _setup(): for _i in range(20): diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py --- a/pypy/module/_vmprof/interp_vmprof.py +++ b/pypy/module/_vmprof/interp_vmprof.py @@ -93,8 +93,8 @@ return space.newtext(path) def stop_sampling(space): - return space.newint(rvmprof.stop_sampling(space)) + return space.newint(rvmprof.stop_sampling()) def start_sampling(space): - rvmprof.start_sampling(space) + rvmprof.start_sampling() return space.w_None diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -237,9 +237,9 @@ assert isinstance(w_long, W_LongObject) return w_long.num.sign -UCHARP = lltype.Ptr(lltype.Array( - rffi.UCHAR, hints={'nolength':True, 'render_as_const':True})) -@cpython_api([UCHARP, rffi.SIZE_T, rffi.INT_real, rffi.INT_real], PyObject) +CONST_UCHARP = lltype.Ptr(lltype.Array(rffi.UCHAR, hints={'nolength': True, + 'render_as_const': True})) +@cpython_api([CONST_UCHARP, rffi.SIZE_T, rffi.INT_real, rffi.INT_real], PyObject) def _PyLong_FromByteArray(space, bytes, n, little_endian, signed): little_endian = rffi.cast(lltype.Signed, little_endian) signed = rffi.cast(lltype.Signed, signed) diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py @@ -2271,7 +2271,7 @@ char32_t foo_4bytes(char32_t); """) lib = verify(ffi, "test_char16_char32_type" + no_cpp * "_nocpp", """ - #if !defined(__cplusplus) || __cplusplus < 201103L + #if !defined(__cplusplus) || (!defined(_LIBCPP_VERSION) && __cplusplus < 201103L) typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #endif diff --git a/pypy/module/thread/test/test_import_lock.py b/pypy/module/thread/test/test_import_lock.py --- a/pypy/module/thread/test/test_import_lock.py +++ b/pypy/module/thread/test/test_import_lock.py @@ -101,8 +101,8 @@ importhook(space, 'sys') assert importlock.count == 0 # A new module - importhook(space, "time") - assert importlock.count == 1 + importhook(space, 're') + assert importlock.count >= 9 # Import it again previous_count = importlock.count importhook(space, "time") diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -15,34 +15,10 @@ typeof, s_ImpossibleValue, SomeInstance, intersection, difference) from rpython.annotator.bookkeeper import Bookkeeper from rpython.rtyper.normalizecalls import perform_normalizations -from collections import deque log = AnsiLogger("annrpython") -class ShuffleDict(object): - def __init__(self): - self._d = {} - self.keys = deque() - - def __setitem__(self, k, v): - if k in self._d: - self._d[k] = v - else: - self._d[k] = v - self.keys.append(k) - - def __getitem__(self, k): - return self._d[k] - - def popitem(self): - key = self.keys.popleft() - item = self._d.pop(key) - return (key, item) - - def __nonzero__(self): - return bool(self._d) - class RPythonAnnotator(object): """Block annotator for RPython. See description in doc/translation.txt.""" @@ -57,7 +33,7 @@ translator = TranslationContext() translator.annotator = self self.translator = translator - self.pendingblocks = ShuffleDict() # map {block: graph-containing-it} + self.genpendingblocks=[{}] # [{block: graph-containing-it}] * generation self.annotated = {} # set of blocks already seen self.added_blocks = None # see processblock() below self.links_followed = {} # set of links that have ever been followed @@ -81,7 +57,7 @@ self.errors = [] def __getstate__(self): - attrs = """translator pendingblocks annotated links_followed + attrs = """translator genpendingblocks annotated links_followed notify bookkeeper frozen policy added_blocks""".split() ret = self.__dict__.copy() for key, value in ret.items(): @@ -212,19 +188,47 @@ else: self.mergeinputargs(graph, block, cells) if not self.annotated[block]: - self.pendingblocks[block] = graph + self.schedulependingblock(graph, block) + + def schedulependingblock(self, graph, block): + # 'self.genpendingblocks' is a list of dictionaries which is + # logically equivalent to just one dictionary. But we keep a + # 'generation' number on each block (=key), and whenever we + # process a block, we increase its generation number. The + # block is added to the 'genpendingblocks' indexed by its + # generation number. See complete_pending_blocks() below. + generation = getattr(block, 'generation', 0) + self.genpendingblocks[generation][block] = graph def complete_pending_blocks(self): - while self.pendingblocks: - block, graph = self.pendingblocks.popitem() - self.processblock(graph, block) + while True: + # Find the first of the dictionaries in 'self.genpendingblocks' + # which is not empty + gen = 0 + for pendingblocks in self.genpendingblocks: + if pendingblocks: + break + gen += 1 + else: + return # all empty => done + + gen += 1 # next generation number + if len(self.genpendingblocks) == gen: + self.genpendingblocks.append({}) + + # Process all blocks at this level + # (if any gets re-inserted, it will be into the next level) + while pendingblocks: + block, graph = pendingblocks.popitem() + block.generation = gen + self.processblock(graph, block) def complete(self): """Process pending blocks until none is left.""" while True: self.complete_pending_blocks() self.policy.no_more_blocks_to_annotate(self) - if not self.pendingblocks: + if not any(self.genpendingblocks): break # finished # make sure that the return variables of all graphs is annotated if self.added_blocks is not None: @@ -309,21 +313,15 @@ #___ interface for annotator.bookkeeper _______ def recursivecall(self, graph, whence, inputcells): - if isinstance(whence, tuple): + if whence is not None: parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - # self.notify[graph.returnblock] is a dictionary of call - # points to this func which triggers a reflow whenever the - # return block of this graph has been analysed. - callpositions = self.notify.setdefault(graph.returnblock, {}) - if whence is not None: - if callable(whence): - def callback(): - whence(self, graph) - else: - callback = whence - callpositions[callback] = True + # self.notify[graph.returnblock] is a set of call + # points to this func which triggers a reflow whenever the + # return block of this graph has been analysed. + returnpositions = self.notify.setdefault(graph.returnblock, set()) + returnpositions.add(whence) # generalize the function's input arguments self.addpendingblock(graph, graph.startblock, inputcells) @@ -416,7 +414,7 @@ def reflowpendingblock(self, graph, block): assert not self.frozen assert graph not in self.fixed_graphs - self.pendingblocks[block] = graph + self.schedulependingblock(graph, block) assert block in self.annotated self.annotated[block] = False # must re-flow self.blocked_blocks[block] = (graph, None) @@ -574,12 +572,8 @@ self.follow_link(graph, link, constraints) if block in self.notify: - # reflow from certain positions when this block is done - for callback in self.notify[block]: - if isinstance(callback, tuple): - self.reflowfromposition(callback) # callback is a position - else: - callback() + for position in self.notify[block]: + self.reflowfromposition(position) def follow_link(self, graph, link, constraints): diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -547,10 +547,8 @@ (position_key, "first") and (position_key, "second"). In general, "unique_key" should somehow uniquely identify where - the call is in the source code, and "callback" can be either a - position_key to reflow from when we see more general results, - or a real callback function that will be called with arguments - # "(annotator, called_graph)" whenever the result is generalized. + the call is in the source code, and "callback" is a + position_key to reflow from when we see more general results. "replace" can be set to a list of old unique_key values to forget now, because the given "unique_key" replaces them. diff --git a/rpython/annotator/dictdef.py b/rpython/annotator/dictdef.py --- a/rpython/annotator/dictdef.py +++ b/rpython/annotator/dictdef.py @@ -1,5 +1,5 @@ from rpython.annotator.model import ( - s_ImpossibleValue, SomeInteger, s_Bool, union) + s_ImpossibleValue, SomeInteger, s_Bool, union, AnnotatorError) from rpython.annotator.listdef import ListItem from rpython.rlib.objectmodel import compute_hash @@ -51,23 +51,19 @@ s_key = self.s_value - def check_eqfn(annotator, graph): - s = annotator.binding(graph.getreturnvar()) - assert s_Bool.contains(s), ( + s = self.bookkeeper.emulate_pbc_call( + myeq, self.s_rdict_eqfn, [s_key, s_key], replace=replace_othereq) + if not s_Bool.contains(s): + raise AnnotatorError( "the custom eq function of an r_dict must return a boolean" " (got %r)" % (s,)) - self.bookkeeper.emulate_pbc_call(myeq, self.s_rdict_eqfn, [s_key, s_key], - replace=replace_othereq, - callback = check_eqfn) - def check_hashfn(annotator, graph): - s = annotator.binding(graph.getreturnvar()) - assert SomeInteger().contains(s), ( + s = self.bookkeeper.emulate_pbc_call( + myhash, self.s_rdict_hashfn, [s_key], replace=replace_otherhash) + if not SomeInteger().contains(s): + raise AnnotatorError( "the custom hash function of an r_dict must return an integer" " (got %r)" % (s,)) - self.bookkeeper.emulate_pbc_call(myhash, self.s_rdict_hashfn, [s_key], - replace=replace_otherhash, - callback = check_hashfn) class DictValue(ListItem): @@ -93,11 +89,11 @@ self.force_non_null = force_non_null def read_key(self, position_key): - self.dictkey.read_locations[position_key] = True + self.dictkey.read_locations.add(position_key) return self.dictkey.s_value def read_value(self, position_key): - self.dictvalue.read_locations[position_key] = True + self.dictvalue.read_locations.add(position_key) return self.dictvalue.s_value def same_as(self, other): diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py --- a/rpython/annotator/listdef.py +++ b/rpython/annotator/listdef.py @@ -30,7 +30,7 @@ self.s_value = s_value self.bookkeeper = bookkeeper self.itemof = {} # set of all ListDefs using this ListItem - self.read_locations = {} + self.read_locations = set() if bookkeeper is None: self.dont_change_any_more = True @@ -95,7 +95,7 @@ self.notify_update() if s_new_value != s_other_value: other.notify_update() - self.read_locations.update(other.read_locations) + self.read_locations |= other.read_locations def patch(self): for listdef in self.itemof: @@ -130,7 +130,7 @@ self.listitem.itemof[self] = True def read_item(self, position_key): - self.listitem.read_locations[position_key] = True + self.listitem.read_locations.add(position_key) return self.listitem.s_value def same_as(self, other): diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -2141,28 +2141,6 @@ assert (fdesc.get_s_signatures((2, (), False)) == [([someint,someint],someint)]) - def test_emulated_pbc_call_callback(self): - def f(a,b): - return a + b - from rpython.annotator import annrpython - a = annrpython.RPythonAnnotator() - from rpython.annotator import model as annmodel - - memo = [] - def callb(ann, graph): - memo.append(annmodel.SomeInteger() == ann.binding(graph.getreturnvar())) - - s_f = a.bookkeeper.immutablevalue(f) - s = a.bookkeeper.emulate_pbc_call('f', s_f, [annmodel.SomeInteger(), annmodel.SomeInteger()], - callback=callb) - assert s == annmodel.SomeImpossibleValue() - a.complete() - - assert a.binding(graphof(a, f).getreturnvar()).knowntype == int - assert len(memo) >= 1 - for t in memo: - assert t - def test_iterator_union(self): def it(d): return d.iteritems() diff --git a/rpython/config/support.py b/rpython/config/support.py --- a/rpython/config/support.py +++ b/rpython/config/support.py @@ -41,8 +41,8 @@ Function to determine if your system comes with PAX protection. """ if sys.platform.startswith('linux'): - # we need a running process PID and 1 is always running - with open("/proc/1/status") as fd: + # use PID of current process for the check + with open("/proc/self/status") as fd: data = fd.read() if 'PaX' in data: return True diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py --- a/rpython/flowspace/model.py +++ b/rpython/flowspace/model.py @@ -170,7 +170,7 @@ class Block(object): __slots__ = """inputargs operations exitswitch - exits blockcolor""".split() + exits blockcolor generation""".split() def __init__(self, inputargs): self.inputargs = list(inputargs) # mixed list of variable/const XXX diff --git a/rpython/rlib/rerased.py b/rpython/rlib/rerased.py --- a/rpython/rlib/rerased.py +++ b/rpython/rlib/rerased.py @@ -15,6 +15,8 @@ """ import sys +from collections import defaultdict + from rpython.annotator import model as annmodel from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rtyper.llannotation import lltype_to_annotation @@ -48,34 +50,29 @@ def __deepcopy__(self, memo): return self - def _getdict(self, bk): - try: - dict = bk._erasing_pairs_tunnel - except AttributeError: - dict = bk._erasing_pairs_tunnel = {} - return dict +class IdentityDesc(object): + def __init__(self, bookkeeper): + self.bookkeeper = bookkeeper + self.s_input = annmodel.s_ImpossibleValue + self.reflowpositions = {} - def enter_tunnel(self, bookkeeper, s_obj): - dict = self._getdict(bookkeeper) - s_previousobj, reflowpositions = dict.setdefault( - self, (annmodel.s_ImpossibleValue, {})) - s_obj = annmodel.unionof(s_previousobj, s_obj) - if s_obj != s_previousobj: - dict[self] = (s_obj, reflowpositions) - for position in reflowpositions: - bookkeeper.annotator.reflowfromposition(position) + def enter_tunnel(self, s_obj): + s_obj = annmodel.unionof(self.s_input, s_obj) + if s_obj != self.s_input: + self.s_input = s_obj + for position in self.reflowpositions: + self.bookkeeper.annotator.reflowfromposition(position) - def leave_tunnel(self, bookkeeper): - dict = self._getdict(bookkeeper) - s_obj, reflowpositions = dict.setdefault( - self, (annmodel.s_ImpossibleValue, {})) - reflowpositions[bookkeeper.position_key] = True - return s_obj + def leave_tunnel(self): + self.reflowpositions[self.bookkeeper.position_key] = True + return self.s_input - def get_input_annotation(self, bookkeeper): - dict = self._getdict(bookkeeper) - s_obj, _ = dict[self] - return s_obj +def _get_desc(bk, identity): + try: + descs = bk._erasing_pairs_descs + except AttributeError: + descs = bk._erasing_pairs_descs = defaultdict(lambda: IdentityDesc(bk)) + return descs[identity] _identity_for_ints = ErasingPairIdentity("int") @@ -94,21 +91,23 @@ _about_ = erase def compute_result_annotation(self, s_obj): - identity.enter_tunnel(self.bookkeeper, s_obj) + desc = _get_desc(self.bookkeeper, identity) + desc.enter_tunnel(s_obj) return _some_erased() def specialize_call(self, hop): bk = hop.rtyper.annotator.bookkeeper - s_obj = identity.get_input_annotation(bk) + desc = _get_desc(bk, identity) hop.exception_cannot_occur() - return _rtype_erase(hop, s_obj) + return _rtype_erase(hop, desc.s_input) class Entry(ExtRegistryEntry): _about_ = unerase def compute_result_annotation(self, s_obj): assert _some_erased().contains(s_obj) - return identity.leave_tunnel(self.bookkeeper) + desc = _get_desc(self.bookkeeper, identity) + return desc.leave_tunnel() def specialize_call(self, hop): hop.exception_cannot_occur() @@ -130,6 +129,7 @@ def __init__(self, x, identity): self._x = x self._identity = identity + def __repr__(self): return "Erased(%r, %r)" % (self._x, self._identity) @@ -140,7 +140,7 @@ assert config.translation.taggedpointers, "need to enable tagged pointers to use erase_int" return lltype.cast_int_to_ptr(r_self.lowleveltype, value._x * 2 + 1) bk = r_self.rtyper.annotator.bookkeeper - s_obj = value._identity.get_input_annotation(bk) + s_obj = _get_desc(bk, value._identity).s_input r_obj = r_self.rtyper.getrepr(s_obj) if r_obj.lowleveltype is lltype.Void: return lltype.nullptr(r_self.lowleveltype.TO) @@ -182,9 +182,9 @@ _type_ = Erased def compute_annotation(self): - identity = self.instance._identity + desc = _get_desc(self.bookkeeper, self.instance._identity) s_obj = self.bookkeeper.immutablevalue(self.instance._x) - identity.enter_tunnel(self.bookkeeper, s_obj) + desc.enter_tunnel(s_obj) return _some_erased() # annotation and rtyping support diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -1881,7 +1881,8 @@ c_chroot = external('chroot', [rffi.CCHARP], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, - macro=_MACRO_ON_POSIX) + macro=_MACRO_ON_POSIX, + compilation_info=ExternalCompilationInfo(includes=['unistd.h'])) @replace_os_function('chroot') def chroot(path): diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py --- a/rpython/rlib/rstacklet.py +++ b/rpython/rlib/rstacklet.py @@ -3,6 +3,7 @@ from rpython.rlib import jit from rpython.rlib.objectmodel import fetch_translated_config from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.rlib import rvmprof from rpython.rlib.rvmprof import cintf DEBUG = False @@ -40,11 +41,13 @@ def switch(self, stacklet): if DEBUG: debug.remove(stacklet) + rvmprof.stop_sampling() x = cintf.save_rvmprof_stack() try: h = self._gcrootfinder.switch(stacklet) finally: cintf.restore_rvmprof_stack(x) + rvmprof.start_sampling() if DEBUG: debug.add(h) return h diff --git a/rpython/rlib/rvmprof/__init__.py b/rpython/rlib/rvmprof/__init__.py --- a/rpython/rlib/rvmprof/__init__.py +++ b/rpython/rlib/rvmprof/__init__.py @@ -55,9 +55,9 @@ return None -def stop_sampling(space): +def stop_sampling(): fd = _get_vmprof().cintf.vmprof_stop_sampling() return rffi.cast(lltype.Signed, fd) -def start_sampling(space): +def start_sampling(): _get_vmprof().cintf.vmprof_start_sampling() diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py --- a/rpython/rlib/rvmprof/cintf.py +++ b/rpython/rlib/rvmprof/cintf.py @@ -62,7 +62,6 @@ SHARED.join('compat.c'), SHARED.join('machine.c'), SHARED.join('vmp_stack.c'), - SHARED.join('vmprof_mt.c'), SHARED.join('vmprof_memory.c'), SHARED.join('vmprof_common.c'), # symbol table already in separate_module_files @@ -70,6 +69,10 @@ post_include_bits=[], compile_extra=compile_extra ) +if sys.platform != 'win32': + eci_kwds['separate_module_files'].append( + SHARED.join('vmprof_mt.c'), + ) global_eci = ExternalCompilationInfo(**eci_kwds) def configure_libbacktrace_linux(): diff --git a/rpython/rlib/rvmprof/test/test_rvmprof.py b/rpython/rlib/rvmprof/test/test_rvmprof.py --- a/rpython/rlib/rvmprof/test/test_rvmprof.py +++ b/rpython/rlib/rvmprof/test/test_rvmprof.py @@ -164,23 +164,25 @@ @rvmprof.vmprof_execute_code("xcode1", lambda self, code, count: code) def main(self, code, count): + code = self.MyCode('py:main:3:main') + rvmprof.register_code(code, self.MyCode.get_name) + code = self.MyCode('py:code:7:native_func') + rvmprof.register_code(code, self.MyCode.get_name) if count > 0: return self.main(code, count-1) else: return self.native_func(100) def test(self): - # XXX: this test is known to fail since rev a4f077ba651c, but buildbot - # never ran it. FIXME. from vmprof import read_profile - from vmprof.show import PrettyPrinter + # from vmprof.show import PrettyPrinter assert self.rpy_entry_point(3, 0.5) == 42000 assert self.tmpfile.check() - # + prof = read_profile(self.tmpfilename) tree = prof.get_tree() - p = PrettyPrinter() - p._print_tree(tree) + # p = PrettyPrinter() + # p._print_tree(tree) def walk(tree, symbols): symbols.append(tree.name) if len(tree.children) == 0: @@ -189,7 +191,7 @@ walk(child, symbols) symbols = [] walk(tree, symbols) - not_found = ['n:native_func'] + not_found = ['py:code:7:native_func'] for sym in symbols: for i,name in enumerate(not_found): if sym.startswith(name): 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 @@ -2,7 +2,7 @@ from rpython.rtyper.test.test_llinterp import interpret from rpython.rlib.rarithmetic import * from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError -from hypothesis import given, strategies +from hypothesis import given, strategies, assume import sys import py @@ -404,8 +404,11 @@ def test_int_c_div_mod(x, y): assert int_c_div(~x, y) == -(abs(~x) // y) assert int_c_div( x,-y) == -(x // y) - if (x, y) == (sys.maxint, 1): - py.test.skip("would overflow") + +@given(strategies.integers(min_value=0, max_value=sys.maxint), + strategies.integers(min_value=1, max_value=sys.maxint)) +def test_int_c_div_mod_2(x, y): + assume((x, y) != (sys.maxint, 1)) # This case would overflow assert int_c_div(~x,-y) == +(abs(~x) // y) for x1 in [x, ~x]: for y1 in [y, -y]: diff --git a/rpython/rlib/test/test_rstacklet.py b/rpython/rlib/test/test_rstacklet.py --- a/rpython/rlib/test/test_rstacklet.py +++ b/rpython/rlib/test/test_rstacklet.py @@ -10,6 +10,8 @@ from rpython.config.translationoption import DEFL_ROOTFINDER_WITHJIT from rpython.rlib import rrandom, rgc from rpython.rlib.rarithmetic import intmask +from rpython.rlib.nonconst import NonConstant +from rpython.rlib import rvmprof from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.c.test.test_standalone import StandaloneTests @@ -273,7 +275,23 @@ llmemory.raw_free(raw) +# <vmprof-hack> +# bah, we need to make sure that vmprof_execute_code is annotated, else +# rvmprof.c does not compile correctly +class FakeVMProfCode(object): + pass +rvmprof.register_code_object_class(FakeVMProfCode, lambda code: 'name') +@rvmprof.vmprof_execute_code("xcode1", lambda code, num: code) +def fake_vmprof_main(code, num): + return 42 +# </vmprof-hack> + def entry_point(argv): + # <vmprof-hack> + if NonConstant(False): + fake_vmprof_main(FakeVMProfCode(), 42) + # </vmprof-hack> + # seed = 0 if len(argv) > 1: seed = int(argv[1]) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit