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

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

Issue 2484213003: Convert performance monitor to the subscription model. (Closed)
Patch Set: same Created 4 years, 1 month 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
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 17 matching lines...) Expand all
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 "core/timing/Performance.h" 32 #include "core/timing/Performance.h"
33 33
34 #include "bindings/core/v8/ScriptValue.h" 34 #include "bindings/core/v8/ScriptValue.h"
35 #include "bindings/core/v8/V8ObjectBuilder.h" 35 #include "bindings/core/v8/V8ObjectBuilder.h"
36 #include "core/dom/Document.h" 36 #include "core/dom/Document.h"
37 #include "core/frame/LocalFrame.h" 37 #include "core/frame/LocalFrame.h"
38 #include "core/frame/PerformanceMonitor.h" 38 #include "core/frame/UseCounter.h"
39 #include "core/loader/DocumentLoader.h" 39 #include "core/loader/DocumentLoader.h"
40 #include "core/origin_trials/OriginTrials.h" 40 #include "core/origin_trials/OriginTrials.h"
41 #include "core/timing/PerformanceTiming.h" 41 #include "core/timing/PerformanceTiming.h"
42 42
43 static const double kLongTaskThreshold = 0.05;
44
45 static const char kUnknownAttribution[] = "unknown";
46 static const char kAmbugiousAttribution[] = "multiple-contexts";
47 static const char kSameOriginAttribution[] = "same-origin";
48 static const char kAncestorAttribution[] = "cross-origin-ancestor";
49 static const char kDescendantAttribution[] = "cross-origin-descendant";
50 static const char kCrossOriginAttribution[] = "cross-origin-unreachable";
51
43 namespace blink { 52 namespace blink {
44 53
45 static double toTimeOrigin(LocalFrame* frame) { 54 static double toTimeOrigin(LocalFrame* frame) {
46 if (!frame) 55 if (!frame)
47 return 0.0; 56 return 0.0;
48 57
49 Document* document = frame->document(); 58 Document* document = frame->document();
50 if (!document) 59 if (!document)
51 return 0.0; 60 return 0.0;
52 61
53 DocumentLoader* loader = document->loader(); 62 DocumentLoader* loader = document->loader();
54 if (!loader) 63 if (!loader)
55 return 0.0; 64 return 0.0;
56 65
57 return loader->timing().referenceMonotonicTime(); 66 return loader->timing().referenceMonotonicTime();
58 } 67 }
59 68
60 Performance::Performance(LocalFrame* frame) 69 Performance::Performance(LocalFrame* frame)
61 : PerformanceBase(toTimeOrigin(frame)), DOMWindowProperty(frame) {} 70 : PerformanceBase(toTimeOrigin(frame)), DOMWindowProperty(frame) {}
62 71
63 Performance::~Performance() { 72 Performance::~Performance() {}
64 if (frame())
65 PerformanceMonitor::performanceObserverRemoved(this);
66 }
67
68 void Performance::frameDestroyed() {
caseq 2016/11/09 00:41:11 Shouldn't you unsubscribe when frame is gone?
pfeldman 2016/11/09 01:39:14 Done.
pfeldman 2016/11/09 01:39:14 Done.
69 PerformanceMonitor::performanceObserverRemoved(this);
70 DOMWindowProperty::frameDestroyed();
71 }
72 73
73 ExecutionContext* Performance::getExecutionContext() const { 74 ExecutionContext* Performance::getExecutionContext() const {
74 if (!frame()) 75 if (!frame())
75 return nullptr; 76 return nullptr;
76 return frame()->document(); 77 return frame()->document();
77 } 78 }
78 79
79 MemoryInfo* Performance::memory() { 80 MemoryInfo* Performance::memory() {
80 return MemoryInfo::create(); 81 return MemoryInfo::create();
81 } 82 }
(...skipping 10 matching lines...) Expand all
92 m_timing = PerformanceTiming::create(frame()); 93 m_timing = PerformanceTiming::create(frame());
93 94
94 return m_timing.get(); 95 return m_timing.get();
95 } 96 }
96 97
97 void Performance::updateLongTaskInstrumentation() { 98 void Performance::updateLongTaskInstrumentation() {
98 DCHECK(frame()); 99 DCHECK(frame());
99 if (!frame()->document() || 100 if (!frame()->document() ||
100 !OriginTrials::longTaskObserverEnabled(frame()->document())) 101 !OriginTrials::longTaskObserverEnabled(frame()->document()))
101 return; 102 return;
102 LocalFrame* localRoot = frame()->localFrameRoot();
103 DCHECK(localRoot);
104 103
105 if (hasObserverFor(PerformanceEntry::LongTask)) 104 if (hasObserverFor(PerformanceEntry::LongTask)) {
106 PerformanceMonitor::performanceObserverAdded(this); 105 UseCounter::count(frame()->localFrameRoot(), UseCounter::LongTaskObserver);
107 else 106 frame()->performanceMonitor()->subscribe(PerformanceMonitor::kLongTask,
108 PerformanceMonitor::performanceObserverRemoved(this); 107 kLongTaskThreshold, this);
108 } else {
109 frame()->performanceMonitor()->unsubscribeAll(this);
110 }
109 } 111 }
110 112
111 ScriptValue Performance::toJSONForBinding(ScriptState* scriptState) const { 113 ScriptValue Performance::toJSONForBinding(ScriptState* scriptState) const {
112 V8ObjectBuilder result(scriptState); 114 V8ObjectBuilder result(scriptState);
113 result.add("timing", timing()->toJSONForBinding(scriptState)); 115 result.add("timing", timing()->toJSONForBinding(scriptState));
114 result.add("navigation", navigation()->toJSONForBinding(scriptState)); 116 result.add("navigation", navigation()->toJSONForBinding(scriptState));
115 return result.scriptValue(); 117 return result.scriptValue();
116 } 118 }
117 119
118 DEFINE_TRACE(Performance) { 120 DEFINE_TRACE(Performance) {
119 visitor->trace(m_navigation); 121 visitor->trace(m_navigation);
120 visitor->trace(m_timing); 122 visitor->trace(m_timing);
121 DOMWindowProperty::trace(visitor); 123 DOMWindowProperty::trace(visitor);
122 PerformanceBase::trace(visitor); 124 PerformanceBase::trace(visitor);
125 PerformanceMonitor::Client::trace(visitor);
126 }
127
128 static bool canAccessOrigin(Frame* frame1, Frame* frame2) {
129 SecurityOrigin* securityOrigin1 =
130 frame1->securityContext()->getSecurityOrigin();
131 SecurityOrigin* securityOrigin2 =
132 frame2->securityContext()->getSecurityOrigin();
133 return securityOrigin1->canAccess(securityOrigin2);
134 }
135
136 /**
137 * Report sanitized name based on cross-origin policy.
138 * See detailed Security doc here: http://bit.ly/2duD3F7
139 */
140 // static
141 std::pair<String, DOMWindow*> Performance::sanitizedAttribution(
142 const HeapHashSet<Member<Frame>>& frames,
143 Frame* observerFrame) {
144 if (frames.size() == 0) {
145 // Unable to attribute as no script was involved.
146 return std::make_pair(kUnknownAttribution, nullptr);
147 }
148 if (frames.size() > 1) {
149 // Unable to attribute, multiple script execution contents were involved.
150 return std::make_pair(kAmbugiousAttribution, nullptr);
151 }
152 // Exactly one culprit location, attribute based on origin boundary.
153 DCHECK_EQ(1u, frames.size());
154 Frame* culpritFrame = *frames.begin();
155 DCHECK(culpritFrame);
156 if (canAccessOrigin(observerFrame, culpritFrame)) {
157 // From accessible frames or same origin, return culprit location URL.
158 return std::make_pair(kSameOriginAttribution, culpritFrame->domWindow());
159 }
160 // For cross-origin, if the culprit is the descendant or ancestor of
161 // observer then indicate the *closest* cross-origin frame between
162 // the observer and the culprit, in the corresponding direction.
163 if (culpritFrame->tree().isDescendantOf(observerFrame)) {
164 // If the culprit is a descendant of the observer, then walk up the tree
165 // from culprit to observer, and report the *last* cross-origin (from
166 // observer) frame. If no intermediate cross-origin frame is found, then
167 // report the culprit directly.
168 Frame* lastCrossOriginFrame = culpritFrame;
169 for (Frame* frame = culpritFrame; frame != observerFrame;
170 frame = frame->tree().parent()) {
171 if (!canAccessOrigin(observerFrame, frame)) {
172 lastCrossOriginFrame = frame;
173 }
174 }
175 return std::make_pair(kDescendantAttribution,
176 lastCrossOriginFrame->domWindow());
177 }
178 if (observerFrame->tree().isDescendantOf(culpritFrame)) {
179 return std::make_pair(kAncestorAttribution, nullptr);
180 }
181 return std::make_pair(kCrossOriginAttribution, nullptr);
182 }
183
184 void Performance::reportLongTask(
185 double startTime,
186 double endTime,
187 const HeapHashSet<Member<Frame>>& contextFrames) {
188 std::pair<String, DOMWindow*> attribution =
189 Performance::sanitizedAttribution(contextFrames, frame());
caseq 2016/11/09 00:41:12 frame() can be null here, right?
pfeldman 2016/11/09 01:39:14 Not anymore.
190 addLongTaskTiming(startTime, endTime, attribution.first, attribution.second);
123 } 191 }
124 192
125 } // namespace blink 193 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698