OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #ifndef TraceEventDispatcher_h | |
32 #define TraceEventDispatcher_h | |
33 | |
34 #include "platform/TraceEvent.h" | |
35 #include "platform/heap/Handle.h" | |
36 #include "wtf/HashMap.h" | |
37 #include "wtf/Threading.h" | |
38 #include "wtf/ThreadingPrimitives.h" | |
39 #include "wtf/Vector.h" | |
40 #include "wtf/text/StringHash.h" | |
41 #include "wtf/text/WTFString.h" | |
42 | |
43 namespace blink { | |
44 | |
45 class InspectorClient; | |
46 | |
47 class TraceEventDispatcher { | |
48 WTF_MAKE_NONCOPYABLE(TraceEventDispatcher); | |
49 public: | |
50 class TraceEvent { | |
51 public: | |
52 TraceEvent() | |
53 : m_name(0) | |
54 , m_argumentCount(0) | |
55 { | |
56 } | |
57 | |
58 TraceEvent(double timestamp, char phase, const char* name, unsigned long
long id, ThreadIdentifier threadIdentifier, | |
59 int argumentCount, const char* const* argumentNames, const unsigned
char* argumentTypes, const unsigned long long* argumentValues) | |
60 : m_timestamp(timestamp) | |
61 , m_phase(phase) | |
62 , m_name(name) | |
63 , m_id(id) | |
64 , m_threadIdentifier(threadIdentifier) | |
65 , m_argumentCount(argumentCount) | |
66 { | |
67 if (m_argumentCount > MaxArguments) { | |
68 ASSERT_NOT_REACHED(); | |
69 m_argumentCount = MaxArguments; | |
70 } | |
71 for (int i = 0; i < m_argumentCount; ++i) { | |
72 m_argumentNames[i] = argumentNames[i]; | |
73 if (argumentTypes[i] == TRACE_VALUE_TYPE_COPY_STRING) { | |
74 m_stringArguments[i] = reinterpret_cast<const char*>(argumen
tValues[i]); | |
75 m_argumentValues[i].m_string = reinterpret_cast<const char*>
(m_stringArguments[i].characters8()); | |
76 m_argumentTypes[i] = TRACE_VALUE_TYPE_STRING; | |
77 } else { | |
78 m_argumentValues[i].m_int = argumentValues[i]; | |
79 m_argumentTypes[i] = argumentTypes[i]; | |
80 } | |
81 } | |
82 } | |
83 | |
84 double timestamp() const { return m_timestamp; } | |
85 char phase() const { return m_phase; } | |
86 const char* name() const { return m_name; } | |
87 unsigned long long id() const { return m_id; } | |
88 ThreadIdentifier threadIdentifier() const { return m_threadIdentifier; } | |
89 int argumentCount() const { return m_argumentCount; } | |
90 bool isNull() const { return !m_name; } | |
91 | |
92 bool asBool(const char* name) const | |
93 { | |
94 return parameter(name, TRACE_VALUE_TYPE_BOOL).m_bool; | |
95 } | |
96 long long asInt(const char* name) const | |
97 { | |
98 size_t index = findParameter(name); | |
99 if (index == kNotFound || (m_argumentTypes[index] != TRACE_VALUE_TYP
E_INT && m_argumentTypes[index] != TRACE_VALUE_TYPE_UINT)) { | |
100 ASSERT_NOT_REACHED(); | |
101 return 0; | |
102 } | |
103 return reinterpret_cast<const blink::TraceEvent::TraceValueUnion*>(m
_argumentValues + index)->m_int; | |
104 } | |
105 unsigned long long asUInt(const char* name) const | |
106 { | |
107 return asInt(name); | |
108 } | |
109 double asDouble(const char* name) const | |
110 { | |
111 return parameter(name, TRACE_VALUE_TYPE_DOUBLE).m_double; | |
112 } | |
113 const char* asString(const char* name) const | |
114 { | |
115 return parameter(name, TRACE_VALUE_TYPE_STRING).m_string; | |
116 } | |
117 | |
118 private: | |
119 enum { MaxArguments = 2 }; | |
120 | |
121 size_t findParameter(const char*) const; | |
122 const blink::TraceEvent::TraceValueUnion& parameter(const char* name, un
signed char expectedType) const; | |
123 | |
124 double m_timestamp; | |
125 char m_phase; | |
126 const char* m_name; | |
127 unsigned long long m_id; | |
128 ThreadIdentifier m_threadIdentifier; | |
129 int m_argumentCount; | |
130 const char* m_argumentNames[MaxArguments]; | |
131 unsigned char m_argumentTypes[MaxArguments]; | |
132 blink::TraceEvent::TraceValueUnion m_argumentValues[MaxArguments]; | |
133 // These are only used as buffers for TRACE_VALUE_TYPE_COPY_STRING. | |
134 // Consider allocating the entire vector of buffered trace events and th
eir copied arguments out of a special arena | |
135 // to make things more compact. | |
136 String m_stringArguments[MaxArguments]; | |
137 }; | |
138 | |
139 class TraceEventListener : public NoBaseWillBeGarbageCollected<TraceEventLis
tener> { | |
140 public: | |
141 #if !ENABLE(OILPAN) | |
142 virtual ~TraceEventListener() { } | |
143 #endif | |
144 virtual void call(const TraceEventDispatcher::TraceEvent&) = 0; | |
145 virtual void* target() = 0; | |
146 virtual void trace(Visitor*) { } | |
147 }; | |
148 | |
149 static TraceEventDispatcher* instance() | |
150 { | |
151 DEFINE_STATIC_LOCAL(TraceEventDispatcher, instance, ()); | |
152 return &instance; | |
153 } | |
154 | |
155 void addListener(const char* name, char phase, PassOwnPtrWillBeRawPtr<TraceE
ventListener>, InspectorClient*); | |
156 | |
157 void removeAllListeners(void*, InspectorClient*); | |
158 void processBackgroundEvents(); | |
159 | |
160 private: | |
161 typedef std::pair<String, int> EventSelector; | |
162 typedef WillBeHeapHashMap<EventSelector, OwnPtrWillBeMember<WillBeHeapVector
<OwnPtrWillBeMember<TraceEventListener> > > > ListenersMap; | |
163 | |
164 TraceEventDispatcher() | |
165 : m_listeners(adoptPtrWillBeNoop(new ListenersMap())) | |
166 , m_processEventsTaskInFlight(false) | |
167 , m_lastEventProcessingTime(0) | |
168 { | |
169 } | |
170 | |
171 static void dispatchEventOnAnyThread(char phase, const unsigned char*, const
char* name, unsigned long long id, | |
172 int numArgs, const char* const* argNames, const unsigned char* argTypes,
const unsigned long long* argValues, | |
173 unsigned char flags, double timestamp); | |
174 | |
175 void enqueueEvent(const TraceEvent&); | |
176 void processBackgroundEventsTask(); | |
177 | |
178 Mutex m_mutex; | |
179 OwnPtrWillBePersistent<ListenersMap> m_listeners; | |
180 Vector<TraceEvent> m_backgroundEvents; | |
181 bool m_processEventsTaskInFlight; | |
182 double m_lastEventProcessingTime; | |
183 }; | |
184 | |
185 } // namespace blink | |
186 | |
187 #endif // TraceEventDispatcher_h | |
OLD | NEW |