Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: value-profiling
Changeset: r78993:f22171f122f5
Date: 2015-08-15 16:01 +0200
http://bitbucket.org/pypy/pypy/changeset/f22171f122f5/

Log:    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
@@ -66,3 +66,4 @@
 
 .. branch: vmprof-review
 
+Clean up of vmprof, notably to handle correctly multiple threads
diff --git a/pypy/module/_vmprof/__init__.py b/pypy/module/_vmprof/__init__.py
--- a/pypy/module/_vmprof/__init__.py
+++ b/pypy/module/_vmprof/__init__.py
@@ -1,4 +1,5 @@
 from pypy.interpreter.mixedmodule import MixedModule
+from rpython.rlib.rvmprof import VMProfPlatformUnsupported
 
 class Module(MixedModule):
     """
@@ -19,4 +20,7 @@
 # already found by the annotator to be the original empty
 # method, and the annotator doesn't notice that interp_vmprof.py
 # (loaded later) replaces this method.
-import pypy.module._vmprof.interp_vmprof
+try:
+    import pypy.module._vmprof.interp_vmprof
+except VMProfPlatformUnsupported, e:
+    pass
diff --git a/pypy/module/micronumpy/concrete.py 
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -52,11 +52,16 @@
 
     @jit.unroll_safe
     def setslice(self, space, arr):
-        if len(arr.get_shape()) > 0 and len(self.get_shape()) == 0:
-            raise oefmt(space.w_ValueError,
-                "could not broadcast input array from shape "
-                "(%s) into shape ()",
-                ','.join([str(x) for x in arr.get_shape()]))
+        if len(arr.get_shape()) >  len(self.get_shape()):
+            # record arrays get one extra dimension
+            if not self.dtype.is_record() or \
+                    len(arr.get_shape()) > len(self.get_shape()) + 1:
+                raise oefmt(space.w_ValueError,
+                    "could not broadcast input array from shape "
+                    "(%s) into shape (%s)",
+                    ','.join([str(x) for x in arr.get_shape()]),
+                    ','.join([str(x) for x in self.get_shape()]),
+                    )
         shape = shape_agreement(space, self.get_shape(), arr)
         impl = arr.implementation
         if impl.storage == self.storage:
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
@@ -247,6 +247,20 @@
         if space.is_w(w_idx, space.w_Ellipsis):
             self.implementation.setslice(space, convert_to_array(space, 
w_value))
             return
+        # TODO: multiarray/mapping.c calls a subclass's __getitem__ here, which
+        # is a big performance hit but necessary for the matrix class. The 
original
+        # C code is like:
+        #/*
+        #* WARNING: There is a huge special case here. If this is not a
+        #*          base class array, we have to get the view through its
+        #*          very own index machinery.
+        #*          Many subclasses should probably call __setitem__
+        #*          with a base class ndarray view to avoid this.
+        #*/
+        #else if (!(index_type & (HAS_FANCY | HAS_SCALAR_ARRAY))
+        #        && !PyArray_CheckExact(self)) {
+        #view = (PyArrayObject *)PyObject_GetItem((PyObject *)self, ind);
+
         elif isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool() \
                 and w_idx.ndims() > 0:
             self.setitem_filter(space, w_idx, convert_to_array(space, w_value))
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
@@ -2668,6 +2668,15 @@
         a[0, :: -1] = numpy.array([11, 12])
         assert (a == [[12, 11], [5, 10]]).all()
 
+        a = numpy.zeros((3, 2), int)
+        b = numpy.ones((3, 1), int)
+        exc = raises(ValueError, 'a[:, 1] = b')
+        assert str(exc.value) == "could not broadcast " +\
+                "input array from shape (3,1) into shape (3)"
+        a[:, 1] = b[:,0] > 0.5
+        assert (a == [[0, 1], [0, 1], [0, 1]]).all()
+        
+
     def test_ufunc(self):
         from numpy import array
         a = array([[1, 2], [3, 4], [5, 6]])
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py 
b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -1166,6 +1166,7 @@
         assert (logical_xor([True, False, True, False], [1, 2, 0, 0])
                 == [False, True, True, False]).all()
         assert (logical_not([True, False]) == [False, True]).all()
+        assert logical_and.reduce([1.,1.]) == True
 
     def test_logn(self):
         import math
diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py
--- a/pypy/module/micronumpy/ufuncs.py
+++ b/pypy/module/micronumpy/ufuncs.py
@@ -511,15 +511,15 @@
         W_Ufunc.__init__(self, name, promote_to_largest, promote_to_float, 
promote_bools,
                          identity, int_only, allow_bool, allow_complex, 
complex_to_float)
         self.func = func
-        self.bool_result = bool_result
         if name == 'logical_and':
             self.done_func = done_if_false
         elif name == 'logical_or':
             self.done_func = done_if_true
         else:
             self.done_func = None
+        self.bool_result = bool_result or (self.done_func is not None)
         self.simple_binary = (
-            allow_complex and allow_bool and not bool_result and not int_only
+            allow_complex and allow_bool and not self.bool_result and not 
int_only
             and not complex_to_float and not promote_to_float
             and not promote_bools)
 
@@ -630,7 +630,7 @@
                                             r_dtype.is_complex())):
             raise oefmt(space.w_TypeError,
                 "ufunc '%s' not supported for the input types", self.name)
-        if self.bool_result:
+        if self.bool_result and not self.done_func:
             # XXX: should actually pass the arrays
             dtype = find_result_type(space, [], [l_dtype, r_dtype])
             bool_dtype = get_dtype_cache(space).w_booldtype
diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py 
b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
--- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
@@ -28,9 +28,9 @@
             f16 = raw_load(i9, i5, descr=<ArrayF \d+>)
             guard_true(i15, descr=...)
             guard_not_invalidated(descr=...)
-            i17 = cast_float_to_int(f16)
-            i19 = int_is_true(i17)
-            guard_true(i19, descr=...)
+            i18 = float_ne(f16, 0.000000)
+            guard_true(i18, descr=...)
+            guard_nonnull_class(p2, ConstClass(W_BoolBox), descr=...)
             i20 = getfield_gc_pure(p2, descr=<FieldU 
pypy.module.micronumpy.boxes.W_BoolBox.inst_value \d+>)
             i21 = int_is_true(i20)
             guard_false(i21, descr=...)
@@ -70,10 +70,10 @@
         assert loop.match("""
             f31 = raw_load(i9, i29, descr=<ArrayF 8>)
             guard_not_invalidated(descr=...)
