Chromium Code Reviews| Index: Source/core/timing/PerformanceBase.cpp |
| diff --git a/Source/core/timing/PerformanceBase.cpp b/Source/core/timing/PerformanceBase.cpp |
| index 219f3f5b51331991db0f63fb8f2a52bb9ffdd724..901d3d56ce9cfa61b8d78ec2c554b236fc64e01e 100644 |
| --- a/Source/core/timing/PerformanceBase.cpp |
| +++ b/Source/core/timing/PerformanceBase.cpp |
| @@ -35,6 +35,8 @@ |
| #include "core/dom/Document.h" |
| #include "core/events/Event.h" |
| #include "core/timing/PerformanceCompositeTiming.h" |
| +#include "core/timing/PerformanceObserver.h" |
| +#include "core/timing/PerformanceObserverRegistration.h" |
| #include "core/timing/PerformanceRenderTiming.h" |
| #include "core/timing/PerformanceResourceTiming.h" |
| #include "core/timing/PerformanceUserTiming.h" |
| @@ -47,6 +49,16 @@ namespace blink { |
| static const size_t defaultResourceTimingBufferSize = 150; |
| static const size_t defaultFrameTimingBufferSize = 150; |
| +// The order here has to match the order in PerformanceBase.h enum FilterType |
| +static const char* kFilterTypes[] = { |
| + "_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.
|
| + "composite", |
| + "mark", |
| + "measure", |
| + "render", |
| + "resource" |
| +}; |
| + |
| PerformanceBase::PerformanceBase(double timeOrigin) |
| : m_frameTimingBufferSize(defaultFrameTimingBufferSize) |
| , m_resourceTimingBufferSize(defaultResourceTimingBufferSize) |
| @@ -211,7 +223,7 @@ static bool allowsTimingRedirect(const Vector<ResourceResponse>& redirectChain, |
| void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) |
| { |
| - if (isResourceTimingBufferFull()) |
| + if (isResourceTimingBufferFull() && !hasObserverFor(Resource)) |
| return; |
| SecurityOrigin* securityOrigin = nullptr; |
| if (ExecutionContext* context = executionContext()) |
| @@ -244,7 +256,9 @@ void PerformanceBase::addResourceTiming(const ResourceTimingInfo& info) |
| double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd(); |
| PerformanceEntry* entry = PerformanceResourceTiming::create(info, timeOrigin(), startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails); |
| - addResourceTimingBuffer(entry); |
| + notifyObserversOfEntry(Resource, entry); |
| + if (!isResourceTimingBufferFull()) |
| + addResourceTimingBuffer(entry); |
| } |
| void PerformanceBase::addResourceTimingBuffer(PerformanceEntry* entry) |
| @@ -262,20 +276,24 @@ bool PerformanceBase::isResourceTimingBufferFull() |
| void PerformanceBase::addRenderTiming(Document* initiatorDocument, unsigned sourceFrame, double startTime, double finishTime) |
| { |
| - if (isFrameTimingBufferFull()) |
| + if (isFrameTimingBufferFull() && !hasObserverFor(Render)) |
| return; |
| PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument, sourceFrame, startTime, finishTime); |
| - addFrameTimingBuffer(entry); |
| + notifyObserversOfEntry(Render, entry); |
| + if (!isFrameTimingBufferFull()) |
| + addFrameTimingBuffer(entry); |
| } |
| void PerformanceBase::addCompositeTiming(Document* initiatorDocument, unsigned sourceFrame, double startTime) |
| { |
| - if (isFrameTimingBufferFull()) |
| + if (isFrameTimingBufferFull() && !hasObserverFor(Composite)) |
| return; |
| PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocument, sourceFrame, startTime); |
| - addFrameTimingBuffer(entry); |
| + notifyObserversOfEntry(Composite, entry); |
| + if (!isFrameTimingBufferFull()) |
| + addFrameTimingBuffer(entry); |
| } |
| void PerformanceBase::addFrameTimingBuffer(PerformanceEntry* entry) |
| @@ -295,7 +313,8 @@ void PerformanceBase::mark(const String& markName, ExceptionState& exceptionStat |
| { |
| if (!m_userTiming) |
| m_userTiming = UserTiming::create(this); |
| - m_userTiming->mark(markName, exceptionState); |
| + NewPerformanceEntryCallback callback = WTF::bind<PerformanceEntry*>(&PerformanceBase::notifyObserversOfEntry, this, Mark); |
| + m_userTiming->mark(markName, callback, exceptionState); |
| } |
| void PerformanceBase::clearMarks(const String& markName) |
| @@ -309,7 +328,8 @@ void PerformanceBase::measure(const String& measureName, const String& startMark |
| { |
| if (!m_userTiming) |
| m_userTiming = UserTiming::create(this); |
| - m_userTiming->measure(measureName, startMark, endMark, exceptionState); |
| + NewPerformanceEntryCallback callback = WTF::bind<PerformanceEntry*>(&PerformanceBase::notifyObserversOfEntry, this, Measure); |
| + m_userTiming->measure(measureName, startMark, endMark, callback, exceptionState); |
|
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
|
| } |
| void PerformanceBase::clearMeasures(const String& measureName) |
| @@ -319,6 +339,48 @@ void PerformanceBase::clearMeasures(const String& measureName) |
| m_userTiming->clearMeasures(measureName); |
| } |
| +void PerformanceBase::registerPerformanceObserver(PerformanceObserverRegistration* registration) |
| +{ |
| + 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
|
| + if (registration->shouldReceiveEntryFrom(kFilterTypes[filterIndex])) { |
| + PerformanceObserverRegistrations::AddResult result = m_observerRegistry.add(filterIndex, PerformanceObserverRegistrationVector()); |
| + 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
|
| + result.storedValue->value.append(registration); |
| + } |
| + } |
| +} |
| +PerformanceObserver* PerformanceBase::createPerformanceObserver(PerformanceObserverCallback* 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
|
| +{ |
| + return PerformanceObserver::create(this, callback); |
| +} |
| + |
| +void PerformanceBase::unregisterPerformanceObserver(PerformanceObserverRegistration* registration) |
| +{ |
| + for (auto& registry : m_observerRegistry) { |
| + 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.
|
| + if (index == kNotFound) |
| + continue; |
| + registration->dispose(); |
| + registry.value.remove(index); |
| + } |
| +} |
| + |
| +void PerformanceBase::notifyObserversOfEntry(FilterType filterType, PerformanceEntry* entry) |
| +{ |
| + PerformanceObserverRegistrations::iterator registry = m_observerRegistry.find(filterType); |
| + if (registry == m_observerRegistry.end()) |
| + return; |
| + for (auto& registration : *registry.values()) { |
| + registration->observer().enqueuePerformanceEntry(entry); |
| + } |
| +} |
| + |
| +bool PerformanceBase::hasObserverFor(FilterType filterType) |
| +{ |
| + PerformanceObserverRegistrations::iterator registry = m_observerRegistry.find(filterType); |
| + return registry != m_observerRegistry.end() && registry.values()->size(); |
| +} |
| + |
| double PerformanceBase::now() const |
| { |
| double nowSeconds = monotonicallyIncreasingTime() - m_timeOrigin; |
| @@ -331,6 +393,7 @@ DEFINE_TRACE(PerformanceBase) |
| visitor->trace(m_frameTimingBuffer); |
| visitor->trace(m_resourceTimingBuffer); |
| visitor->trace(m_userTiming); |
| + visitor->trace(m_observerRegistry); |
| EventTargetWithInlineData::trace(visitor); |
| } |