[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