+            i32 = float_ne(f31, 0.000000)
+            guard_true(i32, descr=...)
             i34 = getarrayitem_raw(#, #, descr=<ArrayU 1>)  # XXX what are 
these?
             guard_value(i34, #, descr=...)                  # XXX don't appear 
in
-            i32 = float_ne(f31, 0.000000)
-            guard_true(i32, descr=...)
             i35 = getarrayitem_raw(#, #, descr=<ArrayU 1>)  # XXX equiv 
test_zjit
             i36 = int_add(i24, 1)
             i37 = int_add(i29, i28)
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
@@ -569,17 +569,19 @@
     rangen = unroll.unrolling_iterable(range(n))
     nmin1 = n - 1
     rangenmin1 = unroll.unrolling_iterable(range(nmin1))
+    valnmin1 = "_value%s" % nmin1
     class subcls(BaseMapdictObject, supercls):
         def _init_empty(self, map):
-            for i in rangen:
-                setattr(self, "_value%s" % i, erase_item(None))
+            for i in rangenmin1:
+                setattr(self, "_value%s" % i, None)
+            setattr(self, valnmin1, erase_item(None))
             self.map = map
 
         def _has_storage_list(self):
             return self.map.length() > n
 
         def _mapdict_get_storage_list(self):
-            erased = getattr(self, "_value%s" % nmin1)
+            erased = getattr(self, valnmin1)
             return unerase_list(erased)
 
         def _mapdict_read_storage(self, storageindex):
@@ -587,23 +589,21 @@
             if storageindex < nmin1:
                 for i in rangenmin1:
                     if storageindex == i:
-                        erased = getattr(self, "_value%s" % i)
-                        return unerase_item(erased)
+                        return getattr(self, "_value%s" % i)
             if self._has_storage_list():
                 return self._mapdict_get_storage_list()[storageindex - nmin1]
             erased = getattr(self, "_value%s" % nmin1)
             return unerase_item(erased)
 
         def _mapdict_write_storage(self, storageindex, value):
-            erased = erase_item(value)
             for i in rangenmin1:
                 if storageindex == i:
-                    setattr(self, "_value%s" % i, erased)
+                    setattr(self, "_value%s" % i, value)
                     return
             if self._has_storage_list():
                 self._mapdict_get_storage_list()[storageindex - nmin1] = value
                 return
-            setattr(self, "_value%s" % nmin1, erased)
+            setattr(self, "_value%s" % nmin1, erase_item(value))
 
         def _mapdict_storage_length(self):
             if self._has_storage_list():
@@ -615,9 +615,9 @@
             len_storage = len(storage)
             for i in rangenmin1:
                 if i < len_storage:
-                    erased = erase_item(storage[i])
+                    erased = storage[i]
                 else:
-                    erased = erase_item(None)
+                    erased = None
                 setattr(self, "_value%s" % i, erased)
             has_storage_list = self._has_storage_list()
             if len_storage < n:
diff --git a/pypy/objspace/std/stringmethods.py 
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -195,7 +195,8 @@
             splitted = split(value, self._chr('\t'))
 
         try:
-            ovfcheck(len(splitted) * tabsize)
+            if tabsize > 0:
+                ovfcheck(len(splitted) * tabsize)
         except OverflowError:
             raise oefmt(space.w_OverflowError, "new string is too long")
         expanded = oldtoken = splitted.pop(0)
@@ -210,6 +211,8 @@
     def _tabindent(self, token, tabsize):
         """calculates distance behind the token to the next tabstop"""
 
+        if tabsize <= 0:
+            return 0
         distance = tabsize
         if token:
             distance = 0
diff --git a/pypy/objspace/std/test/test_bytesobject.py 
b/pypy/objspace/std/test/test_bytesobject.py
--- a/pypy/objspace/std/test/test_bytesobject.py
+++ b/pypy/objspace/std/test/test_bytesobject.py
@@ -388,6 +388,10 @@
             skip("Wrong platform")
         raises((MemoryError, OverflowError), 't\tt\t'.expandtabs, sys.maxint)
 
+    def test_expandtabs_0(self):
+        assert 'x\ty'.expandtabs(0) == 'xy'
+        assert 'x\ty'.expandtabs(-42) == 'xy'
+
     def test_splitlines(self):
         s = ""
         assert s.splitlines() == []
diff --git a/pypy/objspace/std/test/test_mapdict.py 
b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -500,12 +500,12 @@
         obj = objectcls()
         obj.user_setup(space, cls)
         obj.setdictvalue(space, "a", w1)
-        assert unerase_item(obj._value0) is w1
+        assert obj._value0 is w1
         assert obj.getdictvalue(space, "a") is w1
         assert obj.getdictvalue(space, "b") is None
         assert obj.getdictvalue(space, "c") is None
         obj.setdictvalue(space, "a", w2)
-        assert unerase_item(obj._value0) is w2
+        assert obj._value0 is w2
         assert obj.getdictvalue(space, "a") == w2
         assert obj.getdictvalue(space, "b") is None
         assert obj.getdictvalue(space, "c") is None
@@ -523,7 +523,7 @@
 
         res = obj.deldictvalue(space, "a")
         assert res
-        assert unerase_item(obj._value0) is w4
+        assert obj._value0 is w4
         assert obj.getdictvalue(space, "a") is None
         assert obj.getdictvalue(space, "b") is w4
         assert obj.getdictvalue(space, "c") is None
diff --git a/pypy/objspace/std/test/test_unicodeobject.py 
b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -494,6 +494,10 @@
             skip("Wrong platform")
         raises((OverflowError, MemoryError), u't\tt\t'.expandtabs, sys.maxint)
 
+    def test_expandtabs_0(self):
+        assert u'x\ty'.expandtabs(0) == u'xy'
+        assert u'x\ty'.expandtabs(-42) == u'xy'
+
     def test_translate(self):
         assert u'bbbc' == u'abababc'.translate({ord('a'):None})
         assert u'iiic' == u'abababc'.translate({ord('a'):None, 
ord('b'):ord('i')})
diff --git a/rpython/jit/codewriter/support.py 
b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -79,9 +79,6 @@
             assert methname == 'jit_merge_point', (
                 "reds='auto' is supported only for jit drivers which "
                 "calls only jit_merge_point. Found a call to %s" % methname)
-            if jitdriver.numreds is not None:
-                raise AssertionError("there are multiple jit_merge_points "
-                                     "with the same jitdriver")
             #
             # compute the set of live variables across the jit_marker
             alive_v = set()
@@ -99,7 +96,11 @@
                                            v.concretetype is not lltype.Void]
             reds_v = sort_vars(reds_v)
             op.args.extend(reds_v)
-            jitdriver.numreds = len(reds_v)
+            if jitdriver.numreds is None:
+                jitdriver.numreds = len(reds_v)
+            elif jitdriver.numreds != len(reds_v):
+                raise AssertionError("there are multiple jit_merge_points "
+                                     "with the same jitdriver")
 
 def split_before_jit_merge_point(graph, portalblock, portalopindex):
     """Split the block just before the 'jit_merge_point',
diff --git a/rpython/jit/metainterp/heapcache.py 
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -9,6 +9,7 @@
 
     def reset_keep_likely_virtual(self):
         self.known_class = False
+        self.known_nullity = False
         # did we see the allocation during tracing?
         self.seen_allocation = False
         self.is_unescaped = False
@@ -290,6 +291,15 @@
     def class_now_known(self, box):
         self.getvalue(box).known_class = True
 
+    def is_nullity_known(self, box):
+        value = self.getvalue(box, create=False)
+        if value:
+            return value.known_nullity
+        return False
+
+    def nullity_now_known(self, box):
+        self.getvalue(box).known_nullity = True
+
     def is_nonstandard_virtualizable(self, box):
         value = self.getvalue(box, create=False)
         if value:
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -369,7 +369,10 @@
         ).compile()
 
     def _establish_nullity(self, box, orgpc):
+        heapcache = self.metainterp.heapcache
         value = box.nonnull()
+        if heapcache.is_nullity_known(box):
+            return value
         if value:
             if not self.metainterp.heapcache.is_class_known(box):
                 self.metainterp.generate_guard(rop.GUARD_NONNULL, box,
@@ -380,6 +383,7 @@
                                                resumepc=orgpc)
                 promoted_box = box.constbox()
                 self.metainterp.replace_box(box, promoted_box)
+        heapcache.nullity_now_known(box)
         return value
 
     @arguments("box", "label", "orgpc")
diff --git a/rpython/jit/metainterp/test/test_heapcache.py 
b/rpython/jit/metainterp/test/test_heapcache.py
--- a/rpython/jit/metainterp/test/test_heapcache.py
+++ b/rpython/jit/metainterp/test/test_heapcache.py
@@ -69,6 +69,19 @@
         assert not h.is_class_known(1)
         assert not h.is_class_known(2)
 
+    def test_known_nullity(self):
+        h = HeapCache()
+        assert not h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+        h.nullity_now_known(1)
+        assert h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+
+        h.reset()
+        assert not h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+
+
     def test_nonstandard_virtualizable(self):
         h = HeapCache()
         assert not h.is_nonstandard_virtualizable(1)
diff --git a/rpython/jit/metainterp/test/test_tracingopts.py 
b/rpython/jit/metainterp/test/test_tracingopts.py
--- a/rpython/jit/metainterp/test/test_tracingopts.py
+++ b/rpython/jit/metainterp/test/test_tracingopts.py
@@ -107,6 +107,28 @@
         assert res == -7 * 2
         self.check_operations_history(getfield_gc=1)
 
+    def test_heap_caching_nonnull(self):
+        class A:
+            def __init__(self, x=None):
+                self.next = x
+        a0 = A()
+        a1 = A()
+        a2 = A(a1)
+        def fn(n):
+            if n > 0:
+                a = a1
+            else:
+                a = a2
+            if a.next:
+                a = A(a.next)
+                result = a.next is not None
+                a0.next = a
+                return result
+            return False
+        res = self.interp_operations(fn, [-7])
+        assert res == True
+        self.check_operations_history(guard_nonnull=1)
+
     def test_heap_caching_while_tracing_invalidation(self):
         class A:
             pass
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -725,10 +725,15 @@
     result_w = []
     #
     if not we_are_translated():   # fast path before translation
-        for gcref in roots:       # 'roots' is all objects in this case
-            w_obj = callback(gcref)
-            if w_obj is not None:
-                result_w.append(w_obj)
+        seen = set()
+        while roots:
+            gcref = roots.pop()
+            if gcref not in seen:
+                seen.add(gcref)
+                w_obj = callback(gcref)
+                if w_obj is not None:
+                    result_w.append(w_obj)
+                roots.extend(get_rpy_referents(gcref))
         return result_w
     #
     pending = roots[:]
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
@@ -2,6 +2,7 @@
 from rpython.rlib.rvmprof.rvmprof import _get_vmprof, VMProfError
 from rpython.rlib.rvmprof.rvmprof import vmprof_execute_code, MAX_FUNC_NAME
 from rpython.rlib.rvmprof.rvmprof import _was_registered
+from rpython.rlib.rvmprof.cintf import VMProfPlatformUnsupported
 
 #
 # See README.txt.
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
@@ -1,6 +1,7 @@
 import py
 import sys
 from rpython.tool.udir import udir
+from rpython.tool.version import rpythonroot
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.rtyper.tool import rffi_platform as platform
@@ -16,7 +17,7 @@
                                         " x86-64 CPUs for now")
 
 
-    ROOT = py.path.local(__file__).join('..')
+    ROOT = py.path.local(rpythonroot).join('rpython', 'rlib', 'rvmprof')
     SRC = ROOT.join('src')
 
 
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -196,6 +196,11 @@
     (including 'self' if applicable).
     """
     def decorate(func):
+        try:
+            _get_vmprof()
+        except cintf.VMProfPlatformUnsupported:
+            return func
+
         if hasattr(func, 'im_self'):
             assert func.im_self is None
             func = func.im_func
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
@@ -8,7 +8,10 @@
 
     class MyCode:
         pass
-    rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    try:
+        rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    except rvmprof.VMProfPlatformUnsupported:
+        pass
 
     @rvmprof.vmprof_execute_code("xcode1", lambda code, num: code)
     def main(code, num):
@@ -29,7 +32,10 @@
 
     class MyCode:
         pass
-    rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    try:
+        rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    except rvmprof.VMProfPlatformUnsupported:
+        pass
 
     class A:
         pass
@@ -54,7 +60,10 @@
 
     class MyCode:
         pass
-    rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    try:
+        rvmprof.register_code_object_class(MyCode, lambda code: 'some code')
+    except rvmprof.VMProfPlatformUnsupported, e:
+        py.test.skip(str(e))
 
     @rvmprof.vmprof_execute_code("xcode1", lambda code, num: code)
     def main(code, num):
@@ -79,7 +88,10 @@
         pass
     def get_name(code):
         return 'py:code:52:x'
-    rvmprof.register_code_object_class(MyCode, get_name)
+    try:
+        rvmprof.register_code_object_class(MyCode, get_name)
+    except rvmprof.VMProfPlatformUnsupported, e:
+        py.test.skip(str(e))
 
     @rvmprof.vmprof_execute_code("xcode1", lambda code, num: code)
     def main(code, num):
diff --git a/rpython/rlib/rvmprof/test/test_ztranslation.py 
b/rpython/rlib/rvmprof/test/test_ztranslation.py
--- a/rpython/rlib/rvmprof/test/test_ztranslation.py
+++ b/rpython/rlib/rvmprof/test/test_ztranslation.py
@@ -1,4 +1,4 @@
-import time, os
+import time, os, sys, py
 from rpython.tool.udir import udir
 from rpython.rlib import rvmprof
 from rpython.translator.c.test.test_genc import compile
@@ -14,7 +14,10 @@
 
 
 def setup_module(mod):
-    rvmprof.register_code_object_class(MyCode, MyCode.get_name)
+    try:
+        rvmprof.register_code_object_class(MyCode, MyCode.get_name)
+    except rvmprof.VMProfPlatformUnsupported, e:
+        py.test.skip(str(e))
 
 
 @rvmprof.vmprof_execute_code("interp", lambda code: code)
@@ -52,7 +55,9 @@
     return main
 
 def test_interpreted():
-    main()
+    # takes forever if the Python process is already big...
+    import subprocess
+    subprocess.check_call([sys.executable, __file__])
 
 def test_compiled():
     fn = compile(main, [], gcpolicy="minimark")
@@ -60,3 +65,8 @@
         os.unlink(PROF_FILE)
     fn()
     assert os.path.exists(PROF_FILE)
+
+if __name__ == '__main__':
+    setup_module(None)
+    res = main()
+    assert res == 0
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to