Author: Manuel Jacob <m...@manueljacob.de> Branch: py3k Changeset: r82211:837af91c362b Date: 2016-02-13 15:01 +0100 http://bitbucket.org/pypy/pypy/changeset/837af91c362b/
Log: hg merge default diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -37,13 +37,13 @@ "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "_continuation", "_cffi_backend", - "_csv", "_pypyjson", "_posixsubprocess", # "cppyy", "micronumpy" + "_csv", "_pypyjson", "_vmprof", "_posixsubprocess", # "cppyy", "micronumpy" ]) -if ((sys.platform.startswith('linux') or sys.platform == 'darwin') - and os.uname()[4] == 'x86_64' and sys.maxint > 2**32): +#if ((sys.platform.startswith('linux') or sys.platform == 'darwin') +# and os.uname()[4] == 'x86_64' and sys.maxint > 2**32): # it's not enough that we get x86_64 - working_modules.add('_vmprof') +# working_modules.add('_vmprof') translation_modules = default_modules.copy() translation_modules.update([ diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -313,7 +313,7 @@ return None -class W_InterpIterable(W_Root): +class InterpIterable(object): def __init__(self, space, w_iterable): self.w_iter = space.iter(w_iterable) self.space = space @@ -763,9 +763,13 @@ return self.int_w(self.hash(w_obj)) def len_w(self, w_obj): - """shotcut for space.int_w(space.len(w_obj))""" + """shortcut for space.int_w(space.len(w_obj))""" return self.int_w(self.len(w_obj)) + def contains_w(self, w_container, w_item): + """shortcut for space.is_true(space.contains(w_container, w_item))""" + return self.is_true(self.contains(w_container, w_item)) + def setitem_str(self, w_obj, key, w_value): return self.setitem(w_obj, self.wrap(key), w_value) @@ -868,7 +872,7 @@ return lst_w[:] # make the resulting list resizable def iteriterable(self, w_iterable): - return W_InterpIterable(self, w_iterable) + return InterpIterable(self, w_iterable) def _unpackiterable_unknown_length(self, w_iterator, w_iterable): """Unpack an iterable of unknown length into an interp-level @@ -1229,7 +1233,7 @@ if not isinstance(statement, PyCode): raise TypeError('space.exec_(): expected a string, code or PyCode object') w_key = self.wrap('__builtins__') - if not self.is_true(self.contains(w_globals, w_key)): + if not self.contains_w(w_globals, w_key): self.setitem(w_globals, w_key, self.wrap(self.builtin)) return statement.exec_code(self, w_globals, w_locals) diff --git a/pypy/module/_demo/test/test_import.py b/pypy/module/_demo/test/test_import.py --- a/pypy/module/_demo/test/test_import.py +++ b/pypy/module/_demo/test/test_import.py @@ -12,8 +12,7 @@ w_modules = space.sys.get('modules') assert _demo.Module.demo_events == ['setup'] - assert not space.is_true(space.contains(w_modules, - space.wrap('_demo'))) + assert not space.contains_w(w_modules, space.wrap('_demo')) # first import w_import = space.builtin.get('__import__') diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py --- a/pypy/module/_vmprof/interp_vmprof.py +++ b/pypy/module/_vmprof/interp_vmprof.py @@ -60,7 +60,7 @@ Must be smaller than 1.0 """ w_modules = space.sys.get('modules') - if space.is_true(space.contains(w_modules, space.wrap('_continuation'))): + if space.contains_w(w_modules, space.wrap('_continuation')): space.warn(space.wrap("Using _continuation/greenlet/stacklet together " "with vmprof will crash"), space.w_RuntimeWarning) diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py --- a/pypy/module/cpyext/test/test_dictobject.py +++ b/pypy/module/cpyext/test/test_dictobject.py @@ -150,7 +150,7 @@ def test_dictproxy(self, space, api): w_dict = space.sys.get('modules') w_proxy = api.PyDictProxy_New(w_dict) - assert space.is_true(space.contains(w_proxy, space.wrap('sys'))) + assert space.contains_w(w_proxy, space.wrap('sys')) raises(OperationError, space.setitem, w_proxy, space.wrap('sys'), space.w_None) raises(OperationError, space.delitem, diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py --- a/pypy/module/cpyext/test/test_import.py +++ b/pypy/module/cpyext/test/test_import.py @@ -21,7 +21,7 @@ def test_getmoduledict(self, space, api): testmod = "contextlib" w_pre_dict = api.PyImport_GetModuleDict() - assert not space.is_true(space.contains(w_pre_dict, space.wrap(testmod))) + assert not space.contains_w(w_pre_dict, space.wrap(testmod)) with rffi.scoped_str2charp(testmod) as modname: w_module = api.PyImport_ImportModule(modname) @@ -29,7 +29,7 @@ assert w_module w_dict = api.PyImport_GetModuleDict() - assert space.is_true(space.contains(w_dict, space.wrap(testmod))) + assert space.contains_w(w_dict, space.wrap(testmod)) def test_reload(self, space, api): stat = api.PyImport_Import(space.wrap("stat")) diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -179,7 +179,7 @@ def test_dir(self, space, api): w_dir = api.PyObject_Dir(space.sys) assert space.isinstance_w(w_dir, space.w_list) - assert space.is_true(space.contains(w_dir, space.wrap('modules'))) + assert space.contains_w(w_dir, space.wrap('modules')) class AppTestObject(AppTestCpythonExtensionBase): def setup_class(cls): diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py --- a/pypy/objspace/std/dictmultiobject.py +++ b/pypy/objspace/std/dictmultiobject.py @@ -1339,9 +1339,8 @@ return space.len(self.w_dict) def _all_contained_in(space, w_dictview, w_other): - w_iter = space.iter(w_dictview) - for w_item in space.iteriterable(w_iter): - if not space.is_true(space.contains(w_other, w_item)): + for w_item in space.iteriterable(w_dictview): + if not space.contains_w(w_other, w_item): return space.w_False return space.w_True diff --git a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py --- a/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py +++ b/rpython/jit/backend/llsupport/test/zrpy_vmprof_test.py @@ -3,16 +3,13 @@ from rpython.jit.backend.test.support import CCompiledMixin from rpython.rlib.jit import JitDriver from rpython.tool.udir import udir +from rpython.rlib import rthread from rpython.translator.translator import TranslationContext from rpython.jit.backend.detect_cpu import getcpuclass class CompiledVmprofTest(CCompiledMixin): CPUClass = getcpuclass() - def setup(self): - if self.CPUClass.backend_name != 'x86_64': - py.test.skip("vmprof only supports x86-64 CPUs at the moment") - def _get_TranslationContext(self): t = TranslationContext() t.config.translation.gc = 'incminimark' @@ -62,6 +59,7 @@ tmpfilename = str(udir.join('test_rvmprof')) def f(num): + rthread.get_ident() # register TLOFS_thread_ident code = MyCode("py:x:foo:3") rvmprof.register_code(code, get_name) fd = os.open(tmpfilename, os.O_WRONLY | os.O_CREAT, 0666) 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 @@ -30,11 +30,11 @@ def setup(): + compile_extra = ['-DRPYTHON_LL2CTYPES'] platform.verify_eci(ExternalCompilationInfo( - compile_extra=['-DRPYTHON_LL2CTYPES'], + compile_extra=compile_extra, **eci_kwds)) - eci = global_eci vmprof_init = rffi.llexternal("vmprof_init", [rffi.INT, rffi.DOUBLE, rffi.CCHARP], diff --git a/rpython/rlib/rvmprof/src/rvmprof.c b/rpython/rlib/rvmprof/src/rvmprof.c --- a/rpython/rlib/rvmprof/src/rvmprof.c +++ b/rpython/rlib/rvmprof/src/rvmprof.c @@ -1,23 +1,21 @@ #define _GNU_SOURCE 1 - #ifdef RPYTHON_LL2CTYPES /* only for testing: ll2ctypes sets RPY_EXTERN from the command-line */ -# ifndef RPY_EXTERN -# define RPY_EXTERN RPY_EXPORTED -# endif -# define RPY_EXPORTED extern __attribute__((visibility("default"))) -# define VMPROF_ADDR_OF_TRAMPOLINE(addr) 0 +#ifndef RPY_EXTERN +#define RPY_EXTERN RPY_EXPORTED +#endif +#ifdef _WIN32 +#define RPY_EXPORTED __declspec(dllexport) +#else +#define RPY_EXPORTED extern __attribute__((visibility("default"))) +#endif #else - # include "common_header.h" # include "structdef.h" # include "src/threadlocal.h" # include "rvmprof.h" -/*# ifndef VMPROF_ADDR_OF_TRAMPOLINE -# error "RPython program using rvmprof, but not calling vmprof_execute_code()" -# endif*/ #endif 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 @@ -7,9 +7,6 @@ static long profile_interval_usec = 0; static int opened_profile(char *interp_name); -#define MAX_STACK_DEPTH \ - ((SINGLE_BUF_SIZE - sizeof(struct prof_stacktrace_s)) / sizeof(void *)) - #define MARKER_STACKTRACE '\x01' #define MARKER_VIRTUAL_IP '\x02' #define MARKER_TRAILER '\x03' @@ -20,6 +17,9 @@ #define VERSION_THREAD_ID '\x01' #define VERSION_TAG '\x02' +#define MAX_STACK_DEPTH \ + ((SINGLE_BUF_SIZE - sizeof(struct prof_stacktrace_s)) / sizeof(void *)) + typedef struct prof_stacktrace_s { char padding[sizeof(long) - 1]; char marker; @@ -71,6 +71,43 @@ return _write_all((char*)&header, 5 * sizeof(long) + 4 + namelen); } +/* ************************************************************* + * functions to dump the stack trace + * ************************************************************* + */ + + +static int get_stack_trace(vmprof_stack_t* stack, intptr_t *result, int max_depth, intptr_t pc) +{ + int n = 0; + intptr_t addr = 0; + int bottom_jitted = 0; + // check if the pc is in JIT +#ifdef PYPY_JIT_CODEMAP + if (pypy_find_codemap_at_addr((intptr_t)pc, &addr)) { + // the bottom part is jitted, means we can fill up the first part + // from the JIT + n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); + stack = stack->next; // skip the first item as it contains garbage + } +#endif + while (n < max_depth - 1 && stack) { + if (stack->kind == VMPROF_CODE_TAG) { + result[n] = stack->kind; + result[n + 1] = stack->value; + n += 2; + } +#ifdef PYPY_JIT_CODEMAP + else if (stack->kind == VMPROF_JITTED_TAG) { + pc = ((intptr_t*)(stack->value - sizeof(intptr_t)))[0]; + n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); + } +#endif + stack = stack->next; + } + return n; +} + #ifndef RPYTHON_LL2CTYPES static vmprof_stack_t *get_vmprof_stack(void) { 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 @@ -35,6 +35,7 @@ #include "vmprof_stack.h" #include "vmprof_getpc.h" #include "vmprof_mt.h" +#include "vmprof_get_custom_offset.h" #include "vmprof_common.h" /************************************************************/ @@ -78,46 +79,6 @@ static char atfork_hook_installed = 0; -#include "vmprof_get_custom_offset.h" - -/* ************************************************************* - * functions to dump the stack trace - * ************************************************************* - */ - - -static int get_stack_trace(intptr_t *result, int max_depth, intptr_t pc, ucontext_t *ucontext) -{ - vmprof_stack_t* stack = get_vmprof_stack(); - int n = 0; - intptr_t addr = 0; - int bottom_jitted = 0; - // check if the pc is in JIT -#ifdef PYPY_JIT_CODEMAP - if (pypy_find_codemap_at_addr((intptr_t)pc, &addr)) { - // the bottom part is jitted, means we can fill up the first part - // from the JIT - n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); - stack = stack->next; // skip the first item as it contains garbage - } -#endif - while (n < max_depth - 1 && stack) { - if (stack->kind == VMPROF_CODE_TAG) { - result[n] = stack->kind; - result[n + 1] = stack->value; - n += 2; - } -#ifdef PYPY_JIT_CODEMAP - else if (stack->kind == VMPROF_JITTED_TAG) { - pc = ((intptr_t*)(stack->value - sizeof(intptr_t)))[0]; - n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); - } -#endif - stack = stack->next; - } - return n; -} - static intptr_t get_current_thread_id(void) { /* xxx This function is a hack on two fronts: @@ -194,8 +155,8 @@ struct prof_stacktrace_s *st = (struct prof_stacktrace_s *)p->data; st->marker = MARKER_STACKTRACE; st->count = 1; - depth = get_stack_trace(st->stack, - MAX_STACK_DEPTH-2, GetPC((ucontext_t*)ucontext), ucontext); + depth = get_stack_trace(get_vmprof_stack(), st->stack, + MAX_STACK_DEPTH-2, GetPC((ucontext_t*)ucontext)); st->depth = depth; st->stack[depth++] = get_current_thread_id(); p->data_offset = offsetof(struct prof_stacktrace_s, marker); diff --git a/rpython/rlib/rvmprof/src/vmprof_main_win32.h b/rpython/rlib/rvmprof/src/vmprof_main_win32.h --- a/rpython/rlib/rvmprof/src/vmprof_main_win32.h +++ b/rpython/rlib/rvmprof/src/vmprof_main_win32.h @@ -10,13 +10,30 @@ return 0; } +#if defined(_MSC_VER) +#include <BaseTsd.h> +typedef SSIZE_T ssize_t; +#endif + +#include <assert.h> +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +#include <stddef.h> +#include <sys/stat.h> +#include <fcntl.h> #include "vmprof_stack.h" +#include "vmprof_get_custom_offset.h" #include "vmprof_common.h" #include <tlhelp32.h> // This file has been inspired (but not copied from since the LICENSE // would not allow it) from verysleepy profiler +#define SINGLE_BUF_SIZE 8192 + volatile int thread_started = 0; volatile int enabled = 0; @@ -55,52 +72,75 @@ return 0; } -int vmprof_snapshot_thread(DWORD thread_id, PyThreadState *tstate, prof_stacktrace_s *stack) +int vmprof_snapshot_thread(struct pypy_threadlocal_s *p, prof_stacktrace_s *stack) { - HRESULT result; - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); - int depth; + void *addr; + vmprof_stack_t *cur; + long tid; + HANDLE hThread; + long depth; + DWORD result; + CONTEXT ctx; + +#ifdef RPYTHON_LL2CTYPES + return 0; // not much we can do +#else +#ifndef RPY_TLOFS_thread_ident + return 0; // we can't freeze threads, unsafe +#else + hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, p->thread_ident); if (!hThread) { return -1; } result = SuspendThread(hThread); if(result == 0xffffffff) return -1; // possible, e.g. attached debugger or thread alread suspended - // find the correct thread - depth = read_trace_from_cpy_frame(tstate->frame, stack->stack, - MAX_STACK_DEPTH); + ctx.ContextFlags = CONTEXT_FULL; + if (!GetThreadContext(hThread, &ctx)) + return -1; + depth = get_stack_trace(p->vmprof_tl_stack, + stack->stack, MAX_STACK_DEPTH-2, ctx.Eip); stack->depth = depth; - stack->stack[depth++] = (void*)thread_id; + stack->stack[depth++] = (void*)p->thread_ident; stack->count = 1; stack->marker = MARKER_STACKTRACE; ResumeThread(hThread); return depth; +#endif +#endif } long __stdcall vmprof_mainloop(void *arg) { +#ifndef RPYTHON_LL2CTYPES + struct pypy_threadlocal_s *p; prof_stacktrace_s *stack = (prof_stacktrace_s*)malloc(SINGLE_BUF_SIZE); - HANDLE hThreadSnap = INVALID_HANDLE_VALUE; int depth; - PyThreadState *tstate; while (1) { - Sleep(profile_interval_usec * 1000); + //Sleep(profile_interval_usec * 1000); + Sleep(10); if (!enabled) { continue; } - tstate = PyInterpreterState_Head()->tstate_head; - while (tstate) { - depth = vmprof_snapshot_thread(tstate->thread_id, tstate, stack); - if (depth > 0) { - _write_all((char*)stack + offsetof(prof_stacktrace_s, marker), - depth * sizeof(void *) + - sizeof(struct prof_stacktrace_s) - - offsetof(struct prof_stacktrace_s, marker)); + _RPython_ThreadLocals_Acquire(); + p = _RPython_ThreadLocals_Head(); // the first one is one behind head + p = _RPython_ThreadLocals_Enum(p); + while (p) { + if (p->ready == 42) { + depth = vmprof_snapshot_thread(p, stack); + if (depth > 0) { + _write_all((char*)stack + offsetof(prof_stacktrace_s, marker), + depth * sizeof(void *) + + sizeof(struct prof_stacktrace_s) - + offsetof(struct prof_stacktrace_s, marker)); + } } - tstate = tstate->next; + p = _RPython_ThreadLocals_Enum(p); } + _RPython_ThreadLocals_Release(); } +#endif } RPY_EXTERN 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,11 @@ #ifndef _VMPROF_STACK_H_ #define _VMPROF_STACK_H_ +#ifdef _WIN32 +#define intptr_t long // XXX windows VC++ 2008 lacks stdint.h +#else #include <unistd.h> +#endif #define VMPROF_CODE_TAG 1 /* <- also in cintf.py */ #define VMPROF_BLACKHOLE_TAG 2 diff --git a/rpython/rlib/rvmprof/test/test_ztranslation.py b/rpython/rlib/rvmprof/test/test_ztranslation.py --- a/rpython/rlib/rvmprof/test/test_ztranslation.py +++ b/rpython/rlib/rvmprof/test/test_ztranslation.py @@ -3,11 +3,10 @@ sys.path += ['../../../..'] # for subprocess in test_interpreted import py from rpython.tool.udir import udir -from rpython.rlib import rvmprof +from rpython.rlib import rvmprof, rthread from rpython.translator.c.test.test_genc import compile from rpython.rlib.nonconst import NonConstant - class MyCode: def __init__(self, count): self.count = count @@ -39,6 +38,7 @@ PROF_FILE = str(udir.join('test_ztranslation.prof')) def main(argv=[]): + rthread.get_ident() # force TLOFS_thread_ident if NonConstant(False): # Hack to give os.open() the correct annotation os.open('foo', 1, 1) diff --git a/rpython/translator/c/src/threadlocal.c b/rpython/translator/c/src/threadlocal.c --- a/rpython/translator/c/src/threadlocal.c +++ b/rpython/translator/c/src/threadlocal.c @@ -85,6 +85,11 @@ return prev->next; } +struct pypy_threadlocal_s *_RPython_ThreadLocals_Head(void) +{ + return &linkedlist_head; +} + static void _RPy_ThreadLocals_Init(void *p) { struct pypy_threadlocal_s *tls = (struct pypy_threadlocal_s *)p; diff --git a/rpython/translator/c/src/threadlocal.h b/rpython/translator/c/src/threadlocal.h --- a/rpython/translator/c/src/threadlocal.h +++ b/rpython/translator/c/src/threadlocal.h @@ -27,6 +27,9 @@ RPY_EXTERN struct pypy_threadlocal_s * _RPython_ThreadLocals_Enum(struct pypy_threadlocal_s *prev); +/* will return the head of the list */ +RPY_EXTERN struct pypy_threadlocal_s *_RPython_ThreadLocals_Head(); + #define OP_THREADLOCALREF_ACQUIRE(r) _RPython_ThreadLocals_Acquire() #define OP_THREADLOCALREF_RELEASE(r) _RPython_ThreadLocals_Release() #define OP_THREADLOCALREF_ENUM(p, r) r = _RPython_ThreadLocals_Enum(p) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit