[pypy-commit] pypy py3k-faulthandler: in-progress

arigo pypy.commits at gmail.com
Mon Sep 26 14:18:28 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3k-faulthandler
Changeset: r87396:80e8de7e078d
Date: 2016-09-26 20:17 +0200
http://bitbucket.org/pypy/pypy/changeset/80e8de7e078d/

Log:	in-progress

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
@@ -56,6 +56,11 @@
                                             [rffi.INT], lltype.Void,
                                             compilation_info=eci,
                                             _nowrapper=True)
+    vmprof_get_traceback = rffi.llexternal("vmprof_get_traceback",
+                                  [PVMPROFSTACK, lltype.Signed,
+                                   rffi.SIGNEDP, lltype.Signed],
+                                  lltype.Signed, compilation_info=eci,
+                                  _nowrapper=True)
 
     return CInterface(locals())
 
@@ -156,7 +161,7 @@
     vmprof_tl_stack.setraw(x)
 
 #
-# rvmprof.traceback support
+# traceback support
 
 def get_rvmprof_stack():
     return vmprof_tl_stack.get_or_make_raw()
diff --git a/rpython/rlib/rvmprof/src/rvmprof.h b/rpython/rlib/rvmprof/src/rvmprof.h
--- a/rpython/rlib/rvmprof/src/rvmprof.h
+++ b/rpython/rlib/rvmprof/src/rvmprof.h
@@ -8,3 +8,6 @@
 RPY_EXTERN int vmprof_stack_append(void*, long);
 RPY_EXTERN long vmprof_stack_pop(void*);
 RPY_EXTERN void vmprof_stack_free(void*);
+RPY_EXTERN intptr_t vmprof_get_traceback(void *, intptr_t, intptr_t*, intptr_t);
+
+#define RVMPROF_TRACEBACK_ESTIMATE_N(num_entries)  (2 * (num_entries) + 4)
diff --git a/rpython/rlib/rvmprof/src/vmprof_common.h b/rpython/rlib/rvmprof/src/vmprof_common.h
--- a/rpython/rlib/rvmprof/src/vmprof_common.h
+++ b/rpython/rlib/rvmprof/src/vmprof_common.h
@@ -128,3 +128,14 @@
     return 0;
 }
 #endif
+
+RPY_EXTERN
+intptr_t vmprof_get_traceback(void *stack, intptr_t pc,
+                              intptr_t *result_p, intptr_t result_length)
+{
+    int n;
+    if (stack == NULL)
+        stack = get_vmprof_stack();
+    n = get_stack_trace(stack, result_p, result_length - 2, pc);
+    return (intptr_t)n;
+}
diff --git a/rpython/rlib/rvmprof/test/test_traceback.py b/rpython/rlib/rvmprof/test/test_traceback.py
--- a/rpython/rlib/rvmprof/test/test_traceback.py
+++ b/rpython/rlib/rvmprof/test/test_traceback.py
@@ -1,7 +1,8 @@
 import re
-from rpython.rlib import rvmprof
-from rpython.rlib.rvmprof.traceback import traceback
+from rpython.rlib import rvmprof, jit
+from rpython.rlib.rvmprof import traceback
 from rpython.translator.interactive import Translation
+from rpython.rtyper.lltypesystem import lltype
 
 
 def test_direct():
@@ -17,20 +18,21 @@
         if level > 0:
             mainloop(code, level - 1)
         else:
-            traceback(MyCode, my_callback, 42)
+            p, length = traceback.traceback(20)
+            traceback.walk_traceback(MyCode, my_callback, 42, p, length)
+            lltype.free(p, flavor='raw')
     #
     seen = []
-    def my_callback(depth, code, arg):
-        seen.append((depth, code, arg))
-        return 0
+    def my_callback(code, loc, arg):
+        seen.append((code, loc, arg))
     #
     code1 = MyCode()
     rvmprof.register_code(code1, "foo")
     mainloop(code1, 2)
     #
-    assert seen == [(0, code1, 42),
-                    (1, code1, 42),
-                    (2, code1, 42)]
+    assert seen == [(code1, traceback.LOC_INTERPRETED, 42),
+                    (code1, traceback.LOC_INTERPRETED, 42),
+                    (code1, traceback.LOC_INTERPRETED, 42)]
 
 def test_compiled():
     class MyCode:
@@ -44,10 +46,12 @@
         if level > 0:
             mainloop(code, level - 1)
         else:
-            traceback(MyCode, my_callback, 42)
+            p, length = traceback.traceback(20)
+            traceback.walk_traceback(MyCode, my_callback, 42, p, length)
+            lltype.free(p, flavor='raw')
 
-    def my_callback(depth, code, arg):
-        print depth, code, arg
+    def my_callback(code, loc, arg):
+        print code, loc, arg
         return 0
 
     def f(argv):
@@ -59,7 +63,49 @@
     t = Translation(f, None, gc="boehm")
     t.compile_c()
     stdout = t.driver.cbuilder.cmdexec('')
-    r = re.compile("(\d+) [<]MyCode object at 0x([0-9a-f]+)[>] 42\n")
+    r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] 0 42\n")
+    got = r.findall(stdout)
+    assert got == [got[0]] * 3
+
+def test_jitted():
+    class MyCode:
+        pass
+    def get_name(mycode):
+        raise NotImplementedError
+    rvmprof.register_code_object_class(MyCode, get_name)
+
+    jitdriver = jit.JitDriver(greens=[], reds='auto')
+
+    @rvmprof.vmprof_execute_code("mycode", lambda code, level, total_i: code)
+    def mainloop(code, level, total_i):
+        i = 20
+        while i > 0:
+            jitdriver.jit_merge_point()
+            i -= 1
+            if level > 0:
+                mainloop(code, level - 1, total_i + i)
+        if level == 0 and total_i == 0:
+            p, length = traceback.traceback(20)
+            traceback.walk_traceback(MyCode, my_callback, 42, p, length)
+            lltype.free(p, flavor='raw')
+
+    def my_callback(code, loc, arg):
+        print code, loc, arg
+        return 0
+
+    def f(argv):
+        jit.set_param(jitdriver, "inlining", 0)
+        code1 = MyCode()
+        rvmprof.register_code(code1, "foo")
+        mainloop(code1, 2, 0)
+        return 0
+
+    t = Translation(f, None, gc="boehm")
+    t.rtype()
+    t.driver.pyjitpl_lltype()
+    t.compile_c()
+    stdout = t.driver.cbuilder.cmdexec('')
+    r = re.compile("[<]MyCode object at 0x([0-9a-f]+)[>] (\d) 42\n")
     got = r.findall(stdout)
     addr = got[0][1]
-    assert got == [("0", addr), ("1", addr), ("2", addr)]
+    assert got == XXX
diff --git a/rpython/rlib/rvmprof/traceback.py b/rpython/rlib/rvmprof/traceback.py
--- a/rpython/rlib/rvmprof/traceback.py
+++ b/rpython/rlib/rvmprof/traceback.py
@@ -3,36 +3,62 @@
 from the faulthandler module.
 """
 
-from rpython.rlib.rvmprof import cintf
+from rpython.rlib.rvmprof import cintf, rvmprof
 from rpython.rlib.objectmodel import specialize
+from rpython.rtyper.lltypesystem import lltype, rffi
+
+
+def traceback(estimate_number_of_entries):
+    """Build and return a vmprof-like traceback, as a pair (array_p,
+    array_length).  The caller must free array_p.  Not for signal handlers:
+    for these, call vmprof_get_traceback() from C code.
+    """
+    _cintf = rvmprof._get_vmprof().cintf
+    size = estimate_number_of_entries * 2 + 4
+    stack = cintf.get_rvmprof_stack()
+    array_p = lltype.malloc(rffi.SIGNEDP.TO, size, flavor='raw')
+    array_length = _cintf.vmprof_get_traceback(stack, 0, array_p, size)
+    return (array_p, array_length)
+
+
+LOC_INTERPRETED    = 0
+LOC_JITTED         = 1
+LOC_JITTED_INLINED = 2
 
 
 @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.
+def _traceback_one(CodeClass, callback, arg, code_id, loc):
+    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
+    callback(found_code, loc, arg)
+
+ at specialize.arg(0, 1)
+def walk_traceback(CodeClass, callback, arg, array_p, array_length):
+    """Invoke 'callback(code_obj, loc, arg)' for every traceback entry.
+    'code_obj' may be None if it can't be determined.  'loc' is one
+    of the LOC_xxx constants.
     """
-    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
+    i = 0
+    while i < array_length - 1:
+        tag = array_p[i]
+        tagged_value = array_p[i + 1]
+        if tag == rvmprof.VMPROF_CODE_TAG:
+            loc = LOC_INTERPRETED
+            _traceback_one(CodeClass, callback, arg, tagged_value, loc)
+        elif tag == rvmprof.VMPROF_JITTED_TAG:
+            if i + 2 >= array_length:  # skip last entry, can't determine if
+                break                  # it's LOC_JITTED_INLINED or LOC_JITTED
+            if array_p[i + 2] == rvmprof.VMPROF_JITTED_TAG:
+                loc = LOC_JITTED_INLINED
+            else:
+                loc = LOC_JITTED
+            _traceback_one(CodeClass, callback, arg, tagged_value, loc)
+        i += 2


More information about the pypy-commit mailing list