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