Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: Source/core/timing/Performance.cpp

Issue 1100813004: Offer User Timing in workers (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/timing/Performance.h ('k') | Source/core/timing/PerformanceBase.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 15 matching lines...) Expand all
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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/Performance.h" 33 #include "core/timing/Performance.h"
34 34
35 #include "core/dom/Document.h" 35 #include "core/dom/Document.h"
36 #include "core/events/Event.h"
37 #include "core/frame/LocalFrame.h" 36 #include "core/frame/LocalFrame.h"
38 #include "core/loader/DocumentLoader.h" 37 #include "core/loader/DocumentLoader.h"
39 #include "core/timing/PerformanceCompositeTiming.h"
40 #include "core/timing/PerformanceRenderTiming.h"
41 #include "core/timing/PerformanceResourceTiming.h"
42 #include "core/timing/PerformanceTiming.h" 38 #include "core/timing/PerformanceTiming.h"
43 #include "core/timing/PerformanceUserTiming.h"
44 #include "core/timing/ResourceTimingInfo.h"
45 #include "platform/weborigin/SecurityOrigin.h"
46 #include "wtf/CurrentTime.h"
47 39
48 namespace blink { 40 namespace blink {
49 41
50 static const size_t defaultResourceTimingBufferSize = 150;
51 static const size_t defaultFrameTimingBufferSize = 150;
52
53 Performance::Performance(LocalFrame* frame) 42 Performance::Performance(LocalFrame* frame)
54 : DOMWindowProperty(frame) 43 : PerformanceBase(frame && frame->host() ? frame->document()->loader()->timi ng().referenceMonotonicTime() : 0.0)
55 , m_frameTimingBufferSize(defaultFrameTimingBufferSize) 44 , DOMWindowProperty(frame)
56 , m_resourceTimingBufferSize(defaultResourceTimingBufferSize)
57 , m_referenceTime(frame && frame->host() ? frame->document()->loader()->timi ng().referenceMonotonicTime() : 0.0)
58 , m_userTiming(nullptr)
59 { 45 {
60 } 46 }
61 47
62 Performance::~Performance() 48 Performance::~Performance()
63 { 49 {
64 } 50 }
65 51
66 const AtomicString& Performance::interfaceName() const
67 {
68 return EventTargetNames::Performance;
69 }
70
71 ExecutionContext* Performance::executionContext() const 52 ExecutionContext* Performance::executionContext() const
72 { 53 {
73 if (!frame()) 54 if (!frame())
74 return nullptr; 55 return nullptr;
75 return frame()->document(); 56 return frame()->document();
76 } 57 }
77 58
78 MemoryInfo* Performance::memory() 59 MemoryInfo* Performance::memory()
79 { 60 {
80 if (!m_memoryInfo) 61 if (!m_memoryInfo)
(...skipping 10 matching lines...) Expand all
91 } 72 }
92 73
93 PerformanceTiming* Performance::timing() const 74 PerformanceTiming* Performance::timing() const
94 { 75 {
95 if (!m_timing) 76 if (!m_timing)
96 m_timing = PerformanceTiming::create(m_frame); 77 m_timing = PerformanceTiming::create(m_frame);
97 78
98 return m_timing.get(); 79 return m_timing.get();
99 } 80 }
100 81
101 PerformanceEntryVector Performance::getEntries() const
102 {
103 PerformanceEntryVector entries;
104
105 entries.appendVector(m_resourceTimingBuffer);
106 entries.appendVector(m_frameTimingBuffer);
107
108 if (m_userTiming) {
109 entries.appendVector(m_userTiming->getMarks());
110 entries.appendVector(m_userTiming->getMeasures());
111 }
112
113 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare LessThan);
114 return entries;
115 }
116
117 PerformanceEntryVector Performance::getEntriesByType(const String& entryType)
118 {
119 PerformanceEntryVector entries;
120
121 if (equalIgnoringCase(entryType, "resource")) {
122 for (const auto& resource : m_resourceTimingBuffer)
123 entries.append(resource);
124 }
125
126 if (equalIgnoringCase(entryType, "composite")
127 || equalIgnoringCase(entryType, "render")) {
128 for (const auto& frame : m_frameTimingBuffer) {
129 if (equalIgnoringCase(entryType, frame->entryType())) {
130 entries.append(frame);
131 }
132 }
133 }
134
135 if (m_userTiming) {
136 if (equalIgnoringCase(entryType, "mark"))
137 entries.appendVector(m_userTiming->getMarks());
138 else if (equalIgnoringCase(entryType, "measure"))
139 entries.appendVector(m_userTiming->getMeasures());
140 }
141
142 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare LessThan);
143 return entries;
144 }
145
146 PerformanceEntryVector Performance::getEntriesByName(const String& name, const S tring& entryType)
147 {
148 PerformanceEntryVector entries;
149
150 if (entryType.isNull() || equalIgnoringCase(entryType, "resource")) {
151 for (const auto& resource : m_resourceTimingBuffer) {
152 if (resource->name() == name)
153 entries.append(resource);
154 }
155 }
156
157 if (entryType.isNull() || equalIgnoringCase(entryType, "composite")
158 || equalIgnoringCase(entryType, "render")) {
159 for (const auto& frame : m_frameTimingBuffer) {
160 if (frame->name() == name && (entryType.isNull()
161 || equalIgnoringCase(entryType, frame->entryType()))) {
162 entries.append(frame);
163 }
164 }
165 }
166
167 if (m_userTiming) {
168 if (entryType.isNull() || equalIgnoringCase(entryType, "mark"))
169 entries.appendVector(m_userTiming->getMarks(name));
170 if (entryType.isNull() || equalIgnoringCase(entryType, "measure"))
171 entries.appendVector(m_userTiming->getMeasures(name));
172 }
173
174 std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompare LessThan);
175 return entries;
176 }
177
178 void Performance::webkitClearResourceTimings()
179 {
180 m_resourceTimingBuffer.clear();
181 }
182
183 void Performance::webkitSetResourceTimingBufferSize(unsigned size)
184 {
185 m_resourceTimingBufferSize = size;
186 if (isResourceTimingBufferFull())
187 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu ll));
188 }
189
190 void Performance::clearFrameTimings()
191 {
192 m_frameTimingBuffer.clear();
193 }
194
195 void Performance::setFrameTimingBufferSize(unsigned size)
196 {
197 m_frameTimingBufferSize = size;
198 if (isFrameTimingBufferFull())
199 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull));
200 }
201
202 static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r equestingDocument, const AtomicString& originalTimingAllowOrigin)
203 {
204 AtomicallyInitializedStaticReference(AtomicString, timingAllowOrigin, new At omicString("timing-allow-origin"));
205
206 RefPtr<SecurityOrigin> resourceOrigin = SecurityOrigin::create(response.url( ));
207 if (resourceOrigin->isSameSchemeHostPort(requestingDocument->securityOrigin( )))
208 return true;
209
210 const AtomicString& timingAllowOriginString = originalTimingAllowOrigin.isEm pty() ? response.httpHeaderField(timingAllowOrigin) : originalTimingAllowOrigin;
211 if (timingAllowOriginString.isEmpty() || equalIgnoringCase(timingAllowOrigin String, "null"))
212 return false;
213
214 if (timingAllowOriginString == starAtom)
215 return true;
216
217 const String& securityOrigin = requestingDocument->securityOrigin()->toStrin g();
218 Vector<String> timingAllowOrigins;
219 timingAllowOriginString.string().split(' ', timingAllowOrigins);
220 for (const String& allowOrigin : timingAllowOrigins) {
221 if (allowOrigin == securityOrigin)
222 return true;
223 }
224
225 return false;
226 }
227
228 static bool allowsTimingRedirect(const Vector<ResourceResponse>& redirectChain, const ResourceResponse& finalResponse, Document* initiatorDocument)
229 {
230 if (!passesTimingAllowCheck(finalResponse, initiatorDocument, emptyAtom))
231 return false;
232
233 for (const ResourceResponse& response : redirectChain) {
234 if (!passesTimingAllowCheck(response, initiatorDocument, emptyAtom))
235 return false;
236 }
237
238 return true;
239 }
240
241 void Performance::addResourceTiming(const ResourceTimingInfo& info, Document* in itiatorDocument)
242 {
243 if (isResourceTimingBufferFull())
244 return;
245
246 const ResourceResponse& finalResponse = info.finalResponse();
247 bool allowTimingDetails = passesTimingAllowCheck(finalResponse, initiatorDoc ument, info.originalTimingAllowOrigin());
248 double startTime = info.initialTime();
249
250 if (info.redirectChain().isEmpty()) {
251 PerformanceEntry* entry = PerformanceResourceTiming::create(info, initia torDocument, startTime, allowTimingDetails);
252 addResourceTimingBuffer(entry);
253 return;
254 }
255
256 const Vector<ResourceResponse>& redirectChain = info.redirectChain();
257 bool allowRedirectDetails = allowsTimingRedirect(redirectChain, finalRespons e, initiatorDocument);
258
259 if (!allowRedirectDetails) {
260 ResourceLoadTiming* finalTiming = finalResponse.resourceLoadTiming();
261 ASSERT(finalTiming);
262 if (finalTiming)
263 startTime = finalTiming->requestTime();
264 }
265
266 ResourceLoadTiming* lastRedirectTiming = redirectChain.last().resourceLoadTi ming();
267 ASSERT(lastRedirectTiming);
268 double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd();
269
270 PerformanceEntry* entry = PerformanceResourceTiming::create(info, initiatorD ocument, startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetail s);
271 addResourceTimingBuffer(entry);
272 }
273
274 void Performance::addResourceTimingBuffer(PerformanceEntry* entry)
275 {
276 m_resourceTimingBuffer.append(entry);
277
278 if (isResourceTimingBufferFull())
279 dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfu ll));
280 }
281
282 bool Performance::isResourceTimingBufferFull()
283 {
284 return m_resourceTimingBuffer.size() >= m_resourceTimingBufferSize;
285 }
286
287 void Performance::addRenderTiming(Document* initiatorDocument, unsigned sourceFr ame, double startTime, double finishTime)
288 {
289 if (isFrameTimingBufferFull())
290 return;
291
292 PerformanceEntry* entry = PerformanceRenderTiming::create(initiatorDocument, sourceFrame, startTime, finishTime);
293 addFrameTimingBuffer(entry);
294 }
295
296 void Performance::addCompositeTiming(Document* initiatorDocument, unsigned sourc eFrame, double startTime)
297 {
298 if (isFrameTimingBufferFull())
299 return;
300
301 PerformanceEntry* entry = PerformanceCompositeTiming::create(initiatorDocume nt, sourceFrame, startTime);
302 addFrameTimingBuffer(entry);
303 }
304
305 void Performance::addFrameTimingBuffer(PerformanceEntry* entry)
306 {
307 m_frameTimingBuffer.append(entry);
308
309 if (isFrameTimingBufferFull())
310 dispatchEvent(Event::create(EventTypeNames::frametimingbufferfull));
311 }
312
313 bool Performance::isFrameTimingBufferFull()
314 {
315 return m_frameTimingBuffer.size() >= m_frameTimingBufferSize;
316 }
317
318 void Performance::mark(const String& markName, ExceptionState& exceptionState)
319 {
320 if (!m_userTiming)
321 m_userTiming = UserTiming::create(this);
322 m_userTiming->mark(markName, exceptionState);
323 }
324
325 void Performance::clearMarks(const String& markName)
326 {
327 if (!m_userTiming)
328 m_userTiming = UserTiming::create(this);
329 m_userTiming->clearMarks(markName);
330 }
331
332 void Performance::measure(const String& measureName, const String& startMark, co nst String& endMark, ExceptionState& exceptionState)
333 {
334 if (!m_userTiming)
335 m_userTiming = UserTiming::create(this);
336 m_userTiming->measure(measureName, startMark, endMark, exceptionState);
337 }
338
339 void Performance::clearMeasures(const String& measureName)
340 {
341 if (!m_userTiming)
342 m_userTiming = UserTiming::create(this);
343 m_userTiming->clearMeasures(measureName);
344 }
345
346 double Performance::now() const
347 {
348 return 1000.0 * (monotonicallyIncreasingTime() - m_referenceTime);
349 }
350
351 DEFINE_TRACE(Performance) 82 DEFINE_TRACE(Performance)
352 { 83 {
353 visitor->trace(m_navigation); 84 visitor->trace(m_navigation);
354 visitor->trace(m_timing); 85 visitor->trace(m_timing);
355 visitor->trace(m_frameTimingBuffer);
356 visitor->trace(m_resourceTimingBuffer);
357 visitor->trace(m_memoryInfo); 86 visitor->trace(m_memoryInfo);
358 visitor->trace(m_userTiming);
359 EventTargetWithInlineData::trace(visitor);
360 DOMWindowProperty::trace(visitor); 87 DOMWindowProperty::trace(visitor);
88 PerformanceBase::trace(visitor);
361 } 89 }
362 90
363 } // namespace blink 91 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/timing/Performance.h ('k') | Source/core/timing/PerformanceBase.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698