Chromium Code Reviews| 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 |