forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVisualEventTracer.h
207 lines (172 loc) · 8.04 KB
/
VisualEventTracer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Visual event tracer, creates a log of events on each thread for visualization */
/**
* The event tracer code is by default disabled in both build and run time.
*
* To enable this code at build time, add --enable-visual-profiling to your
* configure options.
*
* To enable this code at run time, export MOZ_PROFILING_FILE env var with
* a path to the file to write the log to. This is all you need to produce
* the log of all events instrumentation in the mozilla code.
* Check MOZ_EVENT_TRACER_* macros bellow to add your own.
*
* To let the event tracer log only some events to save disk space, export
* MOZ_PROFILING_EVENTS with comma separated list of event names you want
* to record in the log.
*/
#include "prlock.h"
#include "nscore.h"
#include "mozilla/GuardObjects.h"
#ifdef MOZ_VISUAL_EVENT_TRACER
// Bind an object instance, usually |this|, to a name, usually URL or
// host name, the instance deals with for its lifetime. The name string
// is duplicated.
// IMPORTANT: it is up to the caller to pass the correct static_cast
// of the |instance| pointer to all these macros ; otherwise the linking
// of events and objects will not work!
// The name will show in details of the events on the timeline and also
// will allow events filtering by host names, URLs etc.
#define MOZ_EVENT_TRACER_NAME_OBJECT(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eName, instance, name)
// The same as MOZ_EVENT_TRACER_NAME_OBJECT, just simplifies building
// names when it consists of two parts
#define MOZ_EVENT_TRACER_COMPOUND_NAME(instance, name, name2) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eName, instance, name, name2)
// Call the followings with the same |instance| reference as you have
// previously called MOZ_EVENT_TRACER_NAME_OBJECT.
// Let |name| be the name of the event happening, like "resolving",
// "connecting", "loading" etc.
// This will crate a single-point-in-time event marked with an arrow
// on the timeline, this is a way to indicate an event without a duration.
#define MOZ_EVENT_TRACER_MARK(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eShot, instance, name)
// Following macros are used to log events with duration.
// There always has to be complete WAIT,EXEC,DONE or EXEC,DONE
// uninterrupted and non-interferring tuple(s) for an event to be correctly
// shown on the timeline. Each can be called on any thread, the event tape is
// finally displayed on the thread where it has been EXECuted.
// Example of 3 phases usage for "HTTP request channel":
// WAIT: we've just created the channel and called AsyncOpen on it
// EXEC: we've just got first call to OnDataAvailable, so we are actually
// receiving the content after some time like connection establising,
// opening a cache entry, sending the GET request...
// DONE: we've just got OnStopRequest call that indicates the content
// has been completely delivered and the request is now finished
// Indicate an event pending start, on the timeline this will
// start the event's interval tape with a pale color, the time will
// show in details. Usually used when an event is being posted or
// we wait for a lock acquisition.
// WAITING is not mandatory, some events don't have a pending phase.
#define MOZ_EVENT_TRACER_WAIT(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eWait, instance, name)
// Indicate start of an event actual execution, on the timeline this will
// change the event's tape to a deeper color, the time will show in details.
#define MOZ_EVENT_TRACER_EXEC(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eExec, instance, name)
// Indicate the end of an event execution (the event has been done),
// on the timeline this will end the event's tape and show the time in
// event details.
// NOTE: when the event duration is extremely short, like 1ms, it will convert
// to an event w/o a duration - the same as MOZ_EVENT_TRACER_MARK would be used.
#define MOZ_EVENT_TRACER_DONE(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eDone, instance, name)
// The same meaning as the above macros, just for concurent events.
// Concurent event means it can happen for the same instance on more
// then just a single thread, e.g. a service method call, a global lock
// acquisition, enter and release.
#define MOZ_EVENT_TRACER_WAIT_THREADSAFE(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eWait | mozilla::eventtracer::eThreadConcurrent, instance, name)
#define MOZ_EVENT_TRACER_EXEC_THREADSAFE(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eExec | mozilla::eventtracer::eThreadConcurrent, instance, name)
#define MOZ_EVENT_TRACER_DONE_THREASAFE(instance, name) \
mozilla::eventtracer::Mark(mozilla::eventtracer::eDone | mozilla::eventtracer::eThreadConcurrent, instance, name)
#else
// MOZ_VISUAL_EVENT_TRACER disabled
#define MOZ_EVENT_TRACER_NAME_OBJECT(instance, name) (void)0
#define MOZ_EVENT_TRACER_COMPOUND_NAME(instance, name, name2) (void)0
#define MOZ_EVENT_TRACER_MARK(instance, name) (void)0
#define MOZ_EVENT_TRACER_WAIT(instance, name) (void)0
#define MOZ_EVENT_TRACER_EXEC(instance, name) (void)0
#define MOZ_EVENT_TRACER_DONE(instance, name) (void)0
#define MOZ_EVENT_TRACER_WAIT_THREADSAFE(instance, name) (void)0
#define MOZ_EVENT_TRACER_EXEC_THREADSAFE(instance, name) (void)0
#define MOZ_EVENT_TRACER_DONE_THREASAFE(instance, name) (void)0
#endif
namespace mozilla { namespace eventtracer {
// Initialize the event tracer engine, called automatically on XPCOM startup.
void Init();
// Shuts the event tracer engine down and closes the log file, called
// automatically during XPCOM shutdown.
void Shutdown();
enum MarkType {
eNone, // No operation, ignored
eName, // This is used to bind an object instance with a name
eShot, // An event with no duration
eWait, // Start of waiting for execution (lock acquire, post...)
eExec, // Start of the execution it self
eDone, // End of the execution
eLast, // Sentinel
// Flags
// The same object can execute the same event on several threads concurently
eThreadConcurrent = 0x10000
};
// Records an event on the calling thread.
// @param aType
// One of MarkType fields, can be bitwise or'ed with the flags.
// @param aItem
// Reference to the object we want to bind a name to or the event is
// happening on. Can be actually anything, but valid poitners should
// be used.
// @param aText
// Text of the name (for eName) or event's name for others. The string
// is duplicated.
// @param aText2
// Optional second part of the instnace name, or event name.
// Event filtering does apply only to the first part (aText).
void Mark(PRUint32 aType, void * aItem,
const char * aText, const char * aText2 = 0);
// Helper guard object. Use to mark an event in the constructor and a different
// event in the destructor.
//
// Example:
// int class::func()
// {
// AutoEventTracer tracer(this, eventtracer::eExec, eventtracer::eDone, "func");
//
// do_something_taking_a_long_time();
// }
class NS_STACK_CLASS AutoEventTracer
{
public:
AutoEventTracer(void * aInstance,
PRUint32 aTypeOn, // MarkType marked in constructor
PRUint32 aTypeOff, // MarkType marked in destructor
const char * aName,
const char * aName2 = 0
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mInstance(aInstance)
, mName(aName)
, mName2(aName2)
, mTypeOn(aTypeOn)
, mTypeOff(aTypeOff)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
::mozilla::eventtracer::Mark(mTypeOn, mInstance, mName, mName2);
}
~AutoEventTracer()
{
::mozilla::eventtracer::Mark(mTypeOff, mInstance, mName, mName2);
}
private:
void * mInstance;
const char * mName;
const char * mName2;
PRUint32 mTypeOn;
PRUint32 mTypeOff;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} // eventtracer
} // mozilla