| 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" |
| 38 #include "core/timing/PerformanceRenderTiming.h" | 39 #include "core/timing/PerformanceRenderTiming.h" |
| 39 #include "core/timing/PerformanceResourceTiming.h" | 40 #include "core/timing/PerformanceResourceTiming.h" |
| 40 #include "core/timing/PerformanceUserTiming.h" | 41 #include "core/timing/PerformanceUserTiming.h" |
| 41 #include "platform/network/ResourceTimingInfo.h" | 42 #include "platform/network/ResourceTimingInfo.h" |
| 42 #include "platform/weborigin/SecurityOrigin.h" | 43 #include "platform/weborigin/SecurityOrigin.h" |
| 43 #include "wtf/CurrentTime.h" | 44 #include "wtf/CurrentTime.h" |
| 44 | 45 |
| 45 namespace blink { | 46 namespace blink { |
| 46 | 47 |
| 48 using PerformanceObserverVector = HeapVector<Member<PerformanceObserver>>; |
| 49 |
| 47 static const size_t defaultResourceTimingBufferSize = 150; | 50 static const size_t defaultResourceTimingBufferSize = 150; |
| 48 static const size_t defaultFrameTimingBufferSize = 150; | 51 static const size_t defaultFrameTimingBufferSize = 150; |
| 49 | 52 |
| 50 PerformanceBase::PerformanceBase(double timeOrigin) | 53 PerformanceBase::PerformanceBase(double timeOrigin) |
| 51 : m_frameTimingBufferSize(defaultFrameTimingBufferSize) | 54 : m_frameTimingBufferSize(defaultFrameTimingBufferSize) |
| 52 , m_resourceTimingBufferSize(defaultResourceTimingBufferSize) | 55 , m_resourceTimingBufferSize(defaultResourceTimingBufferSize) |
| 53 , m_timeOrigin(timeOrigin) | 56 , m_timeOrigin(timeOrigin) |
| 54 , m_userTiming(nullptr) | 57 , m_userTiming(nullptr) |
| 58 , m_observerFilterOptions(PerformanceEntry::Invalid) |
| 59 , m_deliverObservationsTimer(this, &PerformanceBase::deliverObservationsTime
rFired) |
| 55 { | 60 { |
| 56 } | 61 } |
| 57 | 62 |
| 58 PerformanceBase::~PerformanceBase() | 63 PerformanceBase::~PerformanceBase() |
| 59 { | 64 { |
| 60 } | 65 } |
| 61 | 66 |
| 62 const AtomicString& PerformanceBase::interfaceName() const | 67 const AtomicString& PerformanceBase::interfaceName() const |
| 63 { | 68 { |
| 64 return EventTargetNames::Performance; | 69 return EventTargetNames::Performance; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 81 entries.appendVector(m_userTiming->getMeasures()); | 86 entries.appendVector(m_userTiming->getMeasures()); |
| 82 } | 87 } |
| 83 | 88 |
| 84 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); | 89 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); |
| 85 return entries; | 90 return entries; |
| 86 } | 91 } |
| 87 | 92 |
| 88 PerformanceEntryVector PerformanceBase::getEntriesByType(const String& entryType
) | 93 PerformanceEntryVector PerformanceBase::getEntriesByType(const String& entryType
) |
| 89 { | 94 { |
| 90 PerformanceEntryVector entries; | 95 PerformanceEntryVector entries; |
| 96 PerformanceEntry::EntryType type = PerformanceEntry::toEntryTypeEnum(entryTy
pe); |
| 91 | 97 |
| 92 if (equalIgnoringCase(entryType, "resource")) { | 98 switch (type) { |
| 99 case PerformanceEntry::Invalid: |
| 100 return entries; |
| 101 case PerformanceEntry::Resource: |
| 93 for (const auto& resource : m_resourceTimingBuffer) | 102 for (const auto& resource : m_resourceTimingBuffer) |
| 94 entries.append(resource); | 103 entries.append(resource); |
| 95 } | 104 break; |
| 96 | 105 case PerformanceEntry::Composite: |
| 97 if (equalIgnoringCase(entryType, "composite") | 106 case PerformanceEntry::Render: |
| 98 || equalIgnoringCase(entryType, "render")) { | |
| 99 for (const auto& frame : m_frameTimingBuffer) { | 107 for (const auto& frame : m_frameTimingBuffer) { |
| 100 if (equalIgnoringCase(entryType, frame->entryType())) { | 108 if (type == frame->entryTypeEnum()) { |
| 101 entries.append(frame); | 109 entries.append(frame); |
| 102 } | 110 } |
| 103 } | 111 } |
| 104 } | 112 break; |
| 105 | 113 case PerformanceEntry::Mark: |
| 106 if (m_userTiming) { | 114 if (m_userTiming) |
| 107 if (equalIgnoringCase(entryType, "mark")) | |
| 108 entries.appendVector(m_userTiming->getMarks()); | 115 entries.appendVector(m_userTiming->getMarks()); |
| 109 else if (equalIgnoringCase(entryType, "measure")) | 116 break; |
| 117 case PerformanceEntry::Measure: |
| 118 if (m_userTiming) |
| 110 entries.appendVector(m_userTiming->getMeasures()); | 119 entries.appendVector(m_userTiming->getMeasures()); |
| 120 break; |
| 111 } | 121 } |
| 112 | 122 |
| 113 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); | 123 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); |
| 114 return entries; | 124 return entries; |
| 115 } | 125 } |
| 116 | 126 |
| 117 PerformanceEntryVector PerformanceBase::getEntriesByName(const String& name, con
st String& entryType) | 127 PerformanceEntryVector PerformanceBase::getEntriesByName(const String& name, con
st String& entryType) |
| 118 { | 128 { |
| 119 PerformanceEntryVector entries; | 129 PerformanceEntryVector entries; |
| 130 PerformanceEntry::EntryType type = PerformanceEntry::toEntryTypeEnum(entryTy
pe); |
| 120 | 131 |
| 121 if (entryType.isNull() || equalIgnoringCase(entryType, "resource")) { | 132 if (!entryType.isNull() && type == PerformanceEntry::Invalid) |
| 133 return entries; |
| 134 |
| 135 if (entryType.isNull() || type == PerformanceEntry::Resource) { |
| 122 for (const auto& resource : m_resourceTimingBuffer) { | 136 for (const auto& resource : m_resourceTimingBuffer) { |
| 123 if (resource->name() == name) | 137 if (resource->name() == name) |
| 124 entries.append(resource); | 138 entries.append(resource); |
| 125 } | 139 } |
| 126 } | 140 } |
| 127 | 141 |
| 128 if (entryType.isNull() || equalIgnoringCase(entryType, "composite") | 142 if (entryType.isNull() || type == PerformanceEntry::Composite || type == Per
formanceEntry::Render) { |
| 129 || equalIgnoringCase(entryType, "render")) { | |
| 130 for (const auto& frame : m_frameTimingBuffer) { | 143 for (const auto& frame : m_frameTimingBuffer) { |
| 131 if (frame->name() == name && (entryType.isNull() | 144 if (frame->name() == name && (entryType.isNull() |
| 132 || equalIgnoringCase(entryType, frame->entryType()))) { | 145 || equalIgnoringCase(entryType, frame->entryType()))) { |
| 133 entries.append(frame); | 146 entries.append(frame); |
| 134 } | 147 } |
| 135 } | 148 } |
| 136 } | 149 } |
| 137 | 150 |
| 138 if (m_userTiming) { | 151 if (m_userTiming) { |
| 139 if (entryType.isNull() || equalIgnoringCase(entryType, "mark")) | 152 if (entryType.isNull() || type == PerformanceEntry::Mark) |
| 140 entries.appendVector(m_userTiming->getMarks(name)); | 153 entries.appendVector(m_userTiming->getMarks(name)); |
| 141 if (entryType.isNull() || equalIgnoringCase(entryType, "measure")) | 154 if (entryType.isNull() || type == PerformanceEntry::Measure) |
| 142 entries.appendVector(m_userTiming->getMeasures(name)); | 155 entries.appendVector(m_userTiming->getMeasures(name)); |
| 143 } | 156 } |
| 144 | 157 |
| 145 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); | 158 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare
LessThan); |
| 146 return entries; | 159 return entries; |
| 147 } | 160 } |
| 148 | 161 |
| 149 void PerformanceBase::clearResourceTimings() | 162 void PerformanceBase::clearResourceTimings() |
| 150 { | 163 { |
| 151 m_resourceTimingBuffer.clear(); | 164 m_resourceTimingBuffer.clear(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 for (const ResourceResponse& response : redirectChain) { | 219 for (const ResourceResponse& response : redirectChain) { |
| 207 if (!passesTimingAllowCheck(response, initiatorSecurityOrigin, emptyAtom
)) | 220 if (!passesTimingAllowCheck(response, initiatorSecurityOrigin, emptyAtom
)) |
| 208 return false; | 221 return false; |
| 209 } | 222 } |
| 210 | 223 |
| 211 return true; | 224 return true; |
| 212 } | 225 } |
| 213 | 226 |
| 214 void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) | 227 void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) |
| 215 { | 228 { |
| 216 if (isResourceTimingBufferFull()) | 229 if (isResourceTimingBufferFull() && !hasObserverFor(PerformanceEntry::Resour
ce)) |
| 217 return; | 230 return; |
| 218 SecurityOrigin* securityOrigin = nullptr; | 231 SecurityOrigin* securityOrigin = nullptr; |
| 219 if (ExecutionContext* context = executionContext()) | 232 if (ExecutionContext* context = executionContext()) |
| 220 securityOrigin = context->securityOrigin(); | 233 securityOrigin = context->securityOrigin(); |
| 221 if (!securityOrigin) | 234 if (!securityOrigin) |
| 222 return; | 235 return; |
| 223 | 236 |
| 224 const ResourceResponse& finalResponse = info.finalResponse(); | 237 const ResourceResponse& finalResponse = info.finalResponse(); |
| 225 bool allowTimingDetails = passesTimingAllowCheck(finalResponse, *securityOri
gin, info.originalTimingAllowOrigin()); | 238 bool allowTimingDetails = passesTimingAllowCheck(finalResponse, *securityOri
gin, info.originalTimingAllowOrigin()); |
| 226 double startTime = info.initialTime(); | 239 double startTime = info.initialTime(); |
| 227 | 240 |
| 228 if (info.redirectChain().isEmpty()) { | 241 if (info.redirectChain().isEmpty()) { |
| 229 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOr
igin(), startTime, allowTimingDetails); | 242 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOr
igin(), startTime, allowTimingDetails); |
| 230 addResourceTimingBuffer(entry); | 243 addResourceTimingBuffer(*entry); |
| 231 return; | 244 return; |
| 232 } | 245 } |
| 233 | 246 |
| 234 const Vector<ResourceResponse>& redirectChain = info.redirectChain(); | 247 const Vector<ResourceResponse>& redirectChain = info.redirectChain(); |
| 235 bool allowRedirectDetails = allowsTimingRedirect(redirectChain, finalRespons
e, *securityOrigin); | 248 bool allowRedirectDetails = allowsTimingRedirect(redirectChain, finalRespons
e, *securityOrigin); |
| 236 | 249 |
| 237 if (!allowRedirectDetails) { | 250 if (!allowRedirectDetails) { |
| 238 ResourceLoadTiming* finalTiming = finalResponse.resourceLoadTiming(); | 251 ResourceLoadTiming* finalTiming = finalResponse.resourceLoadTiming(); |
| 239 ASSERT(finalTiming); | 252 ASSERT(finalTiming); |
| 240 if (finalTiming) | 253 if (finalTiming) |
| 241 startTime = finalTiming->requestTime(); | 254 startTime = finalTiming->requestTime(); |
| 242 } | 255 } |
| 243 | 256 |
| 244 ResourceLoadTiming* lastRedirectTiming = redirectChain.last().resourceLoadTi
ming(); | 257 ResourceLoadTiming* lastRedirectTiming = redirectChain.last().resourceLoadTi
ming(); |
| 245 ASSERT(lastRedirectTiming); | 258 ASSERT(lastRedirectTiming); |
| 246 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); | 259 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
| 247 | 260 |
| 248 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOrigin
(), startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails); | 261 PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOrigin
(), startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails); |
| 249 addResourceTimingBuffer(entry); | 262 notifyObserversOfEntry(*entry); |
| 263 if (!isResourceTimingBufferFull()) |
| 264 addResourceTimingBuffer(*entry); |
| 250 } | 265 } |
| 251 | 266 |
| 252 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry* entry) | 267 void PerformanceBase::addResourceTimingBuffer(PerformanceEntry& entry) |
| 253 { | 268 { |
| 254 m_resourceTimingBuffer.append(entry); | 269 m_resourceTimingBuffer.append(&entry); |
| 255 | 270 |
| 256 if (isResourceTimingBufferFull()) { | 271 if (isResourceTimingBufferFull()) { |
| 257 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); | 272 dispatchEvent(Event::create(EventTypeNames::resourcetimingbufferfull)); |
| 258 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu
ll)); | 273 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu
ll)); |
| 259 } | 274 } |
| 260 } | 275 } |
| 261 | 276 |
| 262 bool PerformanceBase::isResourceTimingBufferFull() | 277 bool PerformanceBase::isResourceTimingBufferFull() |
| 263 { | 278 { |
| 264 return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize; | 279 return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize; |
| 265 } | 280 } |
| 266 | 281 |
| 267 void PerformanceBase::addRenderTiming(Document* initiatorDocument, unsigned sour
ceFrame, double startTime, double finishTime) | 282 void PerformanceBase::addRenderTiming(Document* initiatorDocument, unsigned sour
ceFrame, double startTime, double finishTime) |
| 268 { | 283 { |
| 269 if (isFrameTimingBufferFull()) | 284 if (isFrameTimingBufferFull() && !hasObserverFor(PerformanceEntry::Render)) |
| 270 return; | 285 return; |
| 271 | 286 |
| 272 PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument,
sourceFrame, startTime, finishTime); | 287 PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument,
sourceFrame, startTime, finishTime); |
| 273 addFrameTimingBuffer(entry); | 288 notifyObserversOfEntry(*entry); |
| 289 if (!isFrameTimingBufferFull()) |
| 290 addFrameTimingBuffer(*entry); |
| 274 } | 291 } |
| 275 | 292 |
| 276 void PerformanceBase::addCompositeTiming(Document* initiatorDocument, unsigned s
ourceFrame, double startTime) | 293 void PerformanceBase::addCompositeTiming(Document* initiatorDocument, unsigned s
ourceFrame, double startTime) |
| 277 { | 294 { |
| 278 if (isFrameTimingBufferFull()) | 295 if (isFrameTimingBufferFull() && !hasObserverFor(PerformanceEntry::Composite
)) |
| 279 return; | 296 return; |
| 280 | 297 |
| 281 PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocume
nt, sourceFrame, startTime); | 298 PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocume
nt, sourceFrame, startTime); |
| 282 addFrameTimingBuffer(entry); | 299 notifyObserversOfEntry(*entry); |
| 300 if (!isFrameTimingBufferFull()) |
| 301 addFrameTimingBuffer(*entry); |
| 283 } | 302 } |
| 284 | 303 |
| 285 void PerformanceBase::addFrameTimingBuffer(PerformanceEntry* entry) | 304 void PerformanceBase::addFrameTimingBuffer(PerformanceEntry& entry) |
| 286 { | 305 { |
| 287 m_frameTimingBuffer.append(entry); | 306 m_frameTimingBuffer.append(&entry); |
| 288 | 307 |
| 289 if (isFrameTimingBufferFull()) | 308 if (isFrameTimingBufferFull()) |
| 290 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull)); | 309 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull)); |
| 291 } | 310 } |
| 292 | 311 |
| 293 bool PerformanceBase::isFrameTimingBufferFull() | 312 bool PerformanceBase::isFrameTimingBufferFull() |
| 294 { | 313 { |
| 295 return m_frameTimingBuffer.size() >= m_frameTimingBufferSize; | 314 return m_frameTimingBuffer.size() >= m_frameTimingBufferSize; |
| 296 } | 315 } |
| 297 | 316 |
| 298 void PerformanceBase::mark(const String& markName, ExceptionState& exceptionStat
e) | 317 void PerformanceBase::mark(const String& markName, ExceptionState& exceptionStat
e) |
| 299 { | 318 { |
| 300 if (!m_userTiming) | 319 if (!m_userTiming) |
| 301 m_userTiming = UserTiming::create(this); | 320 m_userTiming = UserTiming::create(*this); |
| 302 m_userTiming->mark(markName, exceptionState); | 321 if (PerformanceEntry* entry = m_userTiming->mark(markName, exceptionState)) |
| 322 notifyObserversOfEntry(*entry); |
| 303 } | 323 } |
| 304 | 324 |
| 305 void PerformanceBase::clearMarks(const String& markName) | 325 void PerformanceBase::clearMarks(const String& markName) |
| 306 { | 326 { |
| 307 if (!m_userTiming) | 327 if (!m_userTiming) |
| 308 m_userTiming = UserTiming::create(this); | 328 m_userTiming = UserTiming::create(*this); |
| 309 m_userTiming->clearMarks(markName); | 329 m_userTiming->clearMarks(markName); |
| 310 } | 330 } |
| 311 | 331 |
| 312 void PerformanceBase::measure(const String& measureName, const String& startMark
, const String& endMark, ExceptionState& exceptionState) | 332 void PerformanceBase::measure(const String& measureName, const String& startMark
, const String& endMark, ExceptionState& exceptionState) |
| 313 { | 333 { |
| 314 if (!m_userTiming) | 334 if (!m_userTiming) |
| 315 m_userTiming = UserTiming::create(this); | 335 m_userTiming = UserTiming::create(*this); |
| 316 m_userTiming->measure(measureName, startMark, endMark, exceptionState); | 336 if (PerformanceEntry* entry = m_userTiming->measure(measureName, startMark,
endMark, exceptionState)) |
| 337 notifyObserversOfEntry(*entry); |
| 317 } | 338 } |
| 318 | 339 |
| 319 void PerformanceBase::clearMeasures(const String& measureName) | 340 void PerformanceBase::clearMeasures(const String& measureName) |
| 320 { | 341 { |
| 321 if (!m_userTiming) | 342 if (!m_userTiming) |
| 322 m_userTiming = UserTiming::create(this); | 343 m_userTiming = UserTiming::create(*this); |
| 323 m_userTiming->clearMeasures(measureName); | 344 m_userTiming->clearMeasures(measureName); |
| 324 } | 345 } |
| 325 | 346 |
| 347 void PerformanceBase::registerPerformanceObserver(PerformanceObserver& observer) |
| 348 { |
| 349 m_observerFilterOptions |= observer.filterOptions(); |
| 350 m_observers.add(&observer); |
| 351 } |
| 352 |
| 353 void PerformanceBase::unregisterPerformanceObserver(PerformanceObserver& oldObse
rver) |
| 354 { |
| 355 m_observers.remove(&oldObserver); |
| 356 updatePerformanceObserverFilterOptions(); |
| 357 } |
| 358 |
| 359 void PerformanceBase::updatePerformanceObserverFilterOptions() |
| 360 { |
| 361 m_observerFilterOptions = PerformanceEntry::Invalid; |
| 362 for (const auto& observer : m_observers) { |
| 363 m_observerFilterOptions |= observer->filterOptions(); |
| 364 } |
| 365 } |
| 366 |
| 367 void PerformanceBase::notifyObserversOfEntry(PerformanceEntry& entry) |
| 368 { |
| 369 for (auto& observer : m_observers) { |
| 370 if (observer->filterOptions() & entry.entryTypeEnum()) |
| 371 observer->enqueuePerformanceEntry(entry); |
| 372 } |
| 373 } |
| 374 |
| 375 bool PerformanceBase::hasObserverFor(PerformanceEntry::EntryType filterType) |
| 376 { |
| 377 return m_observerFilterOptions & filterType; |
| 378 } |
| 379 |
| 380 void PerformanceBase::activateObserver(PerformanceObserver& observer) |
| 381 { |
| 382 if (m_activeObservers.isEmpty()) |
| 383 m_deliverObservationsTimer.startOneShot(0, FROM_HERE); |
| 384 |
| 385 m_activeObservers.add(&observer); |
| 386 } |
| 387 |
| 388 void PerformanceBase::resumeSuspendedObservers() |
| 389 { |
| 390 ASSERT(isMainThread()); |
| 391 if (m_suspendedObservers.isEmpty()) |
| 392 return; |
| 393 |
| 394 PerformanceObserverVector suspended; |
| 395 copyToVector(m_suspendedObservers, suspended); |
| 396 for (size_t i = 0; i < suspended.size(); ++i) { |
| 397 if (!suspended[i]->shouldBeSuspended()) { |
| 398 m_suspendedObservers.remove(suspended[i]); |
| 399 activateObserver(*suspended[i]); |
| 400 } |
| 401 } |
| 402 } |
| 403 |
| 404 void PerformanceBase::deliverObservationsTimerFired(Timer<PerformanceBase>*) |
| 405 { |
| 406 ASSERT(isMainThread()); |
| 407 PerformanceObserverVector observers; |
| 408 copyToVector(m_activeObservers, observers); |
| 409 m_activeObservers.clear(); |
| 410 for (size_t i = 0; i < observers.size(); ++i) { |
| 411 if (observers[i]->shouldBeSuspended()) |
| 412 m_suspendedObservers.add(observers[i]); |
| 413 else |
| 414 observers[i]->deliver(); |
| 415 } |
| 416 } |
| 417 |
| 326 double PerformanceBase::now() const | 418 double PerformanceBase::now() const |
| 327 { | 419 { |
| 328 double nowSeconds = monotonicallyIncreasingTime() - m_timeOrigin; | 420 double nowSeconds = monotonicallyIncreasingTime() - m_timeOrigin; |
| 329 const double resolutionSeconds = 0.000005; | 421 const double resolutionSeconds = 0.000005; |
| 330 return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds; | 422 return 1000.0 * floor(nowSeconds / resolutionSeconds) * resolutionSeconds; |
| 331 } | 423 } |
| 332 | 424 |
| 333 DEFINE_TRACE(PerformanceBase) | 425 DEFINE_TRACE(PerformanceBase) |
| 334 { | 426 { |
| 335 visitor->trace(m_frameTimingBuffer); | 427 visitor->trace(m_frameTimingBuffer); |
| 336 visitor->trace(m_resourceTimingBuffer); | 428 visitor->trace(m_resourceTimingBuffer); |
| 337 visitor->trace(m_userTiming); | 429 visitor->trace(m_userTiming); |
| 430 visitor->trace(m_observers); |
| 431 visitor->trace(m_activeObservers); |
| 432 visitor->trace(m_suspendedObservers); |
| 338 RefCountedGarbageCollectedEventTargetWithInlineData<PerformanceBase>::trace(
visitor); | 433 RefCountedGarbageCollectedEventTargetWithInlineData<PerformanceBase>::trace(
visitor); |
| 339 } | 434 } |
| 340 | 435 |
| 341 } // namespace blink | 436 } // namespace blink |
| OLD | NEW |