Author: Armin Rigo <[email protected]>
Branch: vmprof-newstack
Changeset: r81785:00d3221560e3
Date: 2016-01-15 11:15 +0100
http://bitbucket.org/pypy/pypy/changeset/00d3221560e3/
Log: Use a thread-local. Kill a lot of code no longer needed.
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
@@ -5,6 +5,7 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rtyper.tool import rffi_platform as platform
+from rpython.rlib import rthread
from rpython.jit.backend import detect_cpu
@@ -70,76 +71,33 @@
def _freeze_(self):
return True
-def token2lltype(tok):
- if tok == 'i':
- return lltype.Signed
- if tok == 'r':
- return llmemory.GCREF
- raise NotImplementedError(repr(tok))
-def token2ctype(tok):
- if tok == 'i':
- return 'long'
- elif tok == 'r':
- return 'void*'
- elif tok == 'f':
- return 'double'
- else:
- raise NotImplementedError(repr(tok))
+# --- copy a few declarations from src/vmprof_stack.h ---
-def make_c_trampoline_function(name, func, token, restok):
- cont_name = 'rpyvmprof_f_%s_%s' % (name, token)
- tramp_name = 'rpyvmprof_t_%s_%s' % (name, token)
+VMPROF_CODE_TAG = 1
- func.c_name = cont_name
- func._dont_inline_ = True
+VMPROFSTACK = lltype.ForwardReference()
+PVMPROFSTACK = lltype.Ptr(VMPROFSTACK)
+VMPROFSTACK.become(rffi.CStruct("vmprof_stack_s",
+ ('next', PVMPROFSTACK),
+ ('value', lltype.Signed),
+ ('kind', lltype.Signed)))
+# ----------
- assert detect_cpu.autodetect().startswith(detect_cpu.MODEL_X86_64), (
- "rvmprof only supports x86-64 CPUs for now")
- llargs = ", ".join(["%s arg%d" % (token2ctype(x), i) for i, x in
- enumerate(token)])
- type = token2ctype(restok)
- target = udir.join('module_cache')
- target.ensure(dir=1)
- argnames = ", ".join(["arg%d" % i for i in range(len(token))])
- vmprof_stack_h = SRC.join("vmprof_stack.h").read()
- target = target.join('trampoline_%s_%s.vmprof.c' % (name, token))
- target.write("""
-#include "src/precommondefs.h"
-#include "vmprof_stack.h"
+vmprof_tl_stack = rthread.ThreadLocalField(PVMPROFSTACK, "vmprof_tl_stack")
+do_use_eci = rffi.llexternal_use_eci(
+ ExternalCompilationInfo(includes=['vmprof_stack.h'],
+ include_dirs = [SRC]))
-extern vmprof_stack* vmprof_global_stack;
+def enter_code(unique_id):
+ do_use_eci()
+ s = lltype.malloc(VMPROFSTACK, flavor='raw')
+ s.c_next = vmprof_tl_stack.get_or_make_raw()
+ s.c_value = unique_id
+ s.c_kind = VMPROF_CODE_TAG
+ vmprof_tl_stack.setraw(s)
+ return s
-%(type)s %(cont_name)s(%(llargs)s);
-
-%(type)s %(tramp_name)s(%(llargs)s, long unique_id)
-{
- %(type)s result;
- struct vmprof_stack node;
-
- node.value = unique_id;
- node.kind = VMPROF_CODE_TAG;
- node.next = vmprof_global_stack;
- vmprof_global_stack = &node;
- result = %(cont_name)s(%(argnames)s);
- vmprof_global_stack = node.next;
- return result;
-}
-""" % locals())
- header = 'RPY_EXTERN %s %s(%s);\n' % (
- token2ctype(restok), tramp_name,
- ', '.join([token2ctype(tok) for tok in token] + ['long']))
-
- eci = ExternalCompilationInfo(
- post_include_bits = [header],
- separate_module_files = [str(target)],
- )
- eci = eci.merge(global_eci)
- ARGS = [token2lltype(tok) for tok in token] + [lltype.Signed]
- return rffi.llexternal(
- tramp_name, ARGS,
- token2lltype(restok),
- compilation_info=eci,
- _nowrapper=True, sandboxsafe=True,
- random_effects_on_gcobjs=True)
+def leave_code(s):
+ vmprof_tl_stack.setraw(s.c_next)
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
@@ -141,12 +141,7 @@
'get_code_fn(*args)' is called to extract the code object from the
arguments given to the decorated function.
- The original function can return None, an integer, or an instance.
- In the latter case (only), 'result_class' must be set.
-
- NOTE: for now, this assumes that the decorated functions only takes
- instances or plain integer arguments, and at most 5 of them
- (including 'self' if applicable).
+ 'result_class' is ignored (backward compatibility).
"""
def decorate(func):
try:
@@ -154,53 +149,19 @@
except cintf.VMProfPlatformUnsupported:
return func
- if hasattr(func, 'im_self'):
- assert func.im_self is None
- func = func.im_func
-
- def lower(*args):
- if len(args) == 0:
- return (), ""
- ll_args, token = lower(*args[1:])
- ll_arg = args[0]
- if isinstance(ll_arg, int):
- tok = "i"
- else:
- tok = "r"
- ll_arg = cast_instance_to_gcref(ll_arg)
- return (ll_arg,) + ll_args, tok + token
-
- @specialize.memo()
- def get_ll_trampoline(token):
- """ Used by the trampoline-version only
- """
- if result_class is None:
- restok = "i"
- else:
- restok = "r"
- return cintf.make_c_trampoline_function(name, func, token, restok)
-
def decorated_function(*args):
- # go through the asm trampoline ONLY if we are translated but not
- # being JITted.
- #
- # If we are not translated, we obviously don't want to go through
- # the trampoline because there is no C function it can call.
- #
# If we are being JITted, we want to skip the trampoline, else the
# JIT cannot see through it.
- #
- if we_are_translated() and not jit.we_are_jitted():
+ if not jit.we_are_jitted():
unique_id = get_code_fn(*args)._vmprof_unique_id
- ll_args, token = lower(*args)
- ll_trampoline = get_ll_trampoline(token)
- ll_result = ll_trampoline(*ll_args + (unique_id,))
+ x = cintf.enter_code(unique_id)
+ try:
+ return func(*args)
+ finally:
+ cintf.leave_code(x)
else:
return func(*args)
- if result_class is not None:
- return cast_base_ptr_to_instance(result_class, ll_result)
- else:
- return ll_result
+
decorated_function.__name__ = func.__name__ + '_rvmprof'
return decorated_function
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,4 +8,3 @@
RPY_EXTERN int vmprof_stack_append(void*, long);
RPY_EXTERN long vmprof_stack_pop(void*);
RPY_EXTERN void vmprof_stack_free(void*);
-RPY_EXTERN void* vmprof_address_of_global_stack(void);
\ No newline at end of file
diff --git a/rpython/rlib/rvmprof/src/vmprof_main.h
b/rpython/rlib/rvmprof/src/vmprof_main.h
--- a/rpython/rlib/rvmprof/src/vmprof_main.h
+++ b/rpython/rlib/rvmprof/src/vmprof_main.h
@@ -48,13 +48,6 @@
-RPY_EXTERN vmprof_stack* vmprof_global_stack;
-
-RPY_EXTERN void *vmprof_address_of_global_stack(void)
-{
- return (void*)&vmprof_global_stack;
-}
-
RPY_EXTERN
char *vmprof_init(int fd, double interval, char *interp_name)
{
@@ -115,8 +108,6 @@
#define VERSION_THREAD_ID '\x01'
#define VERSION_TAG '\x02'
-vmprof_stack* vmprof_global_stack = NULL;
-
struct prof_stacktrace_s {
char padding[sizeof(long) - 1];
char marker;
@@ -135,9 +126,16 @@
* *************************************************************
*/
+#include "src/threadlocal.h"
+
+static vmprof_stack_t *get_vmprof_stack(void)
+{
+ return RPY_THREADLOCALREF_GET(vmprof_tl_stack);
+}
+
static int get_stack_trace(intptr_t *result, int max_depth, intptr_t pc,
ucontext_t *ucontext)
{
- struct vmprof_stack* stack = vmprof_global_stack;
+ vmprof_stack_t* stack = get_vmprof_stack();
int n = 0;
intptr_t addr = 0;
int bottom_jitted = 0;
diff --git a/rpython/rlib/rvmprof/src/vmprof_stack.h
b/rpython/rlib/rvmprof/src/vmprof_stack.h
--- a/rpython/rlib/rvmprof/src/vmprof_stack.h
+++ b/rpython/rlib/rvmprof/src/vmprof_stack.h
@@ -1,7 +1,7 @@
#include <unistd.h>
-#define VMPROF_CODE_TAG 1
+#define VMPROF_CODE_TAG 1 /* <- also in cintf.py */
#define VMPROF_BLACKHOLE_TAG 2
#define VMPROF_JITTED_TAG 3
#define VMPROF_JITTING_TAG 4
@@ -9,11 +9,11 @@
#define VMPROF_ASSEMBLER_TAG 6
// whatever we want here
-typedef struct vmprof_stack {
- struct vmprof_stack* next;
+typedef struct vmprof_stack_s {
+ struct vmprof_stack_s* next;
intptr_t value;
intptr_t kind;
-} vmprof_stack;
+} vmprof_stack_t;
// the kind is WORD so we consume exactly 3 WORDs and we don't have
// to worry too much. There is a potential for squeezing it with bit
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit