Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit