OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) | 84 static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget) |
85 { | 85 { |
86 const AtomicString& interfaceName = eventTarget->interfaceName(); | 86 const AtomicString& interfaceName = eventTarget->interfaceName(); |
87 if (interfaceName == EventTargetNames::XMLHttpRequest) | 87 if (interfaceName == EventTargetNames::XMLHttpRequest) |
88 return static_cast<XMLHttpRequest*>(eventTarget); | 88 return static_cast<XMLHttpRequest*>(eventTarget); |
89 if (interfaceName == EventTargetNames::XMLHttpRequestUpload) | 89 if (interfaceName == EventTargetNames::XMLHttpRequestUpload) |
90 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest()
; | 90 return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest()
; |
91 return 0; | 91 return 0; |
92 } | 92 } |
93 | 93 |
94 AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description,
const StackTrace& callFrames) | 94 AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description,
const StackTraces& callFrames) |
95 : m_description(description) | 95 : m_description(description) |
96 , m_callFrames(callFrames) | 96 , m_callFrames(callFrames) |
97 { | 97 { |
98 } | 98 } |
99 | 99 |
100 AsyncCallStackTracker::AsyncCallStack::~AsyncCallStack() | 100 AsyncCallStackTracker::AsyncCallStack::~AsyncCallStack() |
101 { | 101 { |
102 } | 102 } |
103 | 103 |
104 AsyncCallStackTracker::AsyncCallStackTracker() | 104 AsyncCallStackTracker::AsyncCallStackTracker() |
(...skipping 11 matching lines...) Expand all Loading... |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 const AsyncCallStackTracker::AsyncCallChain* AsyncCallStackTracker::currentAsync
CallChain() const | 119 const AsyncCallStackTracker::AsyncCallChain* AsyncCallStackTracker::currentAsync
CallChain() const |
120 { | 120 { |
121 if (m_currentAsyncCallChain) | 121 if (m_currentAsyncCallChain) |
122 ensureMaxAsyncCallChainDepth(m_currentAsyncCallChain.get(), m_maxAsyncCa
llStackDepth); | 122 ensureMaxAsyncCallChainDepth(m_currentAsyncCallChain.get(), m_maxAsyncCa
llStackDepth); |
123 return m_currentAsyncCallChain.get(); | 123 return m_currentAsyncCallChain.get(); |
124 } | 124 } |
125 | 125 |
126 void AsyncCallStackTracker::didInstallTimer(ExecutionContext* context, int timer
Id, bool singleShot, const StackTrace& callFrames) | 126 void AsyncCallStackTracker::didInstallTimer(ExecutionContext* context, int timer
Id, bool singleShot, const StackTraces& callFrames) |
127 { | 127 { |
128 ASSERT(context); | 128 ASSERT(context); |
129 ASSERT(isEnabled()); | 129 ASSERT(isEnabled()); |
130 if (!validateCallFrames(callFrames)) | 130 if (!validateCallFrames(callFrames)) |
131 return; | 131 return; |
132 ASSERT(timerId > 0); | 132 ASSERT(timerId > 0); |
133 ExecutionContextData* data = createContextDataIfNeeded(context); | 133 ExecutionContextData* data = createContextDataIfNeeded(context); |
134 data->m_timerCallChains.set(timerId, createAsyncCallChain(singleShot ? setTi
meoutName : setIntervalName, callFrames)); | 134 data->m_timerCallChains.set(timerId, createAsyncCallChain(singleShot ? setTi
meoutName : setIntervalName, callFrames)); |
135 if (!singleShot) | 135 if (!singleShot) |
136 data->m_intervalTimerIds.add(timerId); | 136 data->m_intervalTimerIds.add(timerId); |
(...skipping 21 matching lines...) Expand all Loading... |
158 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { | 158 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) { |
159 if (data->m_intervalTimerIds.contains(timerId)) | 159 if (data->m_intervalTimerIds.contains(timerId)) |
160 setCurrentAsyncCallChain(data->m_timerCallChains.get(timerId)); | 160 setCurrentAsyncCallChain(data->m_timerCallChains.get(timerId)); |
161 else | 161 else |
162 setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId)); | 162 setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId)); |
163 } else { | 163 } else { |
164 setCurrentAsyncCallChain(nullptr); | 164 setCurrentAsyncCallChain(nullptr); |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 void AsyncCallStackTracker::didRequestAnimationFrame(ExecutionContext* context,
int callbackId, const StackTrace& callFrames) | 168 void AsyncCallStackTracker::didRequestAnimationFrame(ExecutionContext* context,
int callbackId, const StackTraces& callFrames) |
169 { | 169 { |
170 ASSERT(context); | 170 ASSERT(context); |
171 ASSERT(isEnabled()); | 171 ASSERT(isEnabled()); |
172 if (!validateCallFrames(callFrames)) | 172 if (!validateCallFrames(callFrames)) |
173 return; | 173 return; |
174 ASSERT(callbackId > 0); | 174 ASSERT(callbackId > 0); |
175 ExecutionContextData* data = createContextDataIfNeeded(context); | 175 ExecutionContextData* data = createContextDataIfNeeded(context); |
176 data->m_animationFrameCallChains.set(callbackId, createAsyncCallChain(reques
tAnimationFrameName, callFrames)); | 176 data->m_animationFrameCallChains.set(callbackId, createAsyncCallChain(reques
tAnimationFrameName, callFrames)); |
177 } | 177 } |
178 | 178 |
(...skipping 12 matching lines...) Expand all Loading... |
191 ASSERT(context); | 191 ASSERT(context); |
192 ASSERT(isEnabled()); | 192 ASSERT(isEnabled()); |
193 ASSERT(callbackId > 0); | 193 ASSERT(callbackId > 0); |
194 ASSERT(!m_currentAsyncCallChain); | 194 ASSERT(!m_currentAsyncCallChain); |
195 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) | 195 if (ExecutionContextData* data = m_executionContextDataMap.get(context)) |
196 setCurrentAsyncCallChain(data->m_animationFrameCallChains.take(callbackI
d)); | 196 setCurrentAsyncCallChain(data->m_animationFrameCallChains.take(callbackI
d)); |
197 else | 197 else |
198 setCurrentAsyncCallChain(nullptr); | 198 setCurrentAsyncCallChain(nullptr); |
199 } | 199 } |
200 | 200 |
201 void AsyncCallStackTracker::didEnqueueEvent(EventTarget* eventTarget, Event* eve
nt, const StackTrace& callFrames) | 201 void AsyncCallStackTracker::didEnqueueEvent(EventTarget* eventTarget, Event* eve
nt, const StackTraces& callFrames) |
202 { | 202 { |
203 ASSERT(eventTarget->executionContext()); | 203 ASSERT(eventTarget->executionContext()); |
204 ASSERT(isEnabled()); | 204 ASSERT(isEnabled()); |
205 if (!validateCallFrames(callFrames)) | 205 if (!validateCallFrames(callFrames)) |
206 return; | 206 return; |
207 ExecutionContextData* data = createContextDataIfNeeded(eventTarget->executio
nContext()); | 207 ExecutionContextData* data = createContextDataIfNeeded(eventTarget->executio
nContext()); |
208 data->m_eventCallChains.set(event, createAsyncCallChain(event->type(), callF
rames)); | 208 data->m_eventCallChains.set(event, createAsyncCallChain(event->type(), callF
rames)); |
209 } | 209 } |
210 | 210 |
211 void AsyncCallStackTracker::didRemoveEvent(EventTarget* eventTarget, Event* even
t) | 211 void AsyncCallStackTracker::didRemoveEvent(EventTarget* eventTarget, Event* even
t) |
(...skipping 11 matching lines...) Expand all Loading... |
223 if (XMLHttpRequest* xhr = toXmlHttpRequest(eventTarget)) { | 223 if (XMLHttpRequest* xhr = toXmlHttpRequest(eventTarget)) { |
224 willHandleXHREvent(xhr, eventTarget, event); | 224 willHandleXHREvent(xhr, eventTarget, event); |
225 } else { | 225 } else { |
226 if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarg
et->executionContext())) | 226 if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarg
et->executionContext())) |
227 setCurrentAsyncCallChain(data->m_eventCallChains.get(event)); | 227 setCurrentAsyncCallChain(data->m_eventCallChains.get(event)); |
228 else | 228 else |
229 setCurrentAsyncCallChain(nullptr); | 229 setCurrentAsyncCallChain(nullptr); |
230 } | 230 } |
231 } | 231 } |
232 | 232 |
233 void AsyncCallStackTracker::willLoadXHR(XMLHttpRequest* xhr, const StackTrace& c
allFrames) | 233 void AsyncCallStackTracker::willLoadXHR(XMLHttpRequest* xhr, const StackTraces&
callFrames) |
234 { | 234 { |
235 ASSERT(xhr->executionContext()); | 235 ASSERT(xhr->executionContext()); |
236 ASSERT(isEnabled()); | 236 ASSERT(isEnabled()); |
237 if (!validateCallFrames(callFrames)) | 237 if (!validateCallFrames(callFrames)) |
238 return; | 238 return; |
239 ExecutionContextData* data = createContextDataIfNeeded(xhr->executionContext
()); | 239 ExecutionContextData* data = createContextDataIfNeeded(xhr->executionContext
()); |
240 data->m_xhrCallChains.set(xhr, createAsyncCallChain(xhrSendName, callFrames)
); | 240 data->m_xhrCallChains.set(xhr, createAsyncCallChain(xhrSendName, callFrames)
); |
241 } | 241 } |
242 | 242 |
243 void AsyncCallStackTracker::willHandleXHREvent(XMLHttpRequest* xhr, EventTarget*
eventTarget, Event* event) | 243 void AsyncCallStackTracker::willHandleXHREvent(XMLHttpRequest* xhr, EventTarget*
eventTarget, Event* event) |
244 { | 244 { |
245 ASSERT(xhr->executionContext()); | 245 ASSERT(xhr->executionContext()); |
246 ASSERT(isEnabled()); | 246 ASSERT(isEnabled()); |
247 if (ExecutionContextData* data = m_executionContextDataMap.get(xhr->executio
nContext())) { | 247 if (ExecutionContextData* data = m_executionContextDataMap.get(xhr->executio
nContext())) { |
248 bool isXHRDownload = (xhr == eventTarget); | 248 bool isXHRDownload = (xhr == eventTarget); |
249 if (isXHRDownload && event->type() == EventTypeNames::loadend) | 249 if (isXHRDownload && event->type() == EventTypeNames::loadend) |
250 setCurrentAsyncCallChain(data->m_xhrCallChains.take(xhr)); | 250 setCurrentAsyncCallChain(data->m_xhrCallChains.take(xhr)); |
251 else | 251 else |
252 setCurrentAsyncCallChain(data->m_xhrCallChains.get(xhr)); | 252 setCurrentAsyncCallChain(data->m_xhrCallChains.get(xhr)); |
253 } else { | 253 } else { |
254 setCurrentAsyncCallChain(nullptr); | 254 setCurrentAsyncCallChain(nullptr); |
255 } | 255 } |
256 } | 256 } |
257 | 257 |
258 void AsyncCallStackTracker::didEnqueueMutationRecord(ExecutionContext* context,
MutationObserver* observer, const StackTrace& callFrames) | 258 void AsyncCallStackTracker::didEnqueueMutationRecord(ExecutionContext* context,
MutationObserver* observer, const StackTraces& callFrames) |
259 { | 259 { |
260 ASSERT(context); | 260 ASSERT(context); |
261 ASSERT(isEnabled()); | 261 ASSERT(isEnabled()); |
262 if (!validateCallFrames(callFrames)) | 262 if (!validateCallFrames(callFrames)) |
263 return; | 263 return; |
264 ExecutionContextData* data = createContextDataIfNeeded(context); | 264 ExecutionContextData* data = createContextDataIfNeeded(context); |
265 data->m_mutationObserverCallChains.set(observer, createAsyncCallChain(enqueu
eMutationRecordName, callFrames)); | 265 data->m_mutationObserverCallChains.set(observer, createAsyncCallChain(enqueu
eMutationRecordName, callFrames)); |
266 } | 266 } |
267 | 267 |
268 bool AsyncCallStackTracker::hasEnqueuedMutationRecord(ExecutionContext* context,
MutationObserver* observer) | 268 bool AsyncCallStackTracker::hasEnqueuedMutationRecord(ExecutionContext* context,
MutationObserver* observer) |
(...skipping 21 matching lines...) Expand all Loading... |
290 setCurrentAsyncCallChain(data->m_mutationObserverCallChains.take(observe
r)); | 290 setCurrentAsyncCallChain(data->m_mutationObserverCallChains.take(observe
r)); |
291 else | 291 else |
292 setCurrentAsyncCallChain(nullptr); | 292 setCurrentAsyncCallChain(nullptr); |
293 } | 293 } |
294 | 294 |
295 void AsyncCallStackTracker::didFireAsyncCall() | 295 void AsyncCallStackTracker::didFireAsyncCall() |
296 { | 296 { |
297 clearCurrentAsyncCallChain(); | 297 clearCurrentAsyncCallChain(); |
298 } | 298 } |
299 | 299 |
300 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA
syncCallChain(const String& description, const StackTrace& callFrames) | 300 PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createA
syncCallChain(const String& description, const StackTraces& callFrames) |
301 { | 301 { |
302 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC
allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr
acker::AsyncCallChain()); | 302 RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncC
allStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTr
acker::AsyncCallChain()); |
303 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); | 303 ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1); |
304 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta
ck(description, callFrames))); | 304 chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallSta
ck(description, callFrames))); |
305 return chain.release(); | 305 return chain.release(); |
306 } | 306 } |
307 | 307 |
308 void AsyncCallStackTracker::setCurrentAsyncCallChain(PassRefPtr<AsyncCallChain>
chain) | 308 void AsyncCallStackTracker::setCurrentAsyncCallChain(PassRefPtr<AsyncCallChain>
chain) |
309 { | 309 { |
310 if (V8RecursionScope::recursionLevel(v8::Isolate::GetCurrent())) { | 310 if (V8RecursionScope::recursionLevel(v8::Isolate::GetCurrent())) { |
(...skipping 14 matching lines...) Expand all Loading... |
325 if (!m_nestedAsyncCallCount) | 325 if (!m_nestedAsyncCallCount) |
326 m_currentAsyncCallChain.clear(); | 326 m_currentAsyncCallChain.clear(); |
327 } | 327 } |
328 | 328 |
329 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain,
unsigned maxDepth) | 329 void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain,
unsigned maxDepth) |
330 { | 330 { |
331 while (chain->m_callStacks.size() > maxDepth) | 331 while (chain->m_callStacks.size() > maxDepth) |
332 chain->m_callStacks.removeLast(); | 332 chain->m_callStacks.removeLast(); |
333 } | 333 } |
334 | 334 |
335 bool AsyncCallStackTracker::validateCallFrames(const StackTrace& callFrames) | 335 bool AsyncCallStackTracker::validateCallFrames(const StackTraces& callFrames) |
336 { | 336 { |
337 return !callFrames.isNull(); | 337 return !callFrames.isNull(); |
338 } | 338 } |
339 | 339 |
340 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex
tDataIfNeeded(ExecutionContext* context) | 340 AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex
tDataIfNeeded(ExecutionContext* context) |
341 { | 341 { |
342 ExecutionContextData* data = m_executionContextDataMap.get(context); | 342 ExecutionContextData* data = m_executionContextDataMap.get(context); |
343 if (!data) { | 343 if (!data) { |
344 data = new AsyncCallStackTracker::ExecutionContextData(this, context); | 344 data = new AsyncCallStackTracker::ExecutionContextData(this, context); |
345 m_executionContextDataMap.set(context, data); | 345 m_executionContextDataMap.set(context, data); |
346 } | 346 } |
347 return data; | 347 return data; |
348 } | 348 } |
349 | 349 |
350 void AsyncCallStackTracker::clear() | 350 void AsyncCallStackTracker::clear() |
351 { | 351 { |
352 m_currentAsyncCallChain.clear(); | 352 m_currentAsyncCallChain.clear(); |
353 m_nestedAsyncCallCount = 0; | 353 m_nestedAsyncCallCount = 0; |
354 ExecutionContextDataMap copy; | 354 ExecutionContextDataMap copy; |
355 m_executionContextDataMap.swap(copy); | 355 m_executionContextDataMap.swap(copy); |
356 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e
nd(); ++it) | 356 for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.e
nd(); ++it) |
357 delete it->value; | 357 delete it->value; |
358 } | 358 } |
359 | 359 |
360 } // namespace WebCore | 360 } // namespace WebCore |
OLD | NEW |