Author: Armin Rigo <ar...@tunes.org>
Branch: py3k-faulthandler
Changeset: r87373:7ac3dadd629a
Date: 2016-09-25 19:30 +0200
http://bitbucket.org/pypy/pypy/changeset/7ac3dadd629a/

Log:    Change the API in rvmprof to support more directly what we need, in
        a way that is also more testable

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
@@ -37,8 +37,3 @@
 
 def disable():
     _get_vmprof().disable()
-
-@specialize.arg(0)
-def enum_all_code_objs(CodeClass, callback, arg):
-    assert _was_registered(CodeClass)
-    CodeClass._vmprof_enum_all_code_objs(callback, arg)
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
@@ -156,7 +156,7 @@
     vmprof_tl_stack.setraw(x)
 
 #
-# faulthandler support
+# rvmprof.traceback support
 
 def get_rvmprof_stack():
     return vmprof_tl_stack.get_or_make_raw()
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
@@ -116,25 +116,6 @@
         # the types of code objects
         prev = self._gather_all_code_objs
         self._gather_all_code_objs = gather_all_code_objs
-        #
-        # For special usages: the faulthandler pypy module uses this.
-        # It must not allocate anything.
-        @staticmethod
-        @rgc.no_collect
-        def enum_all_code_objs(callback, arg):
-            all_code_wrefs = CodeClass._vmprof_weak_list.get_all_handles()
-            i = len(all_code_wrefs) - 1
-            while i >= 0:
-                code = all_code_wrefs[i]()
-                i -= 1
-                if code is not None:
-                    uid = code._vmprof_unique_id
-                    if uid != 0:
-                        res = callback(code, uid, arg)
-                        if res != 0:
-                            return res
-            return 0
-        CodeClass._vmprof_enum_all_code_objs = enum_all_code_objs
 
     @jit.dont_look_inside
     def enable(self, fileno, interval):
diff --git a/rpython/rlib/rvmprof/test/test_traceback.py 
b/rpython/rlib/rvmprof/test/test_traceback.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/test/test_traceback.py
@@ -0,0 +1,31 @@
+from rpython.rlib import rvmprof
+from rpython.rlib.rvmprof.traceback import traceback
+
+
+def test_direct():
+    class MyCode:
+        pass
+    def get_name(mycode):
+        raise NotImplementedError
+    rvmprof.register_code_object_class(MyCode, get_name)
+    #
+    @rvmprof.vmprof_execute_code("mycode", lambda code, level: code,
+                                 _hack_update_stack_untranslated=True)
+    def mainloop(code, level):
+        if level > 0:
+            mainloop(code, level - 1)
+        else:
+            traceback(MyCode, my_callback, 42)
+    #
+    seen = []
+    def my_callback(depth, code, arg):
+        seen.append((depth, code, arg))
+        return 0
+    #
+    code1 = MyCode()
+    rvmprof.register_code(code1, "foo")
+    mainloop(code1, 2)
+    #
+    assert seen == [(0, code1, 42),
+                    (1, code1, 42),
+                    (2, code1, 42)]
diff --git a/rpython/rlib/rvmprof/traceback.py 
b/rpython/rlib/rvmprof/traceback.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/traceback.py
@@ -0,0 +1,38 @@
+"""
+Semi-public interface to gather and print a raw traceback, e.g.
+from the faulthandler module.
+"""
+
+from rpython.rlib.rvmprof import cintf
+from rpython.rlib.objectmodel import specialize
+
+
+@specialize.arg(0, 1)
+def traceback(CodeClass, callback, arg):
+    """For each frame, invoke 'callback(depth, code_obj, arg)'.
+    'code_obj' is either a CodeClass, or None if we fail to determine
+    what it should be (shouldn't occur, but you never know).  If it
+    returns a non-null integer, stop and return that.  Otherwise,
+    continue.  If all callbacks return 0, this returns 0.
+    """
+    s = cintf.get_rvmprof_stack()
+    depth = 0
+    while s:
+        if s.c_kind == cintf.VMPROF_CODE_TAG:
+            code_id = s.c_value
+            found_code = None
+            if code_id != 0:
+                all_code_wrefs = CodeClass._vmprof_weak_list.get_all_handles()
+                i = len(all_code_wrefs) - 1
+                while i >= 0:
+                    code = all_code_wrefs[i]()
+                    if code is not None and code._vmprof_unique_id == code_id:
+                        found_code = code
+                        break
+                    i -= 1
+            result = callback(depth, found_code, arg)
+            if result != 0:
+                return result
+            depth += 1
+        s = s.c_next
+    return 0
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to