OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | 3 * Copyright (C) 2012 Intel Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 17 matching lines...) Expand all Loading... | |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #include "config.h" | 32 #include "config.h" |
33 #include "core/timing/PerformanceBase.h" | 33 #include "core/timing/PerformanceBase.h" |
34 | 34 |
35 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
36 #include "core/events/Event.h" | 36 #include "core/events/Event.h" |
37 #include "core/timing/PerformanceCompositeTiming.h" | 37 #include "core/timing/PerformanceCompositeTiming.h" |
38 #include "core/timing/PerformanceObserver.h" | |
39 #include "core/timing/PerformanceObserverRegistration.h" | |
38 #include "core/timing/PerformanceRenderTiming.h" | 40 #include "core/timing/PerformanceRenderTiming.h" |
39 #include "core/timing/PerformanceResourceTiming.h" | 41 #include "core/timing/PerformanceResourceTiming.h" |
40 #include "core/timing/PerformanceUserTiming.h" | 42 #include "core/timing/PerformanceUserTiming.h" |
41 #include "platform/network/ResourceTimingInfo.h" | 43 #include "platform/network/ResourceTimingInfo.h" |
42 #include "platform/weborigin/SecurityOrigin.h" | 44 #include "platform/weborigin/SecurityOrigin.h" |
43 #include "wtf/CurrentTime.h" | 45 #include "wtf/CurrentTime.h" |
44 | 46 |
45 namespace blink { | 47 namespace blink { |
46 | 48 |
47 static const size_t defaultResourceTimingBufferSize = 150; | 49 static const size_t defaultResourceTimingBufferSize = 150; |
48 static const size_t defaultFrameTimingBufferSize = 150; | 50 static const size_t defaultFrameTimingBufferSize = 150; |
49 | 51 |
52 // The order here has to match the order in PerformanceBase.h enum FilterType | |
53 static const char* kFilterTypes[] = { | |
54 "_dummy_", | |
esprehn
2015/07/18 22:24:15
What is _dummy_/ we don't generally do this. maybe
MikeB
2015/07/20 23:06:50
Done.
| |
55 "composite", | |
56 "mark", | |
57 "measure", | |
58 "render", | |
59 "resource" | |
60 }; | |
61 | |
50 PerformanceBase::PerformanceBase(double timeOrigin) | 62 PerformanceBase::PerformanceBase(double timeOrigin) |
51 : m_frameTimingBufferSize(defaultFrameTimingBufferSize) | 63 : m_frameTimingBufferSize(defaultFrameTimingBufferSize) |
52 , m_resourceTimingBufferSize(defaultResourceTimingBufferSize) | 64 , m_resourceTimingBufferSize(defaultResourceTimingBufferSize) |
53 , m_timeOrigin(timeOrigin) | 65 , m_timeOrigin(timeOrigin) |
54 , m_userTiming(nullptr) | 66 , m_userTiming(nullptr) |
55 { | 67 { |
56 } | 68 } |
57 | 69 |
58 PerformanceBase::~PerformanceBase() | 70 PerformanceBase::~PerformanceBase() |
59 { | 71 { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 for (const ResourceResponse& response : redirectChain) { | 216 for (const ResourceResponse& response : redirectChain) { |
205 if (!passesTimingAllowCheck(response, initiatorSecurityOrigin, emptyAtom )) | 217 if (!passesTimingAllowCheck(response, initiatorSecurityOrigin, emptyAtom )) |
206 return false; | 218 return false; |
207 } | 219 } |
208 | 220 |
209 return true; | 221 return true; |
210 } | 222 } |
211 | 223 |
212 void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) | 224 void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) |
213 { | 225 { |
214 if (isResourceTimingBufferFull()) | 226 if (isResourceTimingBufferFull() && !hasObserverFor(Resource)) |
215 return; | 227 return; |
216 SecurityOrigin* securityOrigin = nullptr; | 228 SecurityOrigin* securityOrigin = nullptr; |
217 if (ExecutionContext* context = executionContext()) | 229 if (ExecutionContext* context = executionContext()) |
218 securityOrigin = context->securityOrigin(); | 230 securityOrigin = context->securityOrigin(); |
219 if (!securityOrigin) | 231 if (!securityOrigin) |
220 return; | 232 return; |
221 | 233 |
222 const ResourceResponse& finalResponse = info.finalResponse(); | 234 const ResourceResponse& finalResponse = info.finalResponse(); |
223 bool allowTimingDetails = passesTimingAllowCheck(finalResponse, *securityOri gin, info.originalTimingAllowOrigin()); | 235 bool allowTimingDetails = passesTimingAllowCheck(finalResponse, *securityOri gin, info.originalTimingAllowOrigin()); |
224 double startTime = info.initialTime(); | 236 double startTime = info.initialTime(); |
(...skipping 12 matching lines...) Expand all Loading... | |
237 ASSERT(finalTiming); | 249 ASSERT(finalTiming); |
238 if (finalTiming) | 250 if (finalTiming) |
239 startTime = finalTiming->requestTime(); | 251 startTime = finalTiming->requestTime(); |
240 } | 252 } |
241 | 253 |
242 ResourceLoadTiming* lastRedirectTiming = redirectChain.last().resourceLoadTi ming(); | 254 ResourceLoadTiming* lastRedirectTiming = redirectChain.last().resourceLoadTi ming(); |
243 ASSERT(lastRedirectTiming); | 255 ASSERT(lastRedirectTiming); |
244 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); | 256 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
245 | 257 |
246 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOrigin (), startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails); | 258 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOrigin (), startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails); |
247 addResourceTimingBuffer(entry); | 259 notifyObserversOfEntry(Resource, entry); |
260 if (!isResourceTimingBufferFull()) | |
261 addResourceTimingBuffer(entry); | |
248 } | 262 } |
249 | 263 |
250 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry* entry) | 264 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry* entry) |
251 { | 265 { |
252 m_resourceTimingBuffer.append(entry); | 266 m_resourceTimingBuffer.append(entry); |
253 | 267 |
254 if (isResourceTimingBufferFull()) | 268 if (isResourceTimingBufferFull()) |
255 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu ll)); | 269 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu ll)); |
256 } | 270 } |
257 | 271 |
258 bool PerformanceBase::isResourceTimingBufferFull() | 272 bool PerformanceBase::isResourceTimingBufferFull() |
259 { | 273 { |
260 return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize; | 274 return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize; |
261 } | 275 } |
262 | 276 |
263 void PerformanceBase::addRenderTiming(Document* initiatorDocument, unsigned sour ceFrame, double startTime, double finishTime) | 277 void PerformanceBase::addRenderTiming(Document* initiatorDocument, unsigned sour ceFrame, double startTime, double finishTime) |
264 { | 278 { |
265 if (isFrameTimingBufferFull()) | 279 if (isFrameTimingBufferFull() && !hasObserverFor(Render)) |
266 return; | 280 return; |
267 | 281 |
268 PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument, sourceFrame, startTime, finishTime); | 282 PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument, sourceFrame, startTime, finishTime); |
269 addFrameTimingBuffer(entry); | 283 notifyObserversOfEntry(Render, entry); |
284 if (!isFrameTimingBufferFull()) | |
285 addFrameTimingBuffer(entry); | |
270 } | 286 } |
271 | 287 |
272 void PerformanceBase::addCompositeTiming(Document* initiatorDocument, unsigned s ourceFrame, double startTime) | 288 void PerformanceBase::addCompositeTiming(Document* initiatorDocument, unsigned s ourceFrame, double startTime) |
273 { | 289 { |
274 if (isFrameTimingBufferFull()) | 290 if (isFrameTimingBufferFull() && !hasObserverFor(Composite)) |
275 return; | 291 return; |
276 | 292 |
277 PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocume nt, sourceFrame, startTime); | 293 PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocume nt, sourceFrame, startTime); |
278 addFrameTimingBuffer(entry); | 294 notifyObserversOfEntry(Composite, entry); |
295 if (!isFrameTimingBufferFull()) | |
296 addFrameTimingBuffer(entry); | |
279 } | 297 } |
280 | 298 |
281 void PerformanceBase::addFrameTimingBuffer(PerformanceEntry* entry) | 299 void PerformanceBase::addFrameTimingBuffer(PerformanceEntry* entry) |
282 { | 300 { |
283 m_frameTimingBuffer.append(entry); | 301 m_frameTimingBuffer.append(entry); |
284 | 302 |
285 if (isFrameTimingBufferFull()) | 303 if (isFrameTimingBufferFull()) |
286 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull)); | 304 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull)); |
287 } | 305 } |
288 | 306 |
289 bool PerformanceBase::isFrameTimingBufferFull() | 307 bool PerformanceBase::isFrameTimingBufferFull() |
290 { | 308 { |
291 return m_frameTimingBuffer.size() >= m_frameTimingBufferSize; | 309 return m_frameTimingBuffer.size() >= m_frameTimingBufferSize; |
292 } | 310 } |
293 | 311 |
294 void PerformanceBase::mark(const String& markName, ExceptionState& exceptionStat e) | 312 void PerformanceBase::mark(const String& markName, ExceptionState& exceptionStat e) |
295 { | 313 { |
296 if (!m_userTiming) | 314 if (!m_userTiming) |
297 m_userTiming = UserTiming::create(this); | 315 m_userTiming = UserTiming::create(this); |
298 m_userTiming->mark(markName, exceptionState); | 316 NewPerformanceEntryCallback callback = WTF::bind<PerformanceEntry*>(&Perform anceBase::notifyObserversOfEntry, this, Mark); |
317 m_userTiming->mark(markName, callback, exceptionState); | |
299 } | 318 } |
300 | 319 |
301 void PerformanceBase::clearMarks(const String& markName) | 320 void PerformanceBase::clearMarks(const String& markName) |
302 { | 321 { |
303 if (!m_userTiming) | 322 if (!m_userTiming) |
304 m_userTiming = UserTiming::create(this); | 323 m_userTiming = UserTiming::create(this); |
305 m_userTiming->clearMarks(markName); | 324 m_userTiming->clearMarks(markName); |
306 } | 325 } |
307 | 326 |
308 void PerformanceBase::measure(const String& measureName, const String& startMark , const String& endMark, ExceptionState& exceptionState) | 327 void PerformanceBase::measure(const String& measureName, const String& startMark , const String& endMark, ExceptionState& exceptionState) |
309 { | 328 { |
310 if (!m_userTiming) | 329 if (!m_userTiming) |
311 m_userTiming = UserTiming::create(this); | 330 m_userTiming = UserTiming::create(this); |
312 m_userTiming->measure(measureName, startMark, endMark, exceptionState); | 331 NewPerformanceEntryCallback callback = WTF::bind<PerformanceEntry*>(&Perform anceBase::notifyObserversOfEntry, this, Measure); |
332 m_userTiming->measure(measureName, startMark, endMark, callback, exceptionSt ate); | |
esprehn
2015/07/18 22:24:16
Hmm, this seems like you're going to notify multip
MikeB
2015/07/20 23:06:50
That's how it's supposed to work, no? You can crea
| |
313 } | 333 } |
314 | 334 |
315 void PerformanceBase::clearMeasures(const String& measureName) | 335 void PerformanceBase::clearMeasures(const String& measureName) |
316 { | 336 { |
317 if (!m_userTiming) | 337 if (!m_userTiming) |
318 m_userTiming = UserTiming::create(this); | 338 m_userTiming = UserTiming::create(this); |
319 m_userTiming->clearMeasures(measureName); | 339 m_userTiming->clearMeasures(measureName); |
320 } | 340 } |
321 | 341 |
342 void PerformanceBase::registerPerformanceObserver(PerformanceObserverRegistratio n* registration) | |
343 { | |
344 for (FilterTypeIndex filterIndex = 1; filterIndex < (sizeof(kFilterTypes) / sizeof(char*)); ++filterIndex) { | |
esprehn
2015/07/18 22:24:16
I think you want WTF_ARRAY_LENGTH here.
1 is a th
| |
345 if (registration->shouldReceiveEntryFrom(kFilterTypes[filterIndex])) { | |
346 PerformanceObserverRegistrations::AddResult result = m_observerRegis try.add(filterIndex, PerformanceObserverRegistrationVector()); | |
347 registration->addReference(); | |
esprehn
2015/07/18 22:24:15
What is this addReference() ? That means each thin
MikeB
2015/07/20 23:06:50
Got rid of it (and PerformanceObserverRegistration
| |
348 result.storedValue->value.append(registration); | |
349 } | |
350 } | |
351 } | |
352 PerformanceObserver* PerformanceBase::createPerformanceObserver(PerformanceObser verCallback* callback) | |
esprehn
2015/07/18 22:24:16
What is this? it should be new PerformanceObserver
MikeB
2015/07/20 23:06:50
See issue tracker - switching back to new Performa
| |
353 { | |
354 return PerformanceObserver::create(this, callback); | |
355 } | |
356 | |
357 void PerformanceBase::unregisterPerformanceObserver(PerformanceObserverRegistrat ion* registration) | |
358 { | |
359 for (auto& registry : m_observerRegistry) { | |
360 size_t index = registry.value.find(registration); | |
esprehn
2015/07/18 22:24:15
I think you want to make this simpler, have a sing
MikeB
2015/07/20 23:06:50
Done.
| |
361 if (index == kNotFound) | |
362 continue; | |
363 registration->dispose(); | |
364 registry.value.remove(index); | |
365 } | |
366 } | |
367 | |
368 void PerformanceBase::notifyObserversOfEntry(FilterType filterType, PerformanceE ntry* entry) | |
369 { | |
370 PerformanceObserverRegistrations::iterator registry = m_observerRegistry.fin d(filterType); | |
371 if (registry == m_observerRegistry.end()) | |
372 return; | |
373 for (auto& registration : *registry.values()) { | |
374 registration->observer().enqueuePerformanceEntry(entry); | |
375 } | |
376 } | |
377 | |
378 bool PerformanceBase::hasObserverFor(FilterType filterType) | |
379 { | |
380 PerformanceObserverRegistrations::iterator registry = m_observerRegistry.fin d(filterType); | |
381 return registry != m_observerRegistry.end() && registry.values()->size(); | |
382 } | |
383 | |
322 double PerformanceBase::now() const | 384 double PerformanceBase::now() const |
323 { | 385 { |
324 double nowSeconds = monotonicallyIncreasingTime() - m_timeOrigin; | 386 double nowSeconds = monotonicallyIncreasingTime() - m_timeOrigin; |
325 const double resolutionSeconds = 0.000005; | 387 const double resolutionSeconds = 0.000005; |
326 return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds; | 388 return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds; |
327 } | 389 } |
328 | 390 |
329 DEFINE_TRACE(PerformanceBase) | 391 DEFINE_TRACE(PerformanceBase) |
330 { | 392 { |
331 visitor->trace(m_frameTimingBuffer); | 393 visitor->trace(m_frameTimingBuffer); |
332 visitor->trace(m_resourceTimingBuffer); | 394 visitor->trace(m_resourceTimingBuffer); |
333 visitor->trace(m_userTiming); | 395 visitor->trace(m_userTiming); |
396 visitor->trace(m_observerRegistry); | |
334 EventTargetWithInlineData::trace(visitor); | 397 EventTargetWithInlineData::trace(visitor); |
335 } | 398 } |
336 | 399 |
337 } // namespace blink | 400 } // namespace blink |
OLD | NEW |