Chromium Code Reviews| Index: third_party/WebKit/Source/core/timing/Performance.cpp |
| diff --git a/third_party/WebKit/Source/core/timing/Performance.cpp b/third_party/WebKit/Source/core/timing/Performance.cpp |
| index 2bf1572d39744af76477cc2abd9896f37417d6d7..f9a33f19565d9f7f0f8f9ef553e1cacfe1672071 100644 |
| --- a/third_party/WebKit/Source/core/timing/Performance.cpp |
| +++ b/third_party/WebKit/Source/core/timing/Performance.cpp |
| @@ -35,11 +35,20 @@ |
| #include "bindings/core/v8/V8ObjectBuilder.h" |
| #include "core/dom/Document.h" |
| #include "core/frame/LocalFrame.h" |
| -#include "core/frame/PerformanceMonitor.h" |
| +#include "core/frame/UseCounter.h" |
| #include "core/loader/DocumentLoader.h" |
| #include "core/origin_trials/OriginTrials.h" |
| #include "core/timing/PerformanceTiming.h" |
| +static const double kLongTaskThreshold = 0.05; |
| + |
| +static const char kUnknownAttribution[] = "unknown"; |
| +static const char kAmbugiousAttribution[] = "multiple-contexts"; |
| +static const char kSameOriginAttribution[] = "same-origin"; |
| +static const char kAncestorAttribution[] = "cross-origin-ancestor"; |
| +static const char kDescendantAttribution[] = "cross-origin-descendant"; |
| +static const char kCrossOriginAttribution[] = "cross-origin-unreachable"; |
| + |
| namespace blink { |
| static double toTimeOrigin(LocalFrame* frame) { |
| @@ -60,15 +69,7 @@ static double toTimeOrigin(LocalFrame* frame) { |
| Performance::Performance(LocalFrame* frame) |
| : PerformanceBase(toTimeOrigin(frame)), DOMWindowProperty(frame) {} |
| -Performance::~Performance() { |
| - if (frame()) |
| - PerformanceMonitor::performanceObserverRemoved(this); |
| -} |
| - |
| -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.
|
| - PerformanceMonitor::performanceObserverRemoved(this); |
| - DOMWindowProperty::frameDestroyed(); |
| -} |
| +Performance::~Performance() {} |
| ExecutionContext* Performance::getExecutionContext() const { |
| if (!frame()) |
| @@ -99,13 +100,14 @@ void Performance::updateLongTaskInstrumentation() { |
| if (!frame()->document() || |
| !OriginTrials::longTaskObserverEnabled(frame()->document())) |
| return; |
| - LocalFrame* localRoot = frame()->localFrameRoot(); |
| - DCHECK(localRoot); |
| - if (hasObserverFor(PerformanceEntry::LongTask)) |
| - PerformanceMonitor::performanceObserverAdded(this); |
| - else |
| - PerformanceMonitor::performanceObserverRemoved(this); |
| + if (hasObserverFor(PerformanceEntry::LongTask)) { |
| + UseCounter::count(frame()->localFrameRoot(), UseCounter::LongTaskObserver); |
| + frame()->performanceMonitor()->subscribe(PerformanceMonitor::kLongTask, |
| + kLongTaskThreshold, this); |
| + } else { |
| + frame()->performanceMonitor()->unsubscribeAll(this); |
| + } |
| } |
| ScriptValue Performance::toJSONForBinding(ScriptState* scriptState) const { |
| @@ -120,6 +122,72 @@ DEFINE_TRACE(Performance) { |
| visitor->trace(m_timing); |
| DOMWindowProperty::trace(visitor); |
| PerformanceBase::trace(visitor); |
| + PerformanceMonitor::Client::trace(visitor); |
| +} |
| + |
| +static bool canAccessOrigin(Frame* frame1, Frame* frame2) { |
| + SecurityOrigin* securityOrigin1 = |
| + frame1->securityContext()->getSecurityOrigin(); |
| + SecurityOrigin* securityOrigin2 = |
| + frame2->securityContext()->getSecurityOrigin(); |
| + return securityOrigin1->canAccess(securityOrigin2); |
| +} |
| + |
| +/** |
| + * Report sanitized name based on cross-origin policy. |
| + * See detailed Security doc here: http://bit.ly/2duD3F7 |
| + */ |
| +// static |
| +std::pair<String, DOMWindow*> Performance::sanitizedAttribution( |
| + const HeapHashSet<Member<Frame>>& frames, |
| + Frame* observerFrame) { |
| + if (frames.size() == 0) { |
| + // Unable to attribute as no script was involved. |
| + return std::make_pair(kUnknownAttribution, nullptr); |
| + } |
| + if (frames.size() > 1) { |
| + // Unable to attribute, multiple script execution contents were involved. |
| + return std::make_pair(kAmbugiousAttribution, nullptr); |
| + } |
| + // Exactly one culprit location, attribute based on origin boundary. |
| + DCHECK_EQ(1u, frames.size()); |
| + Frame* culpritFrame = *frames.begin(); |
| + DCHECK(culpritFrame); |
| + if (canAccessOrigin(observerFrame, culpritFrame)) { |
| + // From accessible frames or same origin, return culprit location URL. |
| + return std::make_pair(kSameOriginAttribution, culpritFrame->domWindow()); |
| + } |
| + // For cross-origin, if the culprit is the descendant or ancestor of |
| + // observer then indicate the *closest* cross-origin frame between |
| + // the observer and the culprit, in the corresponding direction. |
| + if (culpritFrame->tree().isDescendantOf(observerFrame)) { |
| + // If the culprit is a descendant of the observer, then walk up the tree |
| + // from culprit to observer, and report the *last* cross-origin (from |
| + // observer) frame. If no intermediate cross-origin frame is found, then |
| + // report the culprit directly. |
| + Frame* lastCrossOriginFrame = culpritFrame; |
| + for (Frame* frame = culpritFrame; frame != observerFrame; |
| + frame = frame->tree().parent()) { |
| + if (!canAccessOrigin(observerFrame, frame)) { |
| + lastCrossOriginFrame = frame; |
| + } |
| + } |
| + return std::make_pair(kDescendantAttribution, |
| + lastCrossOriginFrame->domWindow()); |
| + } |
| + if (observerFrame->tree().isDescendantOf(culpritFrame)) { |
| + return std::make_pair(kAncestorAttribution, nullptr); |
| + } |
| + return std::make_pair(kCrossOriginAttribution, nullptr); |
| +} |
| + |
| +void Performance::reportLongTask( |
| + double startTime, |
| + double endTime, |
| + const HeapHashSet<Member<Frame>>& contextFrames) { |
| + std::pair<String, DOMWindow*> attribution = |
| + 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.
|
| + addLongTaskTiming(startTime, endTime, attribution.first, attribution.second); |
| } |
| } // namespace blink |