js/src/devtools/vprof/vprof.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/devtools/vprof/vprof.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,275 @@
     1.4 +/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +//
    1.10 +//  Here are a few examples of using the value-profiling utility:
    1.11 +//
    1.12 +//  _vprof (e);
    1.13 +//    at the end of program execution, you'll get a dump of the source location of this probe,
    1.14 +//    its min, max, average, the total sum of all instances of e, and the total number of times this probe was called.
    1.15 +//
    1.16 +//  _vprof (x > 0);
    1.17 +//    shows how many times and what percentage of the cases x was > 0,
    1.18 +//    that is the probablitiy that x > 0.
    1.19 +//
    1.20 +// _vprof (n % 2 == 0);
    1.21 +//    shows how many times n was an even number
    1.22 +//    as well as th probablitiy of n being an even number.
    1.23 +//
    1.24 +// _hprof (n, 4, 1000, 5000, 5001, 10000);
    1.25 +//    gives you the histogram of n over the given 4 bucket boundaries:
    1.26 +//        # cases <  1000
    1.27 +//        # cases >= 1000 and < 5000
    1.28 +//        # cases >= 5000 and < 5001
    1.29 +//        # cases >= 5001 and < 10000
    1.30 +//        # cases >= 10000
    1.31 +//
    1.32 +// _nvprof ("event name", value);
    1.33 +//    all instances with the same name are merged
    1.34 +//    so, you can call _vprof with the same event name at difference places
    1.35 +//
    1.36 +// _vprof (e, myProbe);
    1.37 +//    value profile e and call myProbe (void* vprofID) at the profiling point.
    1.38 +//    inside the probe, the client has the predefined variables:
    1.39 +//    _VAL, _COUNT, _SUM, _MIN, _MAX, and the general purpose registers
    1.40 +//    _IVAR1, ..., IVAR4      general integer registrs
    1.41 +//    _I64VAR1, ..., I64VAR4  general integer64 registrs
    1.42 +//    _DVAR1, ..., _DVAR4     general double registers
    1.43 +//    _GENPTR a generic pointer that can be used by the client
    1.44 +//    the number of registers can be changed in vprof.h
    1.45 +//
    1.46 +
    1.47 +#ifndef devtools_vprof_vprof_h
    1.48 +#define devtools_vprof_vprof_h
    1.49 +//
    1.50 +// If the application for which you want to use vprof is threaded, THREADED must be defined as 1, otherwise define it as 0
    1.51 +//
    1.52 +// If your application is not threaded, define THREAD_SAFE 0,
    1.53 +// otherwise, you have the option of setting THREAD_SAFE to 1 which results in exact counts or to 0 which results in a much more efficient but non-exact counts
    1.54 +//
    1.55 +#define THREADED 0
    1.56 +#define THREAD_SAFE 0
    1.57 +
    1.58 +#include "VMPI.h"
    1.59 +
    1.60 +// Note, this is not supported in configurations with more than one AvmCore running
    1.61 +// in the same process.
    1.62 +
    1.63 +// portable align macro
    1.64 +#if defined(_MSC_VER)
    1.65 +	#define vprof_align8(t) __declspec(align(8)) t
    1.66 +#elif defined(__GNUC__)
    1.67 +	#define vprof_align8(t) t __attribute__ ((aligned (8)))
    1.68 +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
    1.69 +	#define vprof_align8(t) t __attribute__ ((aligned (8)))
    1.70 +#elif defined(VMCFG_SYMBIAN)
    1.71 +	#define vprof_align8(t) t __attribute__ ((aligned (8)))
    1.72 +#endif
    1.73 +
    1.74 +#ifdef __cplusplus
    1.75 +extern "C" {
    1.76 +#endif
    1.77 +
    1.78 +int initValueProfile(void** id, char* file, int line, ...);
    1.79 +int profileValue(void* id, int64_t value);
    1.80 +int initHistProfile(void** id, char* file, int line, int nbins, ...);
    1.81 +int histValue(void* id, int64_t value);
    1.82 +uint64_t readTimestampCounter();
    1.83 +
    1.84 +#ifdef __cplusplus
    1.85 +}
    1.86 +#endif
    1.87 +
    1.88 +//#define DOPROF
    1.89 +
    1.90 +#ifndef DOPROF
    1.91 +#define _nvprof(e,v)
    1.92 +#ifndef VMCFG_SYMBIAN
    1.93 +#define _vprof(v,...)
    1.94 +#define _hprof(v,n,...)
    1.95 +#define _nhprof(e,v,n,...)
    1.96 +#define _ntprof_begin(e)
    1.97 +#define _ntprof_end(e)
    1.98 +#define _jvprof_init(id,...)
    1.99 +#define _jnvprof_init(id,e,...)
   1.100 +#define _jhprof_init(id,n,...)
   1.101 +#define _jnhprof_init(id,e,n,...)
   1.102 +#define _jvprof(id,v)
   1.103 +#define _jhprof(id,v)
   1.104 +#endif // ! VMCFG_SYMBIAN
   1.105 +#else
   1.106 +
   1.107 +// Historical/compatibility note:
   1.108 +// The macros below were originally written using conditional expressions, not if/else.  The original author
   1.109 +// said that this was done to allow _vprof and _nvprof to be used in an expression context, but the old code
   1.110 +// had already wrapped the macro bodies in { }, so it is not clear how this could have worked.  At present,
   1.111 +// the profiling macros must appear in a statement context only.
   1.112 +
   1.113 +#define _vprof(v,...) \
   1.114 +do { \
   1.115 +    static void* id = 0; \
   1.116 +    if (id == 0) \
   1.117 +        initValueProfile(&id, __FILE__, __LINE__, ##__VA_ARGS__, NULL); \
   1.118 +    profileValue(id, (int64_t) (v)); \
   1.119 +} while (0)
   1.120 +
   1.121 +#define _nvprof(e,v) \
   1.122 +do { \
   1.123 +    static void* id = 0; \
   1.124 +    if (id == 0) \
   1.125 +        initValueProfile(&id, (char*) (e), -1, NULL); \
   1.126 +    profileValue(id, (int64_t) (v)); \
   1.127 +} while (0)
   1.128 +
   1.129 +#define _hprof(v,n,...) \
   1.130 +do { \
   1.131 +    static void* id = 0; \
   1.132 +    if (id == 0) \
   1.133 +        initHistProfile(&id, __FILE__, __LINE__, (int) (n), ##__VA_ARGS__); \
   1.134 +    histValue(id, (int64_t) (v)); \
   1.135 +} while (0)
   1.136 +
   1.137 +#define _nhprof(e,v,n,...) \
   1.138 +do { \
   1.139 +    static void* id = 0; \
   1.140 +    if (id == 0) \
   1.141 +        initHistProfile(&id, (char*) (e), -1, (int) (n), ##__VA_ARGS__); \
   1.142 +    histValue(id, (int64_t) (v)); \
   1.143 +} while (0)
   1.144 +
   1.145 +// Profile execution time between _ntprof_begin(e) and _ntprof_end(e).
   1.146 +// The tag 'e' must match at the beginning and end of the region to
   1.147 +// be timed.  Regions may be nested or overlap arbitrarily, as it is
   1.148 +// the tag alone that defines the begin/end correspondence.
   1.149 +
   1.150 +#define _ntprof_begin(e) \
   1.151 +do { \
   1.152 +    static void* id = 0; \
   1.153 +    if (id == 0) \
   1.154 +        initValueProfile(&id, (char*)(e), -1, NULL); \
   1.155 +    ((entry_t)id)->i64var[0] = readTimestampCounter(); \
   1.156 +} while (0)
   1.157 +
   1.158 +// Assume 2.6 Ghz CPU
   1.159 +#define TICKS_PER_USEC 2600
   1.160 +
   1.161 +#define _ntprof_end(e) \
   1.162 +do { \
   1.163 +    static void* id = 0; \
   1.164 +    uint64_t stop = readTimestampCounter(); \
   1.165 +    if (id == 0) \
   1.166 +        initValueProfile(&id, (char*)(e), -1, NULL); \
   1.167 +    uint64_t start = ((entry_t)id)->i64var[0]; \
   1.168 +    uint64_t usecs = (stop - start) / TICKS_PER_USEC; \
   1.169 +    profileValue(id, usecs); \
   1.170 +} while (0)
   1.171 +
   1.172 +// These macros separate the creation of a profile record from its later usage.
   1.173 +// They are intended for profiling JIT-generated code.  Once created, the JIT can
   1.174 +// bind a pointer to the profile record into the generated code, which can then
   1.175 +// record profile events during execution.
   1.176 +
   1.177 +#define _jvprof_init(id,...) \
   1.178 +    if (*(id) == 0) \
   1.179 +        initValueProfile((id), __FILE__, __LINE__, ##__VA_ARGS__, NULL)
   1.180 +
   1.181 +#define _jnvprof_init(id,e,...) \
   1.182 +    if (*(id) == 0) \
   1.183 +        initValueProfile((id), (char*) (e), -1, ##__VA_ARGS__, NULL)
   1.184 +
   1.185 +#define _jhprof_init(id,n,...) \
   1.186 +    if (*(id) == 0) \
   1.187 +        initHistProfile((id), __FILE__, __LINE__, (int) (n), ##__VA_ARGS__)
   1.188 +
   1.189 +#define _jnhprof_init(id,e,n,...) \
   1.190 +    if (*(id) == 0) \
   1.191 +        initHistProfile((id), (char*) (e), -1, (int) (n), ##__VA_ARGS__)
   1.192 +
   1.193 +// Calls to the _jvprof and _jhprof macros must be wrapped in a non-inline
   1.194 +// function in order to be invoked from JIT-compiled code.
   1.195 +
   1.196 +#define _jvprof(id,v) \
   1.197 +    profileValue((id), (int64_t) (v))
   1.198 +
   1.199 +#define _jhprof(id,v) \
   1.200 +    histValue((id), (int64_t) (v))
   1.201 +
   1.202 +#endif
   1.203 +
   1.204 +#define NUM_EVARS 4
   1.205 +
   1.206 +enum {
   1.207 +    LOCK_IS_FREE = 0,
   1.208 +    LOCK_IS_TAKEN = 1
   1.209 +};
   1.210 +
   1.211 +extern
   1.212 +#ifdef __cplusplus
   1.213 +"C"
   1.214 +#endif
   1.215 +long _InterlockedCompareExchange (
   1.216 +   long volatile * Destination,
   1.217 +   long Exchange,
   1.218 +   long Comperand
   1.219 +);
   1.220 +
   1.221 +typedef struct hist hist;
   1.222 +
   1.223 +typedef struct hist {
   1.224 +    int nbins;
   1.225 +    int64_t* lb;
   1.226 +    int64_t* count;
   1.227 +} *hist_t;
   1.228 +
   1.229 +typedef struct entry entry;
   1.230 +
   1.231 +typedef struct entry {
   1.232 +    long lock;
   1.233 +    char* file;
   1.234 +    int line;
   1.235 +    int64_t value;
   1.236 +    int64_t count;
   1.237 +    int64_t sum;
   1.238 +    int64_t min;
   1.239 +    int64_t max;
   1.240 +    void (*func)(void*);
   1.241 +    hist* h;
   1.242 +
   1.243 +    entry* next;
   1.244 +
   1.245 +    // exposed to the clients
   1.246 +    void* genptr;
   1.247 +    int ivar[NUM_EVARS];
   1.248 +    vprof_align8(int64_t) i64var[NUM_EVARS];
   1.249 +    vprof_align8(double) dvar[NUM_EVARS];
   1.250 +    //
   1.251 +
   1.252 +    char pad[128]; // avoid false sharing
   1.253 +} *entry_t;
   1.254 +
   1.255 +#define _VAL ((entry_t)vprofID)->value
   1.256 +#define _COUNT ((entry_t)vprofID)->count
   1.257 +#define _SUM ((entry_t)vprofID)->sum
   1.258 +#define _MIN ((entry_t)vprofID)->min
   1.259 +#define _MAX ((entry_t)vprofID)->max
   1.260 +
   1.261 +#define _GENPTR ((entry_t)vprofID)->genptr
   1.262 +
   1.263 +#define _IVAR0 ((entry_t)vprofID)->ivar[0]
   1.264 +#define _IVAR1 ((entry_t)vprofID)->ivar[1]
   1.265 +#define _IVAR2 ((entry_t)vprofID)->ivar[2]
   1.266 +#define _IVAR3 ((entry_t)vprofID)->ivar[3]
   1.267 +
   1.268 +#define _I64VAR0 ((entry_t)vprofID)->i64var[0]
   1.269 +#define _I64VAR1 ((entry_t)vprofID)->i64var[1]
   1.270 +#define _I64VAR2 ((entry_t)vprofID)->i64var[2]
   1.271 +#define _I64VAR3 ((entry_t)vprofID)->i64var[3]
   1.272 +
   1.273 +#define _DVAR0 ((entry_t)vprofID)->dvar[0]
   1.274 +#define _DVAR1 ((entry_t)vprofID)->dvar[1]
   1.275 +#define _DVAR2 ((entry_t)vprofID)->dvar[2]
   1.276 +#define _DVAR3 ((entry_t)vprofID)->dvar[3]
   1.277 +
   1.278 +#endif /* devtools_vprof_vprof_h */

mercurial