PageRenderTime 31ms CodeModel.GetById 15ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

/js/src/vprof/vprof.h

http://github.com/zpao/v8monkey
C Header | 308 lines | 162 code | 44 blank | 102 comment | 27 complexity | 7414f0d2afd1d4c47ce2a58ea27c5dfb MD5 | raw file
  1/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
  2/* ***** BEGIN LICENSE BLOCK *****
  3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4 *
  5 * The contents of this file are subject to the Mozilla Public License Version
  6 * 1.1 (the "License"); you may not use this file except in compliance with
  7 * the License. You may obtain a copy of the License at
  8 * http://www.mozilla.org/MPL/
  9 *
 10 * Software distributed under the License is distributed on an "AS IS" basis,
 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 12 * for the specific language governing rights and limitations under the
 13 * License.
 14 *
 15 * The Original Code is Value-Profiling Utility.
 16 *
 17 * The Initial Developer of the Original Code is
 18 * Intel Corporation.
 19 * Portions created by the Initial Developer are Copyright (C) 2008
 20 * the Initial Developer. All Rights Reserved.
 21 *
 22 * Contributor(s):
 23 *   Mohammad R. Haghighat [mohammad.r.haghighat@intel.com] 
 24 *
 25 * Alternatively, the contents of this file may be used under the terms of
 26 * either the GNU General Public License Version 2 or later (the "GPL"), or
 27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 28 * in which case the provisions of the GPL or the LGPL are applicable instead
 29 * of those above. If you wish to allow use of your version of this file only
 30 * under the terms of either the GPL or the LGPL, and not to allow others to
 31 * use your version of this file under the terms of the MPL, indicate your
 32 * decision by deleting the provisions above and replace them with the notice
 33 * and other provisions required by the GPL or the LGPL. If you do not delete
 34 * the provisions above, a recipient may use your version of this file under
 35 * the terms of any one of the MPL, the GPL or the LGPL.
 36 *
 37 * ***** END LICENSE BLOCK ***** */
 38
 39//
 40//  Here are a few examples of using the value-profiling utility:
 41//
 42//  _vprof (e);
 43//    at the end of program execution, you'll get a dump of the source location of this probe,
 44//    its min, max, average, the total sum of all instances of e, and the total number of times this probe was called. 
 45//
 46//  _vprof (x > 0); 
 47//    shows how many times and what percentage of the cases x was > 0, 
 48//    that is the probablitiy that x > 0.
 49// 
 50// _vprof (n % 2 == 0); 
 51//    shows how many times n was an even number 
 52//    as well as th probablitiy of n being an even number. 
 53// 
 54// _hprof (n, 4, 1000, 5000, 5001, 10000); 
 55//    gives you the histogram of n over the given 4 bucket boundaries:
 56//        # cases <  1000 
 57//        # cases >= 1000 and < 5000
 58//        # cases >= 5000 and < 5001
 59//        # cases >= 5001 and < 10000
 60//        # cases >= 10000  
 61// 
 62// _nvprof ("event name", value);   
 63//    all instances with the same name are merged
 64//    so, you can call _vprof with the same event name at difference places
 65// 
 66// _vprof (e, myProbe);  
 67//    value profile e and call myProbe (void* vprofID) at the profiling point.
 68//    inside the probe, the client has the predefined variables:
 69//    _VAL, _COUNT, _SUM, _MIN, _MAX, and the general purpose registers
 70//    _IVAR1, ..., IVAR4      general integer registrs
 71//    _I64VAR1, ..., I64VAR4  general integer64 registrs    
 72//    _DVAR1, ..., _DVAR4     general double registers
 73//    _GENPTR a generic pointer that can be used by the client 
 74//    the number of registers can be changed in vprof.h
 75//
 76
 77#ifndef __VPROF__
 78#define __VPROF__
 79//
 80// If the application for which you want to use vprof is threaded, THREADED must be defined as 1, otherwise define it as 0
 81//
 82// If your application is not threaded, define THREAD_SAFE 0,
 83// 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
 84//
 85#define THREADED 0
 86#define THREAD_SAFE 0
 87
 88#include "VMPI.h"
 89
 90// Note, this is not supported in configurations with more than one AvmCore running
 91// in the same process.
 92
 93// portable align macro
 94#if defined(_MSC_VER)
 95	#define vprof_align8(t) __declspec(align(8)) t
 96#elif defined(__GNUC__)
 97	#define vprof_align8(t) t __attribute__ ((aligned (8)))
 98#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 99	#define vprof_align8(t) t __attribute__ ((aligned (8)))
100#elif defined(VMCFG_SYMBIAN)
101	#define vprof_align8(t) t __attribute__ ((aligned (8)))
102#endif
103
104#ifdef __cplusplus
105extern "C" {
106#endif
107
108int initValueProfile(void** id, char* file, int line, ...);
109int profileValue(void* id, int64_t value);
110int initHistProfile(void** id, char* file, int line, int nbins, ...);
111int histValue(void* id, int64_t value);
112uint64_t readTimestampCounter();
113
114#ifdef __cplusplus
115}
116#endif 
117
118//#define DOPROF
119
120#ifndef DOPROF
121#define _nvprof(e,v)
122#ifndef VMCFG_SYMBIAN
123#define _vprof(v,...)
124#define _hprof(v,n,...)
125#define _nhprof(e,v,n,...)
126#define _ntprof_begin(e)
127#define _ntprof_end(e)
128#define _jvprof_init(id,...)
129#define _jnvprof_init(id,e,...)
130#define _jhprof_init(id,n,...)
131#define _jnhprof_init(id,e,n,...)
132#define _jvprof(id,v)
133#define _jhprof(id,v)
134#endif // ! VMCFG_SYMBIAN
135#else
136
137// Historical/compatibility note:
138// The macros below were originally written using conditional expressions, not if/else.  The original author
139// said that this was done to allow _vprof and _nvprof to be used in an expression context, but the old code
140// had already wrapped the macro bodies in { }, so it is not clear how this could have worked.  At present,
141// the profiling macros must appear in a statement context only.
142 
143#define _vprof(v,...) \
144do { \
145    static void* id = 0; \
146    if (id == 0) \
147        initValueProfile(&id, __FILE__, __LINE__, ##__VA_ARGS__, NULL); \
148    profileValue(id, (int64_t) (v)); \
149} while (0)
150
151#define _nvprof(e,v) \
152do { \
153    static void* id = 0; \
154    if (id == 0) \
155        initValueProfile(&id, (char*) (e), -1, NULL); \
156    profileValue(id, (int64_t) (v)); \
157} while (0)
158
159#define _hprof(v,n,...) \
160do { \
161    static void* id = 0; \
162    if (id == 0) \
163        initHistProfile(&id, __FILE__, __LINE__, (int) (n), ##__VA_ARGS__); \
164    histValue(id, (int64_t) (v)); \
165} while (0)
166
167#define _nhprof(e,v,n,...) \
168do { \
169    static void* id = 0; \
170    if (id == 0) \
171        initHistProfile(&id, (char*) (e), -1, (int) (n), ##__VA_ARGS__); \
172    histValue(id, (int64_t) (v)); \
173} while (0)
174
175// Profile execution time between _ntprof_begin(e) and _ntprof_end(e).
176// The tag 'e' must match at the beginning and end of the region to
177// be timed.  Regions may be nested or overlap arbitrarily, as it is
178// the tag alone that defines the begin/end correspondence.
179
180#define _ntprof_begin(e) \
181do { \
182    static void* id = 0; \
183    if (id == 0) \
184        initValueProfile(&id, (char*)(e), -1, NULL); \
185    ((entry_t)id)->i64var[0] = readTimestampCounter(); \
186} while (0)
187
188// Assume 2.6 Ghz CPU
189#define TICKS_PER_USEC 2600
190
191#define _ntprof_end(e) \
192do { \
193    static void* id = 0; \
194    uint64_t stop = readTimestampCounter(); \
195    if (id == 0) \
196        initValueProfile(&id, (char*)(e), -1, NULL); \
197    uint64_t start = ((entry_t)id)->i64var[0]; \
198    uint64_t usecs = (stop - start) / TICKS_PER_USEC; \
199    profileValue(id, usecs); \
200} while (0)
201
202// These macros separate the creation of a profile record from its later usage.
203// They are intended for profiling JIT-generated code.  Once created, the JIT can
204// bind a pointer to the profile record into the generated code, which can then
205// record profile events during execution.
206
207#define _jvprof_init(id,...) \
208    if (*(id) == 0) \
209        initValueProfile((id), __FILE__, __LINE__, ##__VA_ARGS__, NULL)
210
211#define _jnvprof_init(id,e,...) \
212    if (*(id) == 0) \
213        initValueProfile((id), (char*) (e), -1, ##__VA_ARGS__, NULL)
214
215#define _jhprof_init(id,n,...) \
216    if (*(id) == 0) \
217        initHistProfile((id), __FILE__, __LINE__, (int) (n), ##__VA_ARGS__)
218
219#define _jnhprof_init(id,e,n,...) \
220    if (*(id) == 0) \
221        initHistProfile((id), (char*) (e), -1, (int) (n), ##__VA_ARGS__)
222
223// Calls to the _jvprof and _jhprof macros must be wrapped in a non-inline
224// function in order to be invoked from JIT-compiled code.
225
226#define _jvprof(id,v) \
227    profileValue((id), (int64_t) (v))
228
229#define _jhprof(id,v) \
230    histValue((id), (int64_t) (v))
231
232#endif
233
234#define NUM_EVARS 4
235
236enum {
237    LOCK_IS_FREE = 0, 
238    LOCK_IS_TAKEN = 1
239};
240
241extern
242#ifdef __cplusplus
243"C" 
244#endif
245long _InterlockedCompareExchange (
246   long volatile * Destination,
247   long Exchange,
248   long Comperand
249);
250
251typedef struct hist hist;
252
253typedef struct hist {
254    int nbins;
255    int64_t* lb;
256    int64_t* count;
257} *hist_t;
258
259typedef struct entry entry;
260
261typedef struct entry {
262    long lock;
263    char* file;
264    int line;
265    int64_t value;
266    int64_t count;
267    int64_t sum;
268    int64_t min;
269    int64_t max;
270    void (*func)(void*);
271    hist* h;
272
273    entry* next;
274
275    // exposed to the clients
276    void* genptr;
277    int ivar[NUM_EVARS];
278    vprof_align8(int64_t) i64var[NUM_EVARS];
279    vprof_align8(double) dvar[NUM_EVARS];
280    //
281
282    char pad[128]; // avoid false sharing
283} *entry_t;
284
285#define _VAL ((entry_t)vprofID)->value
286#define _COUNT ((entry_t)vprofID)->count
287#define _SUM ((entry_t)vprofID)->sum
288#define _MIN ((entry_t)vprofID)->min
289#define _MAX ((entry_t)vprofID)->max
290
291#define _GENPTR ((entry_t)vprofID)->genptr
292
293#define _IVAR0 ((entry_t)vprofID)->ivar[0]
294#define _IVAR1 ((entry_t)vprofID)->ivar[1]
295#define _IVAR2 ((entry_t)vprofID)->ivar[2]
296#define _IVAR3 ((entry_t)vprofID)->ivar[3]
297
298#define _I64VAR0 ((entry_t)vprofID)->i64var[0]
299#define _I64VAR1 ((entry_t)vprofID)->i64var[1]
300#define _I64VAR2 ((entry_t)vprofID)->i64var[2]
301#define _I64VAR3 ((entry_t)vprofID)->i64var[3]
302
303#define _DVAR0 ((entry_t)vprofID)->dvar[0]
304#define _DVAR1 ((entry_t)vprofID)->dvar[1]
305#define _DVAR2 ((entry_t)vprofID)->dvar[2]
306#define _DVAR3 ((entry_t)vprofID)->dvar[3]
307
308#endif /* __VPROF__ */