Author: Richard Plangger <planri...@gmail.com> Branch: vmprof-native Changeset: r89975:bd9d1a5a539b Date: 2017-02-06 16:20 +0100 http://bitbucket.org/pypy/pypy/changeset/bd9d1a5a539b/
Log: moved more files diff too long, truncating to 2000 out of 115559 lines diff --git a/rpython/rlib/rvmprof/src/_vmprof.h b/rpython/rlib/rvmprof/src/_vmprof.h deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/_vmprof.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include <Python.h> -#include <frameobject.h> - -#ifdef VMPROF_WINDOWS -#include "msiinttypes/inttypes.h" -#include "msiinttypes/stdint.h" -#else -#include <inttypes.h> -#include <stdint.h> -#endif - -/** - * This whole setup is very strange. There was just one C file called - * _vmprof.c which included all *.h files to copy code. Unsure what - * the goal was with this design, but I assume it just 'GREW' - * - * Thus I'm (plan_rich) slowly trying to separate this. *.h files - * should not have complex implementations (all of them currently have them) - */ - - -#define SINGLE_BUF_SIZE (8192 - 2 * sizeof(unsigned int)) - -#define ROUTINE_IS_PYTHON(RIP) ((unsigned long long)RIP & 0x1) == 0 -#define ROUTINE_IS_C(RIP) ((unsigned long long)RIP & 0x1) == 1 - -typedef uint64_t ptr_t; - -/* This returns the address of the code object - as the identifier. The mapping from identifiers to string - representations of the code object is done elsewhere, namely: - - * If the code object dies while vmprof is enabled, - PyCode_Type.tp_dealloc will emit it. (We don't handle nicely - for now the case where several code objects are created and die - at the same memory address.) - - * When _vmprof.disable() is called, then we look around the - process for code objects and emit all the ones that we can - find (which we hope is very close to 100% of them). -*/ -#define CODE_ADDR_TO_UID(co) (((intptr_t)(co))) - -#define CPYTHON_HAS_FRAME_EVALUATION PY_VERSION_HEX >= 0x30600B0 - -PyObject* vmprof_eval(PyFrameObject *f, int throwflag); - -#ifdef VMPROF_UNIX -#define VMP_SUPPORTS_NATIVE_PROFILING -#endif - -#define MARKER_STACKTRACE '\x01' -#define MARKER_VIRTUAL_IP '\x02' -#define MARKER_TRAILER '\x03' -#define MARKER_INTERP_NAME '\x04' /* deprecated */ -#define MARKER_HEADER '\x05' -#define MARKER_TIME_N_ZONE '\x06' -#define MARKER_META '\x07' -#define MARKER_NATIVE_SYMBOLS '\x08' - -#define VERSION_BASE '\x00' -#define VERSION_THREAD_ID '\x01' -#define VERSION_TAG '\x02' -#define VERSION_MEMORY '\x03' -#define VERSION_MODE_AWARE '\x04' -#define VERSION_DURATION '\x05' -#define VERSION_TIMESTAMP '\x06' - -#define PROFILE_MEMORY '\x01' -#define PROFILE_LINES '\x02' -#define PROFILE_NATIVE '\x04' - -int vmp_write_all(const char *buf, size_t bufsize); diff --git a/rpython/rlib/rvmprof/src/compat.c b/rpython/rlib/rvmprof/src/compat.c deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/compat.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "compat.h" - -#include "_vmprof.h" - -#if VMPROF_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> -#endif - -static int _vmp_profile_fileno = -1; - -int vmp_profile_fileno(void) { - return _vmp_profile_fileno; -} -void vmp_set_profile_fileno(int fileno) { - _vmp_profile_fileno = fileno; -} - -#ifndef VMPROF_WINDOWS -int vmp_write_all(const char *buf, size_t bufsize) -{ - ssize_t count; - if (_vmp_profile_fileno == -1) { - return -1; - } - while (bufsize > 0) { - count = write(_vmp_profile_fileno, buf, bufsize); - if (count <= 0) - return -1; /* failed */ - buf += count; - bufsize -= count; - } - return 0; -} -#endif - -int vmp_write_meta(const char * key, const char * value) -{ - char marker = MARKER_META; - long x = (long)strlen(key); - vmp_write_all(&marker, 1); - vmp_write_all((char*)&x, sizeof(long)); - vmp_write_all(key, x); - x = (long)strlen(value); - vmp_write_all((char*)&x, sizeof(long)); - vmp_write_all(value, x); - return 0; -} - -/** - * Write the time and zone now. - */ - -struct timezone_buf { - int64_t tv_sec; - int64_t tv_usec; -}; -#define __SIZE (1+sizeof(struct timezone_buf)+8) - -#ifdef VMPROF_UNIX -int vmp_write_time_now(int marker) { - char buffer[__SIZE]; - struct timezone_buf buf; - - (void)memset(&buffer, 0, __SIZE); - - assert((marker == MARKER_TRAILER || marker == MARKER_TIME_N_ZONE) && \ - "marker must be either a trailer or time_n_zone!"); - - struct timeval tv; - time_t now; - struct tm tm; - - - /* copy over to the struct */ - if (gettimeofday(&tv, NULL) != 0) { - return -1; - } - if (time(&now) == (time_t)-1) { - return -1; - } - if (localtime_r(&now, &tm) == NULL) { - return -1; - } - buf.tv_sec = tv.tv_sec; - buf.tv_usec = tv.tv_usec; - strncpy(((char*)buffer)+__SIZE-8, tm.tm_zone, 8); - - buffer[0] = marker; - (void)memcpy(buffer+1, &buf, sizeof(struct timezone_buf)); - vmp_write_all(buffer, __SIZE); - return 0; -} -#endif - -#ifdef VMPROF_WINDOWS -int vmp_write_time_now(int marker) { - char buffer[__SIZE]; - struct timezone_buf buf; - - /** - * http://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows - */ - - // Note: some broken versions only have 8 trailing zero's, the correct - // epoch has 9 trailing zero's - static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); - - SYSTEMTIME system_time; - FILETIME file_time; - uint64_t time; - - (void)memset(&buffer, 0, __SIZE); - - assert((marker == MARKER_TRAILER || marker == MARKER_TIME_N_ZONE) && \ - "marker must be either a trailer or time_n_zone!"); - - - GetSystemTime( &system_time ); - SystemTimeToFileTime( &system_time, &file_time ); - time = ((uint64_t)file_time.dwLowDateTime ) ; - time += ((uint64_t)file_time.dwHighDateTime) << 32; - - buf.tv_sec = ((time - EPOCH) / 10000000L); - buf.tv_usec = (system_time.wMilliseconds * 1000); - - // time zone not implemented on windows - memset(((char*)buffer)+__SIZE-8, 0, 8); - (void)memcpy(((char*)buffer)+__SIZE-8, "UTC", 3); - - buffer[0] = marker; - (void)memcpy(buffer+1, &buf, sizeof(struct timezone_buf)); - vmp_write_all(buffer, __SIZE); - return 0; -} -#endif -#undef __SIZE diff --git a/rpython/rlib/rvmprof/src/compat.h b/rpython/rlib/rvmprof/src/compat.h deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/compat.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <Python.h> - -#if PY_MAJOR_VERSION >= 3 - #define PyStr_AS_STRING PyBytes_AS_STRING - #define PyStr_GET_SIZE PyBytes_GET_SIZE - #define PyStr_NEW PyUnicode_FromString - #define PyLong_NEW PyLong_FromLong -#else - #define PyStr_AS_STRING PyString_AS_STRING - #define PyStr_GET_SIZE PyString_GET_SIZE - #define PyStr_NEW PyString_FromString - #define PyLong_NEW PyInt_FromLong -#endif - -int vmp_write_all(const char *buf, size_t bufsize); -int vmp_write_time_now(int marker); -int vmp_write_meta(const char * key, const char * value); - -int vmp_profile_fileno(void); -void vmp_set_profile_fileno(int fileno); diff --git a/rpython/rlib/rvmprof/src/machine.c b/rpython/rlib/rvmprof/src/machine.c deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/machine.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "machine.h" - -#include "_vmprof.h" -#include <stdio.h> - -int vmp_machine_bits(void) -{ - return sizeof(void*)*8; -} - -const char * vmp_machine_os_name(void) -{ -#ifdef _WIN32 - #ifdef _WIN64 - return "win64"; - #endif - return "win32"; -#elif __APPLE__ - #include "TargetConditionals.h" - #if TARGET_OS_MAC - return "mac os x"; - #endif -#elif __linux__ - return "linux"; -#else - #error "Unknown compiler" -#endif -} - -#ifdef VMP_SUPPORTS_NATIVE_PROFILING -#include "libudis86/udis86.h" -unsigned int vmp_machine_code_instr_length(char* pc) -{ - struct ud u; - ud_init(&u); - ud_set_input_buffer(&u, (uint8_t*)pc, 12); - ud_set_mode(&u, vmp_machine_bits()); - return ud_decode(&u); -} -#endif diff --git a/rpython/rlib/rvmprof/src/machine.h b/rpython/rlib/rvmprof/src/machine.h deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/machine.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -/** - * What is the usual word size of the processor? 64bit? 32bit? - */ -int vmp_machine_bits(void); - -/** - * Return the human readable name of the operating system. - */ -const char * vmp_machine_os_name(void); - -/** - * How many bytes does the x86 instruction take at pc[0..]. - * - * Returns 0 on failure. - */ -#ifdef VMP_SUPPORTS_NATIVE_PROFILING -unsigned int vmp_machine_code_instr_length(char* pc); -#endif diff --git a/rpython/rlib/rvmprof/src/msiinttypes/changelog.txt b/rpython/rlib/rvmprof/src/msiinttypes/changelog.txt deleted file mode 100755 --- a/rpython/rlib/rvmprof/src/msiinttypes/changelog.txt +++ /dev/null @@ -1,138 +0,0 @@ ------------------------------------------------------------------------- -r26 | 2009-10-02 13:36:47 +0400 | 2 lines - -[Issue 5] Change <stdint.h> to "stdint.h" to let compiler search for it in local directory. - ------------------------------------------------------------------------- -r25 | 2009-09-17 23:46:49 +0400 | 2 lines - -[Issue 4] Fix incorrect int8_t behaviour if compiled with /J flag. - ------------------------------------------------------------------------- -r24 | 2009-05-13 14:53:48 +0400 | 2 lines - -Forgot about #ifdef __cplusplus guard around 'extern "C"', so inclusion to C files has been broken. - ------------------------------------------------------------------------- -r23 | 2009-05-12 01:27:45 +0400 | 3 lines - -[Issue 2] Always wrap <wchar�� with external "C" {}. -It turns out that not only Visual Studio 6 requires this, but also newer versions when compiling for ARM. - ------------------------------------------------------------------------- -r22 | 2009-05-11 22:22:15 +0400 | 3 lines - -[Issue 3] Visual Studio 6 and Embedded Visual C++ 4 doesn't realize that, e.g. char has the same size as __int8 so we give up on __intX for them. -his should close Issue 3 in issue tracker. - ------------------------------------------------------------------------- -r21 | 2008-07-17 09:47:22 +0400 | 4 lines - -Get rid of these compiler warnings when compiling for 32-bit: - warning C4311: 'type cast' : pointer truncation from 'void *' to 'uintptr_t' - warning C4312: 'type cast' : conversion from 'uintptr_t' to 'const void *' of greater size - ------------------------------------------------------------------------- -r20 | 2007-10-09 16:54:27 +0400 | 2 lines - -Better C99 conformance: macros for format specifiers should only be included in C++ implementations if __STDC_FORMAT_MACROS is defined before <inttypes.h> is included. - ------------------------------------------------------------------------- -r19 | 2007-07-04 02:14:40 +0400 | 3 lines - -Explicitly cast to appropriate type INT8_MIN, INT16_MIN, INT32_MIN and INT64_MIN constants. -Due to their unusual definition in Visual Studio headers (-_Ix_MAX-1) they are propagated to int and thus do not have expected type, causing VS6 strict compiler to claim about type inconsistency. - ------------------------------------------------------------------------- -r18 | 2007-06-26 16:53:23 +0400 | 2 lines - -Better handling of (U)INTx_C macros - now they generate constants of exact width. - ------------------------------------------------------------------------- -r17 | 2007-03-29 20:16:14 +0400 | 2 lines - -Fix typo: Miscrosoft -> Microsoft. - ------------------------------------------------------------------------- -r16 | 2007-02-24 17:32:58 +0300 | 4 lines - -Remove <BaseTsd.h> include, as it is not present in Visual Studio 2005 Epxress Edition and required only for INT_PTR and UINT_PTR types. - -'intptr_t' and 'uintptr_t' types now defined explicitly with #ifdef _WIN64. - ------------------------------------------------------------------------- -r15 | 2007-02-11 20:53:05 +0300 | 2 lines - -More correct fix for compilation under VS6. - ------------------------------------------------------------------------- -r14 | 2007-02-11 20:04:32 +0300 | 2 lines - -Bugfix: fix compiling under VS6, when stdint.h enclosed in 'extern "C" {}'. - ------------------------------------------------------------------------- -r13 | 2006-12-13 16:53:11 +0300 | 2 lines - -Make _inline modifier for imaxdiv default option. Use STATIC_IMAXDIV to make it static. - ------------------------------------------------------------------------- -r12 | 2006-12-13 16:42:24 +0300 | 2 lines - -Error message changed: VC6 supported from now. - ------------------------------------------------------------------------- -r11 | 2006-12-13 16:39:33 +0300 | 2 lines - -All (U)INT* types changed to (unsigned) __int*. This should make stdint.h compatible with VC6. - ------------------------------------------------------------------------- -r10 | 2006-12-13 16:20:57 +0300 | 3 lines - -Added INLINE_IMAXDIV define switch. -If INLINE_IMAXDIV is defined imaxdiv() have static modifier. If not - it is _inline. - ------------------------------------------------------------------------- -r9 | 2006-12-13 15:53:52 +0300 | 2 lines - -Error message for non-MSC compiler changed. - ------------------------------------------------------------------------- -r8 | 2006-12-13 12:47:48 +0300 | 2 lines - -Added #ifndef for SIZE_MAX (it is defined in limits.h on MSVSC 8). - ------------------------------------------------------------------------- -r7 | 2006-12-13 01:08:02 +0300 | 2 lines - -License chaged to BSD-derivative. - ------------------------------------------------------------------------- -r6 | 2006-12-13 00:53:20 +0300 | 2 lines - -Added <wchar.h> include to avoid warnings when it is included after stdint.h. - ------------------------------------------------------------------------- -r5 | 2006-12-12 00:58:05 +0300 | 2 lines - -BUGFIX: Definitions of INTPTR_MIN, INTPTR_MAX and UINTPTR_MAX for WIN32 and WIN64 was mixed up. - ------------------------------------------------------------------------- -r4 | 2006-12-12 00:51:55 +0300 | 2 lines - -Rise #error if _MSC_VER is not defined. I.e. compiler other then Microsoft Visual C++ is used. - ------------------------------------------------------------------------- -r3 | 2006-12-11 22:54:14 +0300 | 2 lines - -Added <limits.h> include to stdint.h. - ------------------------------------------------------------------------- -r2 | 2006-12-11 21:39:27 +0300 | 2 lines - -Initial check in. - ------------------------------------------------------------------------- -r1 | 2006-12-11 21:30:23 +0300 | 1 line - -Initial directory structure. ------------------------------------------------------------------------- diff --git a/rpython/rlib/rvmprof/src/msiinttypes/inttypes.h b/rpython/rlib/rvmprof/src/msiinttypes/inttypes.h deleted file mode 100755 --- a/rpython/rlib/rvmprof/src/msiinttypes/inttypes.h +++ /dev/null @@ -1,305 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - - -#endif // _MSC_INTTYPES_H_ ] diff --git a/rpython/rlib/rvmprof/src/msiinttypes/stdint.h b/rpython/rlib/rvmprof/src/msiinttypes/stdint.h deleted file mode 100755 --- a/rpython/rlib/rvmprof/src/msiinttypes/stdint.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include <limits.h> - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include <wchar.h> -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/rpython/rlib/rvmprof/src/rss_darwin.h b/rpython/rlib/rvmprof/src/rss_darwin.h deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/rss_darwin.h +++ /dev/null @@ -1,31 +0,0 @@ -/* On OS X we can get RSS using the Mach API. */ -#include <mach/mach.h> -#include <mach/message.h> -#include <mach/kern_return.h> -#include <mach/task_info.h> - -static mach_port_t mach_task; - -static int setup_rss(void) -{ - mach_task = mach_task_self(); - return 0; -} - -static int teardown_rss(void) -{ - return 0; -} - -static long get_current_proc_rss(void) -{ - mach_msg_type_number_t out_count = MACH_TASK_BASIC_INFO_COUNT; - mach_task_basic_info_data_t taskinfo = { .resident_size = 0 }; - - kern_return_t error = task_info(mach_task, MACH_TASK_BASIC_INFO, (task_info_t)&taskinfo, &out_count); - if (error == KERN_SUCCESS) { - return taskinfo.resident_size / 1024; - } else { - return -1; - } -} diff --git a/rpython/rlib/rvmprof/src/rss_unix.h b/rpython/rlib/rvmprof/src/rss_unix.h deleted file mode 100644 --- a/rpython/rlib/rvmprof/src/rss_unix.h +++ /dev/null @@ -1,36 +0,0 @@ -/* On normal Unices we can get RSS from '/proc/<pid>/status'. */ -static int proc_file = -1; - -static int setup_rss(void) -{ - char buf[128]; - - sprintf(buf, "/proc/%d/status", getpid()); - proc_file = open(buf, O_RDONLY); - return proc_file; -} - -static int teardown_rss(void) { - close(proc_file); - proc_file = -1; - return 0; -} - -static long get_current_proc_rss(void) -{ - char buf[1024]; - int i = 0; - - if (lseek(proc_file, 0, SEEK_SET) == -1) - return -1; - if (read(proc_file, buf, 1024) == -1) - return -1; - while (i < 1020) { - if (strncmp(buf + i, "VmRSS:\t", 7) == 0) { - i += 7; - return atoi(buf + i); - } - i++; - } - return -1; -} diff --git a/rpython/rlib/rvmprof/src/shared/_vmprof.c b/rpython/rlib/rvmprof/src/shared/_vmprof.c new file mode 100644 --- /dev/null +++ b/rpython/rlib/rvmprof/src/shared/_vmprof.c @@ -0,0 +1,413 @@ +/*[clinic input] +module _vmprof +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b443489e38f2be7d]*/ + +#define _GNU_SOURCE 1 + +#include <Python.h> +#include <frameobject.h> +#include <signal.h> + +#include "_vmprof.h" + +static volatile int is_enabled = 0; + +#if VMPROF_UNIX +#include "trampoline.h" +#include "machine.h" +#include "symboltable.h" +#include "vmprof_main.h" +#else +#include "vmprof_main_win32.h" +#endif +#include "stack.h" + +static destructor Original_code_dealloc = 0; +PyObject* (*_default_eval_loop)(PyFrameObject *, int) = 0; + +#ifdef VMPROF_UNIX +#ifdef __clang__ +__attribute__((disable_tail_calls)) +#elif defined(__GNUC__) +__attribute__((optimize("O1"))) +#endif +PY_EVAL_RETURN_T * vmprof_eval(PY_STACK_FRAME_T *f, int throwflag) +{ +#ifdef X86_64 + register PY_STACK_FRAME_T * callee_saved asm("rbx"); +#elif defined(X86_32) + register PY_STACK_FRAME_T * callee_saved asm("edi"); +#else +# error "platform not supported" +#endif + + asm volatile( +#ifdef X86_64 + "movq %1, %0\t\n" +#elif defined(X86_32) + "mov %1, %0\t\n" +#else +# error "platform not supported" +#endif + : "=r" (callee_saved) + : "r" (f) ); + return _default_eval_loop(f, throwflag); +} +#endif + +static int emit_code_object(PyCodeObject *co) +{ + char buf[MAX_FUNC_NAME + 1]; + char *co_name, *co_filename; + int co_firstlineno; + int sz; +#if PY_MAJOR_VERSION >= 3 + co_name = PyUnicode_AsUTF8(co->co_name); + if (co_name == NULL) + return -1; + co_filename = PyUnicode_AsUTF8(co->co_filename); + if (co_filename == NULL) + return -1; +#else + co_name = PyString_AS_STRING(co->co_name); + co_filename = PyString_AS_STRING(co->co_filename); +#endif + co_firstlineno = co->co_firstlineno; + + sz = snprintf(buf, MAX_FUNC_NAME / 2, "py:%s", co_name); + if (sz < 0) sz = 0; + if (sz > MAX_FUNC_NAME / 2) sz = MAX_FUNC_NAME / 2; + snprintf(buf + sz, MAX_FUNC_NAME / 2, ":%d:%s", co_firstlineno, + co_filename); + return vmprof_register_virtual_function(buf, CODE_ADDR_TO_UID(co), 500000); +} + +static int _look_for_code_object(PyObject *o, void *all_codes) +{ + if (PyCode_Check(o) && !PySet_Contains((PyObject *)all_codes, o)) { + Py_ssize_t i; + PyCodeObject *co = (PyCodeObject *)o; + if (emit_code_object(co) < 0) + return -1; + if (PySet_Add((PyObject *)all_codes, o) < 0) + return -1; + + /* as a special case, recursively look for and add code + objects found in the co_consts. The problem is that code + objects are not created as GC-aware in CPython, so we need + to hack like this to hope to find most of them. + */ + i = PyTuple_Size(co->co_consts); + while (i > 0) { + --i; + if (_look_for_code_object(PyTuple_GET_ITEM(co->co_consts, i), + all_codes) < 0) + return -1; + } + } + return 0; +} + +static void emit_all_code_objects(void) +{ + PyObject *gc_module = NULL, *lst = NULL, *all_codes = NULL; + Py_ssize_t i, size; + + gc_module = PyImport_ImportModuleNoBlock("gc"); + if (gc_module == NULL) + goto error; + + lst = PyObject_CallMethod(gc_module, "get_objects", ""); + if (lst == NULL || !PyList_Check(lst)) + goto error; + + all_codes = PySet_New(NULL); + if (all_codes == NULL) + goto error; + + size = PyList_GET_SIZE(lst); + for (i = 0; i < size; i++) { + PyObject *o = PyList_GET_ITEM(lst, i); + if (o->ob_type->tp_traverse && + o->ob_type->tp_traverse(o, _look_for_code_object, (void *)all_codes) + < 0) + goto error; + } + + error: + Py_XDECREF(all_codes); + Py_XDECREF(lst); + Py_XDECREF(gc_module); +} + +static void cpyprof_code_dealloc(PyObject *co) +{ + if (is_enabled) { + emit_code_object((PyCodeObject *)co); + /* xxx error return values are ignored */ + } + Original_code_dealloc(co); +} + +#ifdef VMP_SUPPORTS_NATIVE_PROFILING +static void init_cpyprof(int native) +{ + // skip this if native should not be enabled + if (!native) { + vmp_native_disable(); + return; + } +#if CPYTHON_HAS_FRAME_EVALUATION + PyThreadState *tstate = PyThreadState_GET(); + tstate->interp->eval_frame = vmprof_eval; + _default_eval_loop = _PyEval_EvalFrameDefault; +#else + if (vmp_patch_callee_trampoline(PyEval_EvalFrameEx, + vmprof_eval, (void*)&_default_eval_loop) == 0) { + } else { + fprintf(stderr, "FATAL: could not insert trampline, try with --no-native\n"); + // TODO dump the first few bytes and tell them to create an issue! + exit(-1); + } +#endif + vmp_native_enable(); +} +#endif + +void dump_native_symbols(int fileno) +{ + PyObject * mod = NULL; + + mod = PyImport_ImportModuleNoBlock("vmprof"); + if (mod == NULL) + goto error; + + PyObject_CallMethod(mod, "dump_native_symbols", "(l)", fileno); + +error: + Py_XDECREF(mod); +} + +#ifdef VMP_SUPPORTS_NATIVE_PROFILING +static void disable_cpyprof(void) +{ + vmp_native_disable(); +#if CPYTHON_HAS_FRAME_EVALUATION + PyThreadState *tstate = PyThreadState_GET(); + tstate->interp->eval_frame = _PyEval_EvalFrameDefault; +#else + if (vmp_unpatch_callee_trampoline(PyEval_EvalFrameEx) > 0) { + fprintf(stderr, "FATAL: could not remove trampoline\n"); + exit(-1); + } +#endif + dump_native_symbols(vmp_profile_fileno()); +} +#endif + + +static PyObject *enable_vmprof(PyObject* self, PyObject *args) +{ + int fd; + int memory = 0; + int lines = 0; + int native = 0; + double interval; + char *p_error; + + if (!PyArg_ParseTuple(args, "id|iii", &fd, &interval, &memory, &lines, &native)) { + return NULL; + } + assert(fd >= 0 && "file descripter provided to vmprof must not" \ + " be less then zero."); + + if (is_enabled) { + PyErr_SetString(PyExc_ValueError, "vmprof is already enabled"); + return NULL; + } + + vmp_profile_lines(lines); + +#ifdef VMP_SUPPORTS_NATIVE_PROFILING + init_cpyprof(native); +#endif + + if (!Original_code_dealloc) { + Original_code_dealloc = PyCode_Type.tp_dealloc; + PyCode_Type.tp_dealloc = &cpyprof_code_dealloc; + } + + p_error = vmprof_init(fd, interval, memory, lines, "cpython", native); + if (p_error) { + PyErr_SetString(PyExc_ValueError, p_error); + return NULL; + } + + if (vmprof_enable(memory) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + is_enabled = 1; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +disable_vmprof(PyObject *module, PyObject *noarg) +{ + if (!is_enabled) { + PyErr_SetString(PyExc_ValueError, "vmprof is not enabled"); + return NULL; + } + is_enabled = 0; + vmprof_ignore_signals(1); + emit_all_code_objects(); +#ifdef VMP_SUPPORTS_NATIVE_PROFILING + disable_cpyprof(); +#endif + + if (vmprof_disable() < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + if (PyErr_Occurred()) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +write_all_code_objects(PyObject *module, PyObject *noargs) +{ + if (!is_enabled) { + PyErr_SetString(PyExc_ValueError, "vmprof is not enabled"); + return NULL; + } + emit_all_code_objects(); + if (PyErr_Occurred()) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + + +static PyObject * +sample_stack_now(PyObject *module, PyObject *args) +{ + PyThreadState * tstate = NULL; + PyObject * list; + int i; + int entry_count; + void ** m; + void * routine_ip; + + // stop any signal to occur + vmprof_ignore_signals(1); + + list = PyList_New(0); + if (list == NULL) { + goto error; + } + + tstate = PyGILState_GetThisThreadState(); + m = (void**)malloc(SINGLE_BUF_SIZE); + if (m == NULL) { + PyErr_SetString(PyExc_MemoryError, "could not allocate buffer for stack trace"); + vmprof_ignore_signals(0); + return NULL; + } + entry_count = vmp_walk_and_record_stack(tstate->frame, m, MAX_STACK_DEPTH-1, 0); + + for (i = 0; i < entry_count; i++) { + routine_ip = m[i]; + PyList_Append(list, PyLong_NEW((long)routine_ip)); + } + + free(m); + + Py_INCREF(list); + + vmprof_ignore_signals(0); + return list; +error: + Py_DECREF(list); + Py_INCREF(Py_None); + + vmprof_ignore_signals(0); + return Py_None; +} + +#ifdef VMP_SUPPORTS_NATIVE_PROFILING +static PyObject * +resolve_addr(PyObject *module, PyObject *args) { + long long addr; + PyObject * o_name = NULL; + PyObject * o_lineno = NULL; + PyObject * o_srcfile = NULL; + char name[128]; + int lineno = 0; + char srcfile[256]; + + if (!PyArg_ParseTuple(args, "L", &addr)) { + return NULL; + } + name[0] = '\x00'; + srcfile[0] = '-'; + srcfile[1] = '\x00'; + if (vmp_resolve_addr((void*)addr, name, 128, &lineno, srcfile, 256) != 0) { + goto error; + } + + o_name = PyStr_NEW(name); + if (o_name == NULL) goto error; + o_lineno = PyLong_NEW(lineno); + if (o_lineno == NULL) goto error; + o_srcfile = PyStr_NEW(srcfile); + if (o_srcfile == NULL) goto error; + // + return PyTuple_Pack(3, o_name, o_lineno, o_srcfile); +error: + Py_XDECREF(o_name); + Py_XDECREF(o_lineno); + Py_XDECREF(o_srcfile); + + Py_INCREF(Py_None); + return Py_None; +} +#endif + +static PyMethodDef VMProfMethods[] = { + {"enable", enable_vmprof, METH_VARARGS, "Enable profiling."}, + {"disable", disable_vmprof, METH_NOARGS, "Disable profiling."}, + {"write_all_code_objects", write_all_code_objects, METH_NOARGS, + "Write eagerly all the IDs of code objects"}, + {"sample_stack_now", sample_stack_now, METH_NOARGS, "Sample the stack now"}, +#ifdef VMP_SUPPORTS_NATIVE_PROFILING + {"resolve_addr", resolve_addr, METH_VARARGS, "Return the name of the addr"}, +#endif + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef VmprofModule = { + PyModuleDef_HEAD_INIT, + "_vmprof", + "", // doc + -1, // size + VMProfMethods +}; + +PyMODINIT_FUNC PyInit__vmprof(void) +{ + return PyModule_Create(&VmprofModule); +} +#else +PyMODINIT_FUNC init_vmprof(void) +{ + Py_InitModule("_vmprof", VMProfMethods); +} +#endif diff --git a/rpython/rlib/rvmprof/src/shared/_vmprof.h b/rpython/rlib/rvmprof/src/shared/_vmprof.h new file mode 100644 --- /dev/null +++ b/rpython/rlib/rvmprof/src/shared/_vmprof.h @@ -0,0 +1,47 @@ +#pragma once + +#include "vmprof.h" + +#ifdef VMPROF_WINDOWS +#include "msiinttypes/inttypes.h" +#include "msiinttypes/stdint.h" +#else +#include <inttypes.h> +#include <stdint.h> +#endif + +/** + * This whole setup is very strange. There was just one C file called + * _vmprof.c which included all *.h files to copy code. Unsure what + * the goal was with this design, but I assume it just 'GREW' + * + * Thus I'm (plan_rich) slowly trying to separate this. *.h files + * should not have complex implementations (all of them currently have them) + */ + + +#define SINGLE_BUF_SIZE (8192 - 2 * sizeof(unsigned int)) + +#define ROUTINE_IS_PYTHON(RIP) ((unsigned long long)RIP & 0x1) == 0 +#define ROUTINE_IS_C(RIP) ((unsigned long long)RIP & 0x1) == 1 + +/* This returns the address of the code object + as the identifier. The mapping from identifiers to string + representations of the code object is done elsewhere, namely: + + * If the code object dies while vmprof is enabled, + PyCode_Type.tp_dealloc will emit it. (We don't handle nicely + for now the case where several code objects are created and die + at the same memory address.) + + * When _vmprof.disable() is called, then we look around the + process for code objects and emit all the ones that we can + find (which we hope is very close to 100% of them). +*/ +#define CODE_ADDR_TO_UID(co) (((intptr_t)(co))) + +#define CPYTHON_HAS_FRAME_EVALUATION PY_VERSION_HEX >= 0x30600B0 + +PyObject* vmprof_eval(PyFrameObject *f, int throwflag); + +int vmp_write_all(const char *buf, size_t bufsize); diff --git a/rpython/rlib/rvmprof/src/shared/compat.c b/rpython/rlib/rvmprof/src/shared/compat.c new file mode 100644 --- /dev/null +++ b/rpython/rlib/rvmprof/src/shared/compat.c @@ -0,0 +1,137 @@ +#include "compat.h" + +#include "_vmprof.h" + +#if VMPROF_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#endif + +static int _vmp_profile_fileno = -1; + +int vmp_profile_fileno(void) { + return _vmp_profile_fileno; +} +void vmp_set_profile_fileno(int fileno) { + _vmp_profile_fileno = fileno; +} + +#ifndef VMPROF_WINDOWS +int vmp_write_all(const char *buf, size_t bufsize) +{ + ssize_t count; + if (_vmp_profile_fileno == -1) { + return -1; + } + while (bufsize > 0) { + count = write(_vmp_profile_fileno, buf, bufsize); + if (count <= 0) + return -1; /* failed */ + buf += count; + bufsize -= count; + } + return 0; +} +#endif + +int vmp_write_meta(const char * key, const char * value) +{ + char marker = MARKER_META; + long x = (long)strlen(key); + vmp_write_all(&marker, 1); + vmp_write_all((char*)&x, sizeof(long)); + vmp_write_all(key, x); + x = (long)strlen(value); + vmp_write_all((char*)&x, sizeof(long)); + vmp_write_all(value, x); + return 0; +} + +/** + * Write the time and zone now. + */ + +struct timezone_buf { + int64_t tv_sec; + int64_t tv_usec; +}; +#define __SIZE (1+sizeof(struct timezone_buf)+8) + +#ifdef VMPROF_UNIX +int vmp_write_time_now(int marker) { + char buffer[__SIZE]; + struct timezone_buf buf; + + (void)memset(&buffer, 0, __SIZE); + + assert((marker == MARKER_TRAILER || marker == MARKER_TIME_N_ZONE) && \ + "marker must be either a trailer or time_n_zone!"); + + struct timeval tv; + time_t now; + struct tm tm; + + + /* copy over to the struct */ + if (gettimeofday(&tv, NULL) != 0) { + return -1; + } + if (time(&now) == (time_t)-1) { + return -1; + } + if (localtime_r(&now, &tm) == NULL) { + return -1; + } + buf.tv_sec = tv.tv_sec; + buf.tv_usec = tv.tv_usec; + strncpy(((char*)buffer)+__SIZE-8, tm.tm_zone, 8); + + buffer[0] = marker; + (void)memcpy(buffer+1, &buf, sizeof(struct timezone_buf)); + vmp_write_all(buffer, __SIZE); + return 0; +} +#endif + +#ifdef VMPROF_WINDOWS +int vmp_write_time_now(int marker) { + char buffer[__SIZE]; + struct timezone_buf buf; + + /** + * http://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows + */ + + // Note: some broken versions only have 8 trailing zero's, the correct + // epoch has 9 trailing zero's + static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + (void)memset(&buffer, 0, __SIZE); + + assert((marker == MARKER_TRAILER || marker == MARKER_TIME_N_ZONE) && \ + "marker must be either a trailer or time_n_zone!"); + + + GetSystemTime( &system_time ); + SystemTimeToFileTime( &system_time, &file_time ); + time = ((uint64_t)file_time.dwLowDateTime ) ; + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + buf.tv_sec = ((time - EPOCH) / 10000000L); + buf.tv_usec = (system_time.wMilliseconds * 1000); + + // time zone not implemented on windows + memset(((char*)buffer)+__SIZE-8, 0, 8); + (void)memcpy(((char*)buffer)+__SIZE-8, "UTC", 3); + + buffer[0] = marker; + (void)memcpy(buffer+1, &buf, sizeof(struct timezone_buf)); + vmp_write_all(buffer, __SIZE); + return 0; +} +#endif +#undef __SIZE diff --git a/rpython/rlib/rvmprof/src/shared/compat.h b/rpython/rlib/rvmprof/src/shared/compat.h new file mode 100644 --- /dev/null +++ b/rpython/rlib/rvmprof/src/shared/compat.h @@ -0,0 +1,24 @@ +#pragma once + +#include "vmprof.h" + +#ifndef RPYTHON_VMPROF +# if PY_MAJOR_VERSION >= 3 + #define PyStr_AS_STRING PyBytes_AS_STRING + #define PyStr_GET_SIZE PyBytes_GET_SIZE + #define PyStr_NEW PyUnicode_FromString + #define PyLong_NEW PyLong_FromLong +# else + #define PyStr_AS_STRING PyString_AS_STRING + #define PyStr_GET_SIZE PyString_GET_SIZE + #define PyStr_NEW PyString_FromString + #define PyLong_NEW PyInt_FromLong +# endif +#endif + +int vmp_write_all(const char *buf, size_t bufsize); +int vmp_write_time_now(int marker); +int vmp_write_meta(const char * key, const char * value); + +int vmp_profile_fileno(void); +void vmp_set_profile_fileno(int fileno); diff --git a/rpython/rlib/rvmprof/src/shared/libbacktrace/ChangeLog b/rpython/rlib/rvmprof/src/shared/libbacktrace/ChangeLog new file mode 100644 --- /dev/null +++ b/rpython/rlib/rvmprof/src/shared/libbacktrace/ChangeLog @@ -0,0 +1,602 @@ +2017-01-01 Jakub Jelinek <ja...@redhat.com> + + Update copyright years. + +2016-11-15 Matthias Klose <d...@ubuntu.com> + + * configure: Regenerate. + +2016-09-11 Carlos Liam <car...@aarzee.me> + + * all: Remove meaningless trailing whitespace. + +2016-05-18 Uros Bizjak <ubiz...@gmail.com> + + PR target/71161 + * elf.c (phdr_callback) [__i386__]: Add + __attribute__((__force_align_arg_pointer__)). + +2016-03-02 Maxim Ostapenko <m.ostape...@partner.samsung.com> + + * elf.c (backtrace_initialize): Properly initialize elf_fileline_fn to + avoid possible crash. + (elf_add): Don't set *fileline_fn to elf_nodebug value in case of + missing debug info anymore. + +2016-02-06 John David Anglin <dang...@gcc.gnu.org> + + * mmap.c (MAP_FAILED): Define if not defined. + +2016-01-04 Jakub Jelinek <ja...@redhat.com> + + Update copyright years. + +2015-12-18 Andris Pavenis <andris.pave...@iki.fi> + + * configure.ac: Specify that DJGPP do not have mmap + even when sys/mman.h exists. + * configure: Regenerate + +2015-12-09 John David Anglin <dang...@gcc.gnu.org> + + PR libgfortran/68115 + * configure.ac: Set libbacktrace_cv_sys_sync to no on hppa*-*-hpux*. + * configure: Regenerate. + * elf.c (backtrace_initialize): Cast __sync_bool_compare_and_swap call + to void. + +2015-09-17 Ian Lance Taylor <i...@google.com> + + * posix.c (backtrace_open): Cast second argument of open() to int. + +2015-09-11 Ian Lance Taylor <i...@google.com> + + * Makefile.am (backtrace.lo): Depend on internal.h. + (sort.lo, stest.lo): Add explicit dependencies. + * Makefile.in: Rebuild. + +2015-09-09 Hans-Peter Nilsson <h...@axis.com> + + * backtrace.c: #include <sys/types.h>. + +2015-09-08 Ian Lance Taylor <i...@google.com> + + PR other/67457 + * backtrace.c: #include "internal.h". + (struct backtrace_data): Add can_alloc field. + (unwind): If can_alloc is false, don't try to get file/line + information. + (backtrace_full): Set can_alloc field in bdata. + * alloc.c (backtrace_alloc): Don't call error_callback if it is + NULL. + * mmap.c (backtrace_alloc): Likewise. + * internal.h: Update comments for backtrace_alloc and + backtrace_free. + +2015-09-08 Ian Lance Taylor <i...@google.com> + + PR other/67457 + * mmap.c (backtrace_alloc): Correct test for mmap failure. + +2015-08-31 Ulrich Weigand <ulrich.weig...@de.ibm.com> + + * configure.ac: For spu-*-* targets, set have_fcntl to no. + * configure: Regenerate. + +2015-08-27 Ulrich Weigand <ulrich.weig...@de.ibm.com> + + * configure.ac: Remove [disable-shared] argument to LT_INIT. + Remove setting PIC_FLAG when building as target library. + * configure: Regenerate. + +2015-08-26 Hans-Peter Nilsson <h...@axis.com> + + * configure.ac: Only compile with -fPIC if the target + supports it. + * configure: Regenerate. + +2015-08-24 Ulrich Weigand <ulrich.weig...@de.ibm.com> + + * configure.ac: Set have_mmap to no on spu-*-* targets. + * configure: Regenerate. + +2015-08-13 Ian Lance Taylor <i...@google.com> + + * dwarf.c (read_function_entry): Add vec_inlined parameter. + Change all callers. + +2015-06-11 Martin Sebor <mse...@redhat.com> + + PR sanitizer/65479 + * dwarf.c (struct line): Add new field idx. + (line_compare): Use it. + (add_line): Set it. + (read_line_info): Reset it. + +2015-05-29 Tristan Gingold <ging...@adacore.com> + + * pecoff.c: New file. + * Makefile.am (FORMAT_FILES): Add pecoff.c and dependencies. + * Makefile.in: Regenerate. + * filetype.awk: Detect pecoff. + * configure.ac: Define BACKTRACE_SUPPORTS_DATA on elf platforms. + Add pecoff. + * btest.c (test5): Test enabled only if BACKTRACE_SUPPORTS_DATA is + true. + * backtrace-supported.h.in (BACKTRACE_SUPPORTS_DATA): Define. + * configure: Regenerate. + * pecoff.c: New file. + +2015-05-13 Michael Haubenwallner <michael.haubenwall...@ssi-schaefer.com> + + * Makefile.in: Regenerated with automake-1.11.6. + * aclocal.m4: Likewise. + * configure: Likewise. + +2015-01-24 Matthias Klose <d...@ubuntu.com> + + * configure.ac: Move AM_ENABLE_MULTILIB before AC_PROG_CC. + * configure: Regenerate. + +2015-01-05 Jakub Jelinek <ja...@redhat.com> + + Update copyright years. + +2014-11-21 H.J. Lu <hongjiu...@intel.com> + + PR bootstrap/63784 + * configure: Regenerated. + +2014-11-11 David Malcolm <dmalc...@redhat.com> + + * ChangeLog.jit: New. + +2014-11-11 Francois-Xavier Coudert <fxcoud...@gcc.gnu.org> + + PR target/63610 + * configure: Regenerate. + +2014-10-23 Ian Lance Taylor <i...@google.com> + + * internal.h (backtrace_atomic_load_pointer) [no atomic or sync]: + Fix to return void *. + +2014-05-08 Ian Lance Taylor <i...@google.com> + + * mmap.c (backtrace_free): If freeing a large aligned block of + memory, call munmap rather than holding onto it. + (backtrace_vector_grow): When growing a vector, double the number + of pages requested. When releasing the old version of a grown + vector, pass the correct size to backtrace_free. + +2014-03-07 Ian Lance Taylor <i...@google.com> + + * sort.c (backtrace_qsort): Use middle element as pivot. + +2014-03-06 Ian Lance Taylor <i...@google.com> + + * sort.c: New file. + * stest.c: New file. + * internal.h (backtrace_qsort): Declare. + * dwarf.c (read_abbrevs): Call backtrace_qsort instead of qsort. + (read_line_info, read_function_entry): Likewise. + (read_function_info, build_dwarf_data): Likewise. + * elf.c (elf_initialize_syminfo): Likewise. + * Makefile.am (libbacktrace_la_SOURCES): Add sort.c. + (stest_SOURCES, stest_LDADD): Define. + (check_PROGRAMS): Add stest. + +2014-02-07 Misty De Meo <mi...@brew.sh> + + PR target/58710 + * configure.ac: Use AC_LINK_IFELSE in check for + _Unwind_GetIPInfo. + * configure: Regenerate. + +2014-01-02 Richard Sandiford <rdsandif...@googlemail.com> + + Update copyright years + +2013-12-06 Jakub Jelinek <ja...@redhat.com> + + * elf.c (ET_DYN): Undefine and define again. + (elf_add): Add exe argument, if true and ehdr.e_type is ET_DYN, + return early -1 without closing the descriptor. + (struct phdr_data): Add exe_descriptor. + (phdr_callback): If pd->exe_descriptor is not -1, for very first + call if dlpi_name is NULL just call elf_add with the exe_descriptor, + otherwise backtrace_close the exe_descriptor if not -1. Adjust + call to elf_add. + (backtrace_initialize): Adjust call to elf_add. If it returns + -1, set pd.exe_descriptor to descriptor, otherwise set it to -1. + +2013-12-05 Ian Lance Taylor <i...@google.com> + + * alloc.c (backtrace_vector_finish): Add error_callback and data + parameters. Call backtrace_vector_release. Return address base. + * mmap.c (backtrace_vector_finish): Add error_callback and data + parameters. Return address base. + * dwarf.c (read_function_info): Get new address base from + backtrace_vector_finish. + * internal.h (backtrace_vector_finish): Update declaration. + +2013-11-27 Ian Lance Taylor <i...@google.com> + + * dwarf.c (find_address_ranges): New static function, broken out + of build_address_map. + (build_address_map): Call it. + * btest.c (check): Check for missing filename or function, rather + than crashing. + (f3): Check that enough frames were returned. + +2013-11-19 Jakub Jelinek <ja...@redhat.com> + + * backtrace.h (backtrace_syminfo_callback): Add symsize argument. + * elf.c (elf_syminfo): Pass 0 or sym->size to the callback as + last argument. + * btest.c (struct symdata): Add size field. + (callback_three): Add symsize argument. Copy it to the data->size + field. + (f23): Set symdata.size to 0. + (test5): Likewise. If sizeof (int) > 1, lookup address of + ((uintptr_t) &global) + 1. Verify symdata.val and symdata.size + values. + + * atomic.c: Include sys/types.h. + +2013-11-18 Ian Lance Taylor <i...@google.com> + + * configure.ac: Check for support of __atomic extensions. + * internal.h: Declare or #define atomic functions for use in + backtrace code. + * atomic.c: New file. + * dwarf.c (dwarf_lookup_pc): Use atomic functions. _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit