summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/timing
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/timing')
-rw-r--r--chromium/third_party/blink/renderer/core/timing/DIR_METADATA5
-rw-r--r--chromium/third_party/blink/renderer/core/timing/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/core/timing/build.gni2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/event_timing.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h9
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift.h10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/OWNERS1
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc288
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h39
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc286
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h42
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl12
-rw-r--r--chromium/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl11
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.cc48
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.h15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance.idl2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_entry.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_entry.h3
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc13
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_event_timing.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h15
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_mark.h3
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_measure.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h3
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.cc37
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_timing.h16
-rw-r--r--chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.cc70
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.h2
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc104
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h6
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.cc74
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance.h23
-rw-r--r--chromium/third_party/blink/renderer/core/timing/window_performance_test.cc3
44 files changed, 631 insertions, 617 deletions
diff --git a/chromium/third_party/blink/renderer/core/timing/DIR_METADATA b/chromium/third_party/blink/renderer/core/timing/DIR_METADATA
new file mode 100644
index 00000000000..8f13e49a253
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/DIR_METADATA
@@ -0,0 +1,5 @@
+monorail {
+ component: "Blink>PerformanceAPIs"
+}
+
+team_email: "speed-metrics-dev@chromium.org"
diff --git a/chromium/third_party/blink/renderer/core/timing/OWNERS b/chromium/third_party/blink/renderer/core/timing/OWNERS
index afc8230f65f..9e3a2546556 100644
--- a/chromium/third_party/blink/renderer/core/timing/OWNERS
+++ b/chromium/third_party/blink/renderer/core/timing/OWNERS
@@ -1,4 +1 @@
npm@chromium.org
-
-# TEAM: speed-metrics-dev@chromium.org
-# COMPONENT: Blink>PerformanceAPIs
diff --git a/chromium/third_party/blink/renderer/core/timing/build.gni b/chromium/third_party/blink/renderer/core/timing/build.gni
index f0b692b53a3..016200a206b 100644
--- a/chromium/third_party/blink/renderer/core/timing/build.gni
+++ b/chromium/third_party/blink/renderer/core/timing/build.gni
@@ -17,8 +17,6 @@ blink_core_sources_timing = [
"layout_shift_attribution.h",
"measure_memory/measure_memory_controller.cc",
"measure_memory/measure_memory_controller.h",
- "measure_memory/measure_memory_delegate.cc",
- "measure_memory/measure_memory_delegate.h",
"memory_info.cc",
"memory_info.h",
"performance.cc",
diff --git a/chromium/third_party/blink/renderer/core/timing/event_timing.cc b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
index 3b3b1fa63b9..ad1207b4190 100644
--- a/chromium/third_party/blink/renderer/core/timing/event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/event_timing.cc
@@ -116,14 +116,6 @@ void EventTiming::DidDispatchEvent(const Event& event, Document& document) {
performance_->RegisterEventTiming(event.type(), event_timestamp_,
processing_start_, processing_end,
event.cancelable(), target);
- if (should_log_event_) {
- InteractiveDetector* interactive_detector =
- InteractiveDetector::From(document);
- if (interactive_detector) {
- interactive_detector->RecordInputEventTimingUKM(
- event, event_timestamp_, processing_start_, processing_end);
- }
- }
}
// static
diff --git a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
index bbebf97d0ca..97b66eb1e53 100644
--- a/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
+++ b/chromium/third_party/blink/renderer/core/timing/largest_contentful_paint.h
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -51,6 +52,14 @@ class CORE_EXPORT LargestContentfulPaint final : public PerformanceEntry {
WeakMember<Element> element_;
};
+template <>
+struct DowncastTraits<LargestContentfulPaint> {
+ static bool AllowFrom(const PerformanceEntry& entry) {
+ return entry.EntryTypeEnum() ==
+ PerformanceEntry::EntryType::kLargestContentfulPaint;
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_LARGEST_CONTENTFUL_PAINT_H_
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift.h b/chromium/third_party/blink/renderer/core/timing/layout_shift.h
index f20e951713e..fcf9987b5ca 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift.h
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift.h
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/timing/layout_shift_attribution.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
@@ -45,7 +46,7 @@ class CORE_EXPORT LayoutShift final : public PerformanceEntry {
bool hadRecentInput() const { return had_recent_input_; }
double lastInputTime() const { return most_recent_input_timestamp_; }
- AttributionList sources() const { return sources_; }
+ const AttributionList& sources() const { return sources_; }
void Trace(Visitor*) const override;
@@ -58,6 +59,13 @@ class CORE_EXPORT LayoutShift final : public PerformanceEntry {
AttributionList sources_;
};
+template <>
+struct DowncastTraits<LayoutShift> {
+ static bool AllowFrom(const PerformanceEntry& entry) {
+ return entry.EntryTypeEnum() == PerformanceEntry::EntryType::kLayoutShift;
+ }
+};
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_LAYOUT_SHIFT_H_
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
index 1da6afd1bf0..791652df91f 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
@@ -31,6 +31,10 @@ Node* LayoutShiftAttribution::node() const {
return Performance::CanExposeNode(node_) ? node_ : nullptr;
}
+Node* LayoutShiftAttribution::rawNodeForInspector() const {
+ return node_;
+}
+
DOMRectReadOnly* LayoutShiftAttribution::previousRect() const {
return previous_rect_;
}
diff --git a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
index 62fa9253d2e..8b4fef906ea 100644
--- a/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
+++ b/chromium/third_party/blink/renderer/core/timing/layout_shift_attribution.h
@@ -11,6 +11,7 @@
namespace blink {
class DOMRectReadOnly;
+class Node;
class ScriptState;
class ScriptValue;
@@ -27,6 +28,9 @@ class CORE_EXPORT LayoutShiftAttribution : public ScriptWrappable {
~LayoutShiftAttribution() override;
Node* node() const;
+ // Return node_ unconditionally, skipping the checks that apply
+ // to exposing it through bindings.
+ Node* rawNodeForInspector() const;
DOMRectReadOnly* previousRect() const;
DOMRectReadOnly* currentRect() const;
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/OWNERS b/chromium/third_party/blink/renderer/core/timing/measure_memory/OWNERS
new file mode 100644
index 00000000000..ccae9082083
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/OWNERS
@@ -0,0 +1 @@
+ulan@chromium.org
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
deleted file mode 100644
index d319cef8df4..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory.idl
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://github.com/WICG/performance-measure-memory
-
-// The result of performance.measureMemory().
-dictionary MeasureMemory {
- required unsigned long long bytes;
- required sequence<MeasureMemoryBreakdown> breakdown;
-};
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
deleted file mode 100644
index e90820e6bda..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_breakdown.idl
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// https://github.com/ulan/performance-measure-memory.
-
-// A single entry of performance.measureMemory() result.
-dictionary MeasureMemoryBreakdown {
- unsigned long long bytes;
- sequence<DOMString> attribution;
- sequence<DOMString> userAgentSpecificTypes;
-};
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
index 1a0aab598a2..3759664a803 100644
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.cc
@@ -4,38 +4,56 @@
#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h"
-#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h"
-
+#include <algorithm>
+#include "base/rand_util.h"
+#include "components/performance_manager/public/mojom/coordination_unit.mojom-blink.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_attribution.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_attribution_container.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_breakdown_entry.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_memory_measurement.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
+#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "v8/include/v8.h"
+using performance_manager::mojom::blink::WebMemoryAttribution;
+using performance_manager::mojom::blink::WebMemoryAttributionPtr;
+using performance_manager::mojom::blink::WebMemoryBreakdownEntryPtr;
+using performance_manager::mojom::blink::WebMemoryMeasurement;
+using performance_manager::mojom::blink::WebMemoryMeasurementPtr;
+using performance_manager::mojom::blink::WebMemoryUsagePtr;
+
namespace blink {
-static MeasureMemoryController::V8MemoryReporter*
- g_dedicated_worker_memory_reporter_ = nullptr;
+namespace {
-void MeasureMemoryController::SetDedicatedWorkerMemoryReporter(
- V8MemoryReporter* reporter) {
- g_dedicated_worker_memory_reporter_ = reporter;
-}
+// String constants used for building the result.
+constexpr const char* kCrossOriginUrl = "cross-origin-url";
+constexpr const char* kMemoryTypeDom = "DOM";
+constexpr const char* kMemoryTypeJavaScript = "JavaScript";
+constexpr const char* kMemoryTypeShared = "Shared";
+constexpr const char* kScopeCrossOriginAggregated = "cross-origin-aggregated";
+constexpr const char* kScopeDedicatedWorker = "DedicatedWorker";
+constexpr const char* kScopeWindow = "Window";
+
+} // anonymous namespace
MeasureMemoryController::MeasureMemoryController(
- util::PassKey<MeasureMemoryController>,
+ base::PassKey<MeasureMemoryController>,
v8::Isolate* isolate,
v8::Local<v8::Context> context,
v8::Local<v8::Promise::Resolver> promise_resolver)
@@ -51,17 +69,77 @@ MeasureMemoryController::MeasureMemoryController(
void MeasureMemoryController::Trace(Visitor* visitor) const {
visitor->Trace(promise_resolver_);
- visitor->Trace(main_result_);
- visitor->Trace(worker_result_);
}
+namespace {
+
+enum class ApiStatus {
+ kAvailable,
+ kNotAvailableDueToFlag,
+ kNotAvailableDueToDetachedContext,
+ kNotAvailableDueToCrossOriginContext,
+ kNotAvailableDueToCrossOriginIsolation,
+ kNotAvailableDueToResourceCoordinator,
+};
+
+ApiStatus CheckMeasureMemoryAvailability(LocalDOMWindow* window) {
+ if (!base::FeatureList::IsEnabled(
+ features::kWebMeasureMemoryViaPerformanceManager)) {
+ return ApiStatus::kNotAvailableDueToFlag;
+ }
+ if (!window) {
+ return ApiStatus::kNotAvailableDueToDetachedContext;
+ }
+ LocalFrame* local_frame = window->GetFrame();
+ if (!local_frame) {
+ return ApiStatus::kNotAvailableDueToDetachedContext;
+ }
+ if (!window->CrossOriginIsolatedCapability() &&
+ local_frame->GetSettings()->GetWebSecurityEnabled()) {
+ return ApiStatus::kNotAvailableDueToCrossOriginIsolation;
+ }
+
+ // We need DocumentResourceCoordinator to query PerformanceManager.
+ if (!window->document()) {
+ return ApiStatus::kNotAvailableDueToDetachedContext;
+ }
+
+ if (!window->document()->GetResourceCoordinator()) {
+ return ApiStatus::kNotAvailableDueToResourceCoordinator;
+ }
+
+ return ApiStatus::kAvailable;
+}
+
+} // anonymous namespace
+
ScriptPromise MeasureMemoryController::StartMeasurement(
ScriptState* script_state,
ExceptionState& exception_state) {
- if (!IsMeasureMemoryAvailable(LocalDOMWindow::From(script_state))) {
- exception_state.ThrowSecurityError(
- "performance.measureMemory is not available in this context");
- return ScriptPromise();
+ switch (auto status = CheckMeasureMemoryAvailability(
+ LocalDOMWindow::From(script_state))) {
+ case ApiStatus::kAvailable:
+ break;
+ case ApiStatus::kNotAvailableDueToFlag:
+ case ApiStatus::kNotAvailableDueToResourceCoordinator:
+ exception_state.ThrowSecurityError(
+ "performance.measureUserAgentSpecificMemory is not available.");
+ return ScriptPromise();
+ case ApiStatus::kNotAvailableDueToDetachedContext:
+ exception_state.ThrowSecurityError(
+ "performance.measureUserAgentSpecificMemory is not supported"
+ " in detached iframes.");
+ return ScriptPromise();
+ case ApiStatus::kNotAvailableDueToCrossOriginContext:
+ exception_state.ThrowSecurityError(
+ "performance.measureUserAgentSpecificMemory is not supported"
+ " in cross-origin iframes.");
+ return ScriptPromise();
+ case ApiStatus::kNotAvailableDueToCrossOriginIsolation:
+ exception_state.ThrowSecurityError(
+ "performance.measureUserAgentSpecificMemory requires"
+ " cross-origin isolation.");
+ return ScriptPromise();
}
v8::Isolate* isolate = script_state->GetIsolate();
v8::TryCatch try_catch(isolate);
@@ -71,73 +149,143 @@ ScriptPromise MeasureMemoryController::StartMeasurement(
exception_state.RethrowV8Exception(try_catch.Exception());
return ScriptPromise();
}
- v8::MeasureMemoryExecution execution =
+ auto measurement_mode =
RuntimeEnabledFeatures::ForceEagerMeasureMemoryEnabled(
ExecutionContext::From(script_state))
- ? v8::MeasureMemoryExecution::kEager
- : v8::MeasureMemoryExecution::kDefault;
+ ? WebMemoryMeasurement::Mode::kEager
+ : WebMemoryMeasurement::Mode::kDefault;
auto* impl = MakeGarbageCollected<MeasureMemoryController>(
- util::PassKey<MeasureMemoryController>(), isolate, context,
+ base::PassKey<MeasureMemoryController>(), isolate, context,
promise_resolver);
+ Document* document = LocalDOMWindow::From(script_state)->document();
+ document->GetResourceCoordinator()->OnWebMemoryMeasurementRequested(
+ measurement_mode, WTF::Bind(&MeasureMemoryController::MeasurementComplete,
+ WrapPersistent(impl)));
- isolate->MeasureMemory(
- std::make_unique<MeasureMemoryDelegate>(
- isolate, context,
- WTF::Bind(&MeasureMemoryController::MainMeasurementComplete,
- WrapPersistent(impl))),
- execution);
- if (g_dedicated_worker_memory_reporter_) {
- g_dedicated_worker_memory_reporter_->GetMemoryUsage(
- WTF::Bind(&MeasureMemoryController::WorkerMeasurementComplete,
- WrapPersistent(impl)),
-
- execution);
- } else {
- HeapVector<Member<MeasureMemoryBreakdown>> result;
- impl->WorkerMeasurementComplete(result);
- }
return ScriptPromise(script_state, promise_resolver->GetPromise());
}
-bool MeasureMemoryController::IsMeasureMemoryAvailable(LocalDOMWindow* window) {
- // TODO(ulan): We should check for window.crossOriginIsolated when it ships.
- // Until then we enable the API only for processes locked to a site
- // similar to the precise mode of the legacy performance.memory API.
- if (!Platform::Current()->IsLockedToSite()) {
- return false;
+
+namespace {
+
+// Satisfies the requirements of UniformRandomBitGenerator from C++ standard.
+// It is used in std::shuffle calls below.
+struct RandomBitGenerator {
+ using result_type = size_t;
+ static constexpr size_t min() { return 0; }
+ static constexpr size_t max() {
+ return static_cast<size_t>(std::numeric_limits<int>::max());
+ }
+ size_t operator()() {
+ return static_cast<size_t>(base::RandInt(min(), max()));
+ }
+};
+
+// These functions convert WebMemory* mojo structs to IDL and JS values.
+WTF::AtomicString ConvertScope(WebMemoryAttribution::Scope scope) {
+ using Scope = WebMemoryAttribution::Scope;
+ switch (scope) {
+ case Scope::kDedicatedWorker:
+ return kScopeDedicatedWorker;
+ case Scope::kWindow:
+ return kScopeWindow;
+ case Scope::kCrossOriginAggregated:
+ return kScopeCrossOriginAggregated;
+ }
+}
+
+MemoryAttributionContainer* ConvertContainer(
+ const WebMemoryAttributionPtr& attribution) {
+ if (!attribution->src && !attribution->id) {
+ return nullptr;
}
- // The window.crossOriginIsolated will be true only for the top-level frame.
- // Until the flag is available we check for the top-level condition manually.
- if (!window) {
- return false;
+ auto* result = MemoryAttributionContainer::Create();
+ result->setSrc(attribution->src);
+ result->setId(attribution->id);
+ return result;
+}
+
+MemoryAttribution* ConvertAttribution(
+ const WebMemoryAttributionPtr& attribution) {
+ auto* result = MemoryAttribution::Create();
+ if (attribution->url) {
+ result->setUrl(attribution->url);
+ } else {
+ result->setUrl(kCrossOriginUrl);
}
- LocalFrame* local_frame = window->GetFrame();
- if (!local_frame || !local_frame->IsMainFrame()) {
- return false;
+ result->setScope(ConvertScope(attribution->scope));
+ result->setContainer(ConvertContainer(attribution));
+ return result;
+}
+
+MemoryBreakdownEntry* ConvertBreakdown(
+ const WebMemoryBreakdownEntryPtr& breakdown_entry) {
+ auto* result = MemoryBreakdownEntry::Create();
+ DCHECK(breakdown_entry->memory);
+ result->setBytes(breakdown_entry->memory->bytes);
+ HeapVector<Member<MemoryAttribution>> attribution;
+ for (const auto& entry : breakdown_entry->attribution) {
+ attribution.push_back(ConvertAttribution(entry));
}
- return true;
+ result->setAttribution(attribution);
+ result->setTypes({WTF::AtomicString(kMemoryTypeJavaScript)});
+ return result;
}
-void MeasureMemoryController::MainMeasurementComplete(Result result) {
- DCHECK(!main_measurement_completed_);
- main_result_ = result;
- main_measurement_completed_ = true;
- MaybeResolvePromise();
+MemoryBreakdownEntry* CreateUnattributedBreakdown(
+ const WebMemoryUsagePtr& memory,
+ const WTF::String& memory_type) {
+ auto* result = MemoryBreakdownEntry::Create();
+ DCHECK(memory);
+ result->setBytes(memory->bytes);
+ result->setAttribution({});
+ Vector<String> types;
+ types.push_back(memory_type);
+ result->setTypes(types);
+ return result;
}
-void MeasureMemoryController::WorkerMeasurementComplete(Result result) {
- DCHECK(!worker_measurement_completed_);
- worker_result_ = result;
- worker_measurement_completed_ = true;
- MaybeResolvePromise();
+MemoryBreakdownEntry* EmptyBreakdown() {
+ auto* result = MemoryBreakdownEntry::Create();
+ result->setBytes(0);
+ result->setAttribution({});
+ result->setTypes({});
+ return result;
}
-void MeasureMemoryController::MaybeResolvePromise() {
- if (!main_measurement_completed_ || !worker_measurement_completed_) {
- // Wait until we have all results.
- return;
+MemoryMeasurement* ConvertResult(const WebMemoryMeasurementPtr& measurement) {
+ HeapVector<Member<MemoryBreakdownEntry>> breakdown;
+ for (const auto& entry : measurement->breakdown) {
+ // Skip breakdowns that didn't get a measurement.
+ if (entry->memory)
+ breakdown.push_back(ConvertBreakdown(entry));
}
+ // Add breakdowns for memory that isn't attributed to an execution context.
+ breakdown.push_back(CreateUnattributedBreakdown(measurement->shared_memory,
+ kMemoryTypeShared));
+ breakdown.push_back(
+ CreateUnattributedBreakdown(measurement->blink_memory, kMemoryTypeDom));
+ // TODO(1085129): Report memory usage of detached frames once implemented.
+ // Add an empty breakdown entry as required by the spec.
+ // See https://github.com/WICG/performance-measure-memory/issues/10.
+ breakdown.push_back(EmptyBreakdown());
+ // Randomize the order of the entries as required by the spec.
+ std::shuffle(breakdown.begin(), breakdown.end(), RandomBitGenerator{});
+ size_t bytes = 0;
+ for (auto entry : breakdown) {
+ bytes += entry->bytes();
+ }
+ auto* result = MemoryMeasurement::Create();
+ result->setBreakdown(breakdown);
+ result->setBytes(bytes);
+ return result;
+}
+
+} // anonymous namespace
+
+void MeasureMemoryController::MeasurementComplete(
+ WebMemoryMeasurementPtr measurement) {
if (context_.IsEmpty()) {
// The context was garbage collected in the meantime.
return;
@@ -145,15 +293,7 @@ void MeasureMemoryController::MaybeResolvePromise() {
v8::HandleScope handle_scope(isolate_);
v8::Local<v8::Context> context = context_.NewLocal(isolate_);
v8::Context::Scope context_scope(context);
- MeasureMemory* result = MeasureMemory::Create();
- auto breakdown = main_result_;
- breakdown.AppendVector(worker_result_);
- size_t total_size = 0;
- for (auto entry : breakdown) {
- total_size += entry->bytes();
- }
- result->setBytes(total_size);
- result->setBreakdown(breakdown);
+ auto* result = ConvertResult(measurement);
v8::Local<v8::Promise::Resolver> promise_resolver =
promise_resolver_.NewLocal(isolate_);
promise_resolver->Resolve(context, ToV8(result, promise_resolver, isolate_))
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
index 6a59e0c99b3..b20ab9ed6ff 100644
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h
@@ -5,7 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_CONTROLLER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_CONTROLLER_H_
-#include "base/util/type_safety/pass_key.h"
+#include "base/types/pass_key.h"
+#include "components/performance_manager/public/mojom/coordination_unit.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
@@ -16,12 +17,10 @@
namespace blink {
-class LocalDOMWindow;
-class MeasureMemoryBreakdown;
class ScriptState;
class ExceptionState;
-// The implementation of Performance.measureMemory() Web API.
+// The implementation of performance.measureUserAgentSpecificMemory() Web API.
// It is responsible for:
// 1. Starting an asynchronous memory measurement of the main V8 isolate.
// 2. Starting an asynchronous memory measurement of dedicated workers.
@@ -30,24 +29,9 @@ class ExceptionState;
class MeasureMemoryController final
: public GarbageCollected<MeasureMemoryController> {
public:
- using Result = HeapVector<Member<MeasureMemoryBreakdown>>;
- using ResultCallback = base::OnceCallback<void(Result)>;
-
- // PerformanceManager in blink/renderer/controller uses this interface
- // to provide an implementation of memory measurement for dedicated workers.
- //
- // It will be removed in the future when performance.measureMemory switches
- // to a mojo-based implementation that queries PerformanceManager in the
- // browser process.
- class V8MemoryReporter {
- public:
- virtual void GetMemoryUsage(MeasureMemoryController::ResultCallback,
- v8::MeasureMemoryExecution) = 0;
- };
-
// Private constructor guarded by PassKey. Use the StartMeasurement() wrapper
// to construct the object and start the measurement.
- MeasureMemoryController(util::PassKey<MeasureMemoryController>,
+ MeasureMemoryController(base::PassKey<MeasureMemoryController>,
v8::Isolate*,
v8::Local<v8::Context>,
v8::Local<v8::Promise::Resolver>);
@@ -58,25 +42,14 @@ class MeasureMemoryController final
void Trace(Visitor* visitor) const;
- // The entry point for injecting dependency on PerformanceManager.
- CORE_EXPORT static void SetDedicatedWorkerMemoryReporter(V8MemoryReporter*);
-
private:
- static bool IsMeasureMemoryAvailable(LocalDOMWindow* window);
// Invoked when the memory of the main V8 isolate is measured.
- void MainMeasurementComplete(Result);
- // Invoked when the memory of all dedicated workers is measured.
- void WorkerMeasurementComplete(Result);
- // Resolves the JS promise if both pending measurements are done.
- void MaybeResolvePromise();
+ void MeasurementComplete(
+ performance_manager::mojom::blink::WebMemoryMeasurementPtr);
v8::Isolate* isolate_;
ScopedPersistent<v8::Context> context_;
TraceWrapperV8Reference<v8::Promise::Resolver> promise_resolver_;
- Result main_result_;
- Result worker_result_;
- bool main_measurement_completed_ = false;
- bool worker_measurement_completed_ = false;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
deleted file mode 100644
index 28f6202d87e..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.cc
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h"
-
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/web/web_frame.h"
-#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_measure_memory_breakdown.h"
-#include "third_party/blink/renderer/core/dom/document.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/core/frame/frame.h"
-#include "third_party/blink/renderer/core/frame/frame_owner.h"
-#include "third_party/blink/renderer/core/frame/local_dom_window.h"
-#include "third_party/blink/renderer/core/frame/local_frame.h"
-#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
-#include "third_party/blink/renderer/platform/bindings/script_state.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
-
-namespace blink {
-
-MeasureMemoryDelegate::MeasureMemoryDelegate(v8::Isolate* isolate,
- v8::Local<v8::Context> context,
- ResultCallback callback)
- : isolate_(isolate),
- context_(isolate, context),
- callback_(std::move(callback)) {
- context_.SetPhantom();
-}
-
-// Returns true if the given context should be included in the current memory
-// measurement. Currently it is very conservative and allows only the same
-// origin contexts that belong to the same JavaScript origin.
-// With COOP/COEP we will be able to relax this restriction for the contexts
-// that opt-in into memory measurement.
-bool MeasureMemoryDelegate::ShouldMeasure(v8::Local<v8::Context> context) {
- if (context_.IsEmpty()) {
- // The original context was garbage collected in the meantime.
- return false;
- }
- v8::Local<v8::Context> original_context = context_.NewLocal(isolate_);
- ExecutionContext* original_execution_context =
- ExecutionContext::From(original_context);
- ExecutionContext* execution_context = ExecutionContext::From(context);
- if (!original_execution_context || !execution_context) {
- // One of the contexts is detached or is created by DevTools.
- return false;
- }
- if (original_execution_context->GetAgent() != execution_context->GetAgent()) {
- // Context do not belong to the same JavaScript agent.
- return false;
- }
- if (ScriptState::From(context)->World().IsIsolatedWorld()) {
- // Context belongs to an extension. Skip it.
- return false;
- }
- const SecurityOrigin* original_security_origin =
- original_execution_context->GetSecurityContext().GetSecurityOrigin();
- const SecurityOrigin* security_origin =
- execution_context->GetSecurityContext().GetSecurityOrigin();
- if (!original_security_origin->IsSameOriginWith(security_origin)) {
- // TODO(ulan): Check for COOP/COEP and allow cross-origin contexts that
- // opted in for memory measurement.
- // Until then we allow cross-origin measurement only for site-isolated
- // web pages.
- return Platform::Current()->IsLockedToSite();
- }
- return true;
-}
-
-namespace {
-// Helper functions for constructing a memory measurement result.
-
-LocalFrame* GetLocalFrame(v8::Local<v8::Context> context) {
- LocalDOMWindow* window = ToLocalDOMWindow(context);
- if (!window) {
- // The context was detached. Ignore it.
- return nullptr;
- }
- return window->GetFrame();
-}
-
-// Returns true if all frames on the path from the main frame to
-// the given frame (excluding the given frame) have the same origin.
-bool AllAncestorsAndOpenersAreSameOrigin(const WebFrame* main_frame,
- const WebFrame* frame) {
- while (frame != main_frame) {
- frame = frame->Parent() ? frame->Parent() : frame->Opener();
- if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
- return false;
- }
- return true;
-}
-
-// Returns the URL corresponding to the given frame. It is:
-// - document's URL if the frame is a same-origin top frame.
-// - the src attribute of the owner iframe element if the frame is
-// an iframe.
-// - nullopt, otherwise.
-// Preconditions:
-// - If the frame is cross-origin, then all its ancestors/openers
-// must be of the same origin as the main frame.
-// - The frame must be attached to the DOM tree and the main frame
-// must be reachable via child => parent and openee => opener edges.
-String GetUrl(const WebFrame* main_frame, const WebFrame* frame) {
- DCHECK(AllAncestorsAndOpenersAreSameOrigin(main_frame, frame));
- if (!frame->Parent()) {
- // TODO(ulan): Turn this conditional into a DCHECK once the API
- // is gated behind COOP+COEP. Only same-origin frames can appear here.
- if (!main_frame->GetSecurityOrigin().CanAccess(frame->GetSecurityOrigin()))
- return {};
- // The frame must be local because it is in the same browsing context
- // group as the main frame and has the same origin.
- // Check to avoid memory corruption in the case if our invariant is off.
- CHECK(IsA<LocalFrame>(WebFrame::ToCoreFrame(*frame)));
- LocalFrame* local = To<LocalFrame>(WebFrame::ToCoreFrame(*frame));
- return local->GetDocument()->Url().GetString();
- }
- FrameOwner* frame_owner = WebFrame::ToCoreFrame(*frame)->Owner();
- // The frame owner must be local because the parent of the frame has
- // the same origin as the main frame. Also the frame cannot be provisional
- // here because it is attached and has a document.
- // Check to avoid of memory corruption in the case if our invariant is off.
- CHECK(IsA<HTMLFrameOwnerElement>(frame_owner));
- HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(frame_owner);
- switch (owner_element->OwnerType()) {
- case mojom::blink::FrameOwnerElementType::kIframe:
- return owner_element->getAttribute(html_names::kSrcAttr);
- case mojom::blink::FrameOwnerElementType::kObject:
- case mojom::blink::FrameOwnerElementType::kEmbed:
- case mojom::blink::FrameOwnerElementType::kFrame:
- case mojom::blink::FrameOwnerElementType::kPortal:
- // TODO(ulan): return the data/src attribute after adding tests.
- return {};
- case mojom::blink::FrameOwnerElementType::kNone:
- // The main frame was handled as a local frame above.
- NOTREACHED();
- return {};
- }
-}
-
-// To avoid information leaks cross-origin iframes are considered opaque for
-// the purposes of attribution. This means the memory of all iframes nested
-// in a cross-origin iframe is attributed to the cross-origin iframe.
-// See https://github.com/WICG/performance-measure-memory for more details.
-//
-// Given the main frame and a frame, this function find the first cross-origin
-// frame in the path from the main frame to the given frame. Edges in the path
-// are parent/child and opener/openee edges.
-// If the path doesn't exist then it returns nullptr.
-// If there are no cross-origin frames, then it returns the given frame.
-//
-// Precondition: the frame must be attached to the DOM tree.
-const WebFrame* GetAttributionFrame(const WebFrame* main_frame,
- const WebFrame* frame) {
- WebSecurityOrigin main_security_origin = main_frame->GetSecurityOrigin();
- // Walk up the tree and the openers to find the first cross-origin frame
- // on the path from the main frame to the given frame.
- const WebFrame* result = frame;
- while (frame != main_frame) {
- if (frame->Parent()) {
- frame = frame->Parent();
- } else if (frame->Opener()) {
- frame = frame->Opener();
- } else {
- // The opener was reset. We cannot get the attribution.
- return nullptr;
- }
- if (!main_security_origin.CanAccess(frame->GetSecurityOrigin()))
- result = frame;
- }
- // The result frame must be attached because we started from an attached
- // frame (precondition) and followed the parent and opener references until
- // the main frame, which is also attached.
- DCHECK(WebFrame::ToCoreFrame(*result)->IsAttached());
- return result;
-}
-
-// Return per-frame sizes based on the given per-context size.
-// TODO(ulan): Revisit this after Origin Trial and see if the results
-// are precise enough or if we need to additionally group by JS agent.
-HashMap<const WebFrame*, size_t> GroupByFrame(
- const WebFrame* main_frame,
- const std::vector<std::pair<v8::Local<v8::Context>, size_t>>& context_sizes,
- size_t& detached_size,
- size_t& unknown_frame_size) {
- detached_size = 0;
- unknown_frame_size = 0;
- HashMap<const WebFrame*, size_t> per_frame;
- for (const auto& context_size : context_sizes) {
- const WebFrame* frame =
- WebFrame::FromFrame(GetLocalFrame(context_size.first));
- if (!frame) {
- detached_size += context_size.second;
- continue;
- }
- frame = GetAttributionFrame(main_frame, frame);
- if (!frame) {
- unknown_frame_size += context_size.second;
- continue;
- }
- auto it = per_frame.find(frame);
- if (it == per_frame.end()) {
- per_frame.insert(frame, context_size.second);
- } else {
- it->value += context_size.second;
- }
- }
- return per_frame;
-}
-
-MeasureMemoryBreakdown* CreateMeasureMemoryBreakdown(
- size_t bytes,
- const Vector<String>& types,
- const String& url) {
- MeasureMemoryBreakdown* result = MeasureMemoryBreakdown::Create();
- result->setBytes(bytes);
- result->setUserAgentSpecificTypes(types);
- result->setAttribution(url.length() ? Vector<String>{url} : Vector<String>());
- return result;
-}
-
-} // anonymous namespace
-
-// Constructs a memory measurement result based on the given list of (context,
-// size) pairs and resolves the promise.
-void MeasureMemoryDelegate::MeasurementComplete(
- const std::vector<std::pair<v8::Local<v8::Context>, size_t>>& context_sizes,
- size_t unattributed_size) {
- if (context_.IsEmpty()) {
- // The context was garbage collected in the meantime.
- return;
- }
- v8::Local<v8::Context> context = context_.NewLocal(isolate_);
- const WebFrame* main_frame = WebFrame::FromFrame(GetLocalFrame(context));
- if (!main_frame) {
- // The context was detached in the meantime.
- return;
- }
- DCHECK(!main_frame->Parent());
- v8::Context::Scope context_scope(context);
- size_t total_size = 0;
- for (const auto& context_size : context_sizes) {
- total_size += context_size.second;
- }
- HeapVector<Member<MeasureMemoryBreakdown>> breakdown;
- size_t detached_size;
- size_t unknown_frame_size;
- HashMap<const WebFrame*, size_t> per_frame(GroupByFrame(
- main_frame, context_sizes, detached_size, unknown_frame_size));
- size_t attributed_size = 0;
- const String kWindow("Window");
- const String kJS("JS");
- const Vector<String> js_window_types = {kWindow, kJS};
- for (const auto& it : per_frame) {
- String url = GetUrl(main_frame, it.key);
- if (url.IsNull()) {
- unknown_frame_size += it.value;
- continue;
- }
- attributed_size += it.value;
- breakdown.push_back(
- CreateMeasureMemoryBreakdown(it.value, js_window_types, url));
- }
- if (detached_size) {
- const String kDetached("Detached");
- breakdown.push_back(CreateMeasureMemoryBreakdown(
- detached_size, Vector<String>{kWindow, kJS, kDetached}, ""));
- }
- if (unattributed_size) {
- const String kShared("Shared");
- breakdown.push_back(CreateMeasureMemoryBreakdown(
- unattributed_size, Vector<String>{kWindow, kJS, kShared}, ""));
- }
- if (unknown_frame_size) {
- breakdown.push_back(CreateMeasureMemoryBreakdown(
- unknown_frame_size, Vector<String>{kWindow, kJS}, ""));
- }
- std::move(callback_).Run(breakdown);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h b/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
deleted file mode 100644
index 23a1100784f..00000000000
--- a/chromium/third_party/blink/renderer/core/timing/measure_memory/measure_memory_delegate.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
-
-#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class MeasureMemoryBreakdown;
-
-// Specifies V8 contexts to be measured and invokes the given callback once V8
-// completes the memory measurement.
-class MeasureMemoryDelegate : public v8::MeasureMemoryDelegate {
- public:
- using ResultCallback =
- base::OnceCallback<void(HeapVector<Member<MeasureMemoryBreakdown>>)>;
-
- MeasureMemoryDelegate(v8::Isolate* isolate,
- v8::Local<v8::Context> context,
- ResultCallback callback);
-
- // v8::MeasureMemoryDelegate overrides.
- bool ShouldMeasure(v8::Local<v8::Context> context) override;
- void MeasurementComplete(
- const std::vector<std::pair<v8::Local<v8::Context>, size_t>>&
- context_sizes,
- size_t unattributed_size) override;
- private:
- v8::Isolate* isolate_;
- ScopedPersistent<v8::Context> context_;
- ResultCallback callback_;
-};
-
-} // namespace blink
-
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_MEASURE_MEMORY_MEASURE_MEMORY_DELEGATE_H_
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl
new file mode 100644
index 00000000000..5a8d9c27bb4
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl
@@ -0,0 +1,12 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memoryattribution
+
+// Describes a context to which the memory was attributed.
+dictionary MemoryAttribution {
+ required USVString url;
+ MemoryAttributionContainer container;
+ required DOMString scope;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl
new file mode 100644
index 00000000000..bb47082f790
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl
@@ -0,0 +1,11 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memoryattribution
+
+// The attributes of the container iframe element.
+dictionary MemoryAttributionContainer {
+ DOMString id;
+ USVString src;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl
new file mode 100644
index 00000000000..e3461faef8e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl
@@ -0,0 +1,12 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memorybreakdownentry
+
+// A single entry of performance.measureUserAgentSpecificMemory() result.
+dictionary MemoryBreakdownEntry {
+ required unsigned long long bytes;
+ required sequence<MemoryAttribution> attribution;
+ required sequence<DOMString> types;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl
new file mode 100644
index 00000000000..0f8feeb5797
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl
@@ -0,0 +1,11 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://wicg.github.io/performance-measure-memory/#dictdef-memorymeasurement
+
+// The result of performance.measureUserAgentSpecificMemory().
+dictionary MemoryMeasurement {
+ required unsigned long long bytes;
+ required sequence<MemoryBreakdownEntry> breakdown;
+};
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.cc b/chromium/third_party/blink/renderer/core/timing/performance.cc
index 3f732b25d25..fb00b62a386 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance.cc
@@ -36,6 +36,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
+#include "third_party/blink/public/mojom/feature_policy/document_policy_feature.mojom-blink.h"
#include "third_party/blink/public/mojom/timing/worker_timing_container.mojom-blink-forward.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
@@ -52,9 +53,11 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/document_load_timing.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/timing/largest_contentful_paint.h"
#include "third_party/blink/renderer/core/timing/layout_shift.h"
#include "third_party/blink/renderer/core/timing/measure_memory/measure_memory_controller.h"
@@ -150,7 +153,7 @@ EventCounts* Performance::eventCounts() {
return nullptr;
}
-ScriptPromise Performance::measureMemory(
+ScriptPromise Performance::measureUserAgentSpecificMemory(
ScriptState* script_state,
ExceptionState& exception_state) const {
return MeasureMemoryController::StartMeasurement(script_state,
@@ -532,6 +535,7 @@ mojom::blink::ResourceTimingInfoPtr Performance::GenerateResourceTiming(
result->encoded_body_size = final_response.EncodedBodyLength();
result->decoded_body_size = final_response.DecodedBodyLength();
result->did_reuse_connection = final_response.ConnectionReused();
+ // TODO(crbug.com/1153336) Use network::IsUrlPotentiallyTrustworthy().
result->is_secure_context =
SecurityOrigin::IsSecure(final_response.ResponseUrl());
result->allow_negative_values = info.NegativeAllowed();
@@ -631,11 +635,13 @@ void Performance::AddEventTimingBuffer(PerformanceEventTiming& entry) {
}
void Performance::AddLayoutShiftBuffer(LayoutShift& entry) {
+ probe::PerformanceEntryAdded(GetExecutionContext(), &entry);
if (layout_shift_buffer_.size() < kDefaultLayoutShiftBufferSize)
layout_shift_buffer_.push_back(&entry);
}
void Performance::AddLargestContentfulPaint(LargestContentfulPaint* entry) {
+ probe::PerformanceEntryAdded(GetExecutionContext(), entry);
if (largest_contentful_paint_buffer_.size() <
kDefaultLargestContenfulPaintSize) {
largest_contentful_paint_buffer_.push_back(entry);
@@ -672,13 +678,18 @@ void Performance::AddLongTaskTiming(base::TimeTicks start_time,
base::TimeTicks end_time,
const AtomicString& name,
const AtomicString& container_type,
- const String& container_src,
- const String& container_id,
- const String& container_name) {
+ const AtomicString& container_src,
+ const AtomicString& container_id,
+ const AtomicString& container_name) {
+ double dom_high_res_start_time =
+ MonotonicTimeToDOMHighResTimeStamp(start_time);
auto* entry = MakeGarbageCollected<PerformanceLongTaskTiming>(
- MonotonicTimeToDOMHighResTimeStamp(start_time),
- MonotonicTimeToDOMHighResTimeStamp(end_time), name, container_type,
- container_src, container_id, container_name);
+ dom_high_res_start_time,
+ // Convert the delta between start and end times to an int to reduce the
+ // granularity of the duration to 1 ms.
+ static_cast<int>(MonotonicTimeToDOMHighResTimeStamp(end_time) -
+ dom_high_res_start_time),
+ name, container_type, container_src, container_id, container_name);
if (longtask_buffer_.size() < kDefaultLongTaskBufferSize) {
longtask_buffer_.push_back(entry);
} else {
@@ -861,7 +872,26 @@ ScriptPromise Performance::profile(ScriptState* script_state,
DCHECK(
RuntimeEnabledFeatures::ExperimentalJSProfilerEnabled(execution_context));
- if (!execution_context->CrossOriginIsolatedCapability()) {
+ if (!GetExecutionContext()->IsFeatureEnabled(
+ mojom::blink::DocumentPolicyFeature::kJSProfiling,
+ ReportOptions::kReportOnFailure)) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kNotAllowedError,
+ "JS profiling is disabled by Document Policy.");
+ return ScriptPromise();
+ }
+
+ // Bypass COOP/COEP checks when the |--disable-web-security| flag is present.
+ bool web_security_enabled = true;
+ if (LocalDOMWindow* window = LocalDOMWindow::From(script_state)) {
+ if (LocalFrame* local_frame = window->GetFrame()) {
+ web_security_enabled =
+ local_frame->GetSettings()->GetWebSecurityEnabled();
+ }
+ }
+
+ if (web_security_enabled &&
+ !execution_context->CrossOriginIsolatedCapability()) {
exception_state.ThrowSecurityError(
"performance.profile() requires COOP+COEP (web.dev/coop-coep)");
return ScriptPromise();
@@ -1029,6 +1059,8 @@ void Performance::Trace(Visitor* visitor) const {
visitor->Trace(observers_);
visitor->Trace(active_observers_);
visitor->Trace(suspended_observers_);
+ visitor->Trace(deliver_observations_timer_);
+ visitor->Trace(resource_timing_buffer_full_timer_);
EventTargetWithInlineData::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.h b/chromium/third_party/blink/renderer/core/timing/performance.h
index 8609a2a87b9..65898ea8131 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance.h
@@ -97,8 +97,9 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
virtual PerformanceTiming* timing() const;
virtual PerformanceNavigation* navigation() const;
virtual MemoryInfo* memory() const;
- virtual ScriptPromise measureMemory(ScriptState*,
- ExceptionState& exception_state) const;
+ virtual ScriptPromise measureUserAgentSpecificMemory(
+ ScriptState*,
+ ExceptionState& exception_state) const;
virtual EventCounts* eventCounts();
// Reduce the resolution to prevent timing attacks. See:
@@ -159,9 +160,9 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
base::TimeTicks end_time,
const AtomicString& name,
const AtomicString& container_type,
- const String& container_src,
- const String& container_id,
- const String& container_name);
+ const AtomicString& container_src,
+ const AtomicString& container_id,
+ const AtomicString& container_name);
// Generates and add a performance entry for the given ResourceTimingInfo.
// |overridden_initiator_type| allows the initiator type to be overridden to
@@ -388,8 +389,8 @@ class CORE_EXPORT Performance : public EventTargetWithInlineData {
HeapLinkedHashSet<Member<PerformanceObserver>> active_observers_;
HeapLinkedHashSet<Member<PerformanceObserver>> suspended_observers_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- TaskRunnerTimer<Performance> deliver_observations_timer_;
- TaskRunnerTimer<Performance> resource_timing_buffer_full_timer_;
+ HeapTaskRunnerTimer<Performance> deliver_observations_timer_;
+ HeapTaskRunnerTimer<Performance> resource_timing_buffer_full_timer_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance.idl b/chromium/third_party/blink/renderer/core/timing/performance.idl
index 4939cad8a26..44502c55e83 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance.idl
+++ b/chromium/third_party/blink/renderer/core/timing/performance.idl
@@ -67,7 +67,7 @@ interface Performance : EventTarget {
// https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
[Exposed=Window, Measure] readonly attribute MemoryInfo memory;
- [MeasureAs=MeasureMemory, Exposed=Window, CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MeasureMemory> measureMemory();
+ [MeasureAs=MeasureMemory, Exposed=Window, CallWith=ScriptState, RuntimeEnabled=MeasureMemory, RaisesException] Promise<MemoryMeasurement> measureUserAgentSpecificMemory();
// JS Self-Profiling API
// https://github.com/WICG/js-self-profiling/
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_entry.cc b/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
index cda5624b9a0..8fe854540da 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -50,6 +50,16 @@ PerformanceEntry::PerformanceEntry(const AtomicString& name,
start_time_(start_time),
index_(index_seq.GetNext()) {}
+PerformanceEntry::PerformanceEntry(double duration,
+ const AtomicString& name,
+ double start_time)
+ : duration_(duration),
+ name_(name),
+ start_time_(start_time),
+ index_(index_seq.GetNext()) {
+ DCHECK_GE(duration_, 0.0);
+}
+
PerformanceEntry::~PerformanceEntry() = default;
DOMHighResTimeStamp PerformanceEntry::startTime() const {
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_entry.h b/chromium/third_party/blink/renderer/core/timing/performance_entry.h
index 82e50edb3e7..59679f11c16 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_entry.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_entry.h
@@ -124,6 +124,9 @@ class CORE_EXPORT PerformanceEntry : public ScriptWrappable {
PerformanceEntry(const AtomicString& name,
double start_time,
double finish_time);
+ PerformanceEntry(double duration,
+ const AtomicString& name,
+ double start_time);
virtual void BuildJSONValue(V8ObjectBuilder&) const;
// Protected and not const because PerformanceEventTiming needs to modify it.
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
index a5723822a4f..5777ecd3fd7 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/performance_entry_names.h"
#include "third_party/blink/renderer/core/timing/performance.h"
+#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
namespace blink {
@@ -85,7 +86,6 @@ void PerformanceEventTiming::BuildJSONValue(V8ObjectBuilder& builder) const {
builder.AddNumber("processingStart", processingStart());
builder.AddNumber("processingEnd", processingEnd());
builder.AddBoolean("cancelable", cancelable_);
- builder.Add("target", target());
}
void PerformanceEventTiming::Trace(Visitor* visitor) const {
@@ -93,4 +93,15 @@ void PerformanceEventTiming::Trace(Visitor* visitor) const {
visitor->Trace(target_);
}
+std::unique_ptr<TracedValue> PerformanceEventTiming::ToTracedValue() const {
+ auto traced_value = std::make_unique<TracedValue>();
+ traced_value->SetString("type", name());
+ traced_value->SetInteger("timeStamp", startTime());
+ traced_value->SetInteger("processingStart", processingStart());
+ traced_value->SetInteger("processingEnd", processingEnd());
+ traced_value->SetInteger("duration", duration());
+ traced_value->SetBoolean("cancelable", cancelable());
+ return traced_value;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
index 78560ef5ed2..cf689f84da5 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_event_timing.h
@@ -51,6 +51,8 @@ class CORE_EXPORT PerformanceEventTiming final : public PerformanceEntry {
void Trace(Visitor*) const override;
+ std::unique_ptr<TracedValue> ToTracedValue() const;
+
private:
AtomicString entry_type_;
DOMHighResTimeStamp processing_start_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
index 83ced4ebcb9..a901c81bf14 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -15,13 +15,13 @@ namespace blink {
PerformanceLongTaskTiming::PerformanceLongTaskTiming(
double start_time,
- double end_time,
+ int duration,
const AtomicString& name,
const AtomicString& culprit_type,
- const String& culprit_src,
- const String& culprit_id,
- const String& culprit_name)
- : PerformanceEntry(name, start_time, end_time) {
+ const AtomicString& culprit_src,
+ const AtomicString& culprit_id,
+ const AtomicString& culprit_name)
+ : PerformanceEntry(duration, name, start_time) {
auto* attribution_entry = MakeGarbageCollected<TaskAttributionTiming>(
"unknown", culprit_type, culprit_src, culprit_id, culprit_name);
attribution_.push_back(*attribution_entry);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
index 8dd3530ebcb..fb000654c81 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_long_task_timing.h
@@ -19,13 +19,18 @@ class PerformanceLongTaskTiming final : public PerformanceEntry {
DEFINE_WRAPPERTYPEINFO();
public:
+ // This constructor uses int for |duration| on purpose: to avoid exposing a
+ // high resolution value in its entry. Having it be int ensures 1 ms
+ // granularity, even though it is ultimately stored as a double in
+ // PerformanceEntry.
PerformanceLongTaskTiming(double start_time,
- double end_time,
+ int duration,
const AtomicString& name,
const AtomicString& culprit_type,
- const String& culprit_src,
- const String& culprit_id,
- const String& culprit_name);
+ const AtomicString& culprit_src,
+ const AtomicString& culprit_id,
+ const AtomicString& culprit_name);
+ ~PerformanceLongTaskTiming() override;
AtomicString entryType() const override;
PerformanceEntryType EntryTypeEnum() const override;
@@ -35,8 +40,6 @@ class PerformanceLongTaskTiming final : public PerformanceEntry {
void Trace(Visitor*) const override;
private:
- ~PerformanceLongTaskTiming() override;
-
void BuildJSONValue(V8ObjectBuilder&) const override;
TaskAttributionVector attribution_;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_mark.h b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
index 2ae62a7e5f0..ea3a65062fa 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_mark.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_mark.h
@@ -58,6 +58,7 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
double start_time,
scoped_refptr<SerializedScriptValue>,
ExceptionState& exception_state);
+ ~PerformanceMark() override = default;
AtomicString entryType() const override;
PerformanceEntryType EntryTypeEnum() const override;
@@ -69,8 +70,6 @@ class CORE_EXPORT PerformanceMark final : public PerformanceEntry {
void Trace(Visitor*) const override;
private:
- ~PerformanceMark() override = default;
-
scoped_refptr<SerializedScriptValue> serialized_detail_;
// In order to prevent cross-world reference leak, we create a copy of the
// detail for each world.
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_measure.h b/chromium/third_party/blink/renderer/core/timing/performance_measure.h
index f1258ced973..862b24de3fd 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_measure.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_measure.h
@@ -49,6 +49,7 @@ class CORE_EXPORT PerformanceMeasure final : public PerformanceEntry {
double end_time,
scoped_refptr<SerializedScriptValue>,
ExceptionState&);
+ ~PerformanceMeasure() override = default;
static PerformanceMeasure* Create(ScriptState*,
const AtomicString& name,
@@ -67,7 +68,6 @@ class CORE_EXPORT PerformanceMeasure final : public PerformanceEntry {
void Trace(Visitor* visitor) const override;
private:
- ~PerformanceMeasure() override = default;
scoped_refptr<SerializedScriptValue> serialized_detail_;
// In order to prevent cross-world reference leak, we create a copy of the
// detail for each world.
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
index de84bfd7ab6..441620f5276 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
@@ -55,6 +55,7 @@ PerformanceNavigationTiming::PerformanceNavigationTiming(
info->FinalResponse().CurrentRequestUrl().GetString())
: g_empty_atom,
time_origin,
+ // TODO(crbug.com/1153336) Use network::IsUrlPotentiallyTrustworthy().
SecurityOrigin::IsSecure(window->Url()),
std::move(server_timing),
window),
@@ -166,7 +167,7 @@ DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventStart() const {
DocumentLoadTiming* timing = GetDocumentLoadTiming();
if (!allow_redirect_details || !timing ||
- !timing->HasSameOriginAsPreviousDocument())
+ !timing->CanRequestFromPreviousDocument())
return 0;
return Performance::MonotonicTimeToDOMHighResTimeStamp(
TimeOrigin(), timing->UnloadEventStart(),
@@ -178,7 +179,7 @@ DOMHighResTimeStamp PerformanceNavigationTiming::unloadEventEnd() const {
DocumentLoadTiming* timing = GetDocumentLoadTiming();
if (!allow_redirect_details || !timing ||
- !timing->HasSameOriginAsPreviousDocument())
+ !timing->CanRequestFromPreviousDocument())
return 0;
return Performance::MonotonicTimeToDOMHighResTimeStamp(
TimeOrigin(), timing->UnloadEventEnd(), false /* allow_negative_value */);
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
index c566ccb134b..22eb990a25e 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_navigation_timing.h
@@ -35,6 +35,7 @@ class CORE_EXPORT PerformanceNavigationTiming final
ResourceTimingInfo*,
base::TimeTicks time_origin,
HeapVector<Member<PerformanceServerTiming>>);
+ ~PerformanceNavigationTiming() override;
// Attributes inherited from PerformanceEntry.
DOMHighResTimeStamp duration() const override;
@@ -67,8 +68,6 @@ class CORE_EXPORT PerformanceNavigationTiming final
void BuildJSONValue(V8ObjectBuilder&) const override;
private:
- ~PerformanceNavigationTiming() override;
-
static AtomicString GetNavigationType(WebNavigationType, const Document*);
const DocumentTiming* GetDocumentTiming() const;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_test.cc b/chromium/third_party/blink/renderer/core/timing/performance_test.cc
index d423813523f..ac07945835e 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_test.cc
@@ -45,6 +45,8 @@ class TestPerformance : public Performance {
class PerformanceTest : public PageTestBase {
protected:
+ ~PerformanceTest() override { execution_context_->NotifyContextDestroyed(); }
+
void Initialize(ScriptState* script_state) {
v8::Local<v8::Function> callback =
v8::Function::New(script_state->GetContext(), nullptr).ToLocalChecked();
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
index e297230e2e1..589a2514be7 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.cc
@@ -85,7 +85,7 @@ uint64_t PerformanceTiming::unloadEventStart() const {
return 0;
if (timing->HasCrossOriginRedirect() ||
- !timing->HasSameOriginAsPreviousDocument())
+ !timing->CanRequestFromPreviousDocument())
return 0;
return MonotonicTimeToIntegerMilliseconds(timing->UnloadEventStart());
@@ -97,7 +97,7 @@ uint64_t PerformanceTiming::unloadEventEnd() const {
return 0;
if (timing->HasCrossOriginRedirect() ||
- !timing->HasSameOriginAsPreviousDocument())
+ !timing->CanRequestFromPreviousDocument())
return 0;
return MonotonicTimeToIntegerMilliseconds(timing->UnloadEventEnd());
@@ -482,6 +482,15 @@ uint64_t PerformanceTiming::ExperimentalLargestTextPaintSize() const {
return paint_timing_detector->ExperimentalLargestTextPaintSize();
}
+base::TimeTicks PerformanceTiming::LargestContentfulPaintAsMonotonicTime()
+ const {
+ PaintTimingDetector* paint_timing_detector = GetPaintTimingDetector();
+ if (!paint_timing_detector)
+ return base::TimeTicks();
+
+ return paint_timing_detector->LargestContentfulPaint();
+}
+
uint64_t PerformanceTiming::FirstEligibleToPaint() const {
const PaintTiming* timing = GetPaintTiming();
if (!timing)
@@ -624,6 +633,30 @@ base::Optional<base::TimeTicks> PerformanceTiming::LastPortalActivatedPaint()
return timing->LastPortalActivatedPaint();
}
+base::Optional<base::TimeTicks> PerformanceTiming::UnloadStart() const {
+ DocumentLoadTiming* timing = GetDocumentLoadTiming();
+ if (!timing)
+ return base::nullopt;
+
+ return timing->UnloadEventStart();
+}
+
+base::Optional<base::TimeTicks> PerformanceTiming::UnloadEnd() const {
+ DocumentLoadTiming* timing = GetDocumentLoadTiming();
+ if (!timing)
+ return base::nullopt;
+
+ return timing->UnloadEventEnd();
+}
+
+base::Optional<base::TimeTicks> PerformanceTiming::CommitNavigationEnd() const {
+ DocumentLoadTiming* timing = GetDocumentLoadTiming();
+ if (!timing)
+ return base::nullopt;
+
+ return timing->CommitNavigationEnd();
+}
+
DocumentLoader* PerformanceTiming::GetDocumentLoader() const {
return DomWindow() ? DomWindow()->GetFrame()->Loader().GetDocumentLoader()
: nullptr;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_timing.h b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
index 2d210014755..8afad757e2d 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/performance_timing.h
@@ -97,12 +97,13 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
uint64_t loadEventStart() const;
uint64_t loadEventEnd() const;
- // The below are non-spec timings, for Page Load UMA metrics.
+ // The below are non-spec timings, for Page Load UMA metrics. Not to be
+ // exposed to JavaScript.
// The time immediately after the user agent finishes prompting to unload the
// previous document, or if there is no previous document, the same value as
// fetchStart. Intended to be used for correlation with other events internal
- // to blink. Not to be exposed to JavaScript.
+ // to blink.
base::TimeTicks NavigationStartAsMonotonicTime() const;
// The timings after the page is restored from back-forward cache.
BackForwardCacheRestoreTimings BackForwardCacheRestore() const;
@@ -114,8 +115,7 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// that includes content of some kind (for example, text or image content).
uint64_t FirstContentfulPaint() const;
// The first 'contentful' paint as full-resolution monotonic time. Intended to
- // be used for correlation with other events internal to blink. Not to be
- // exposed to JavaScript.
+ // be used for correlation with other events internal to blink.
base::TimeTicks FirstContentfulPaintAsMonotonicTime() const;
// The time of the first 'meaningful' paint, A meaningful paint is a paint
// where the page's primary content is visible.
@@ -138,6 +138,9 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
// are the time and size of it.
uint64_t LargestTextPaint() const;
uint64_t LargestTextPaintSize() const;
+ // Largest Contentful Paint is the either the largest text paint time or the
+ // largest image paint time, whichever has the larger size.
+ base::TimeTicks LargestContentfulPaintAsMonotonicTime() const;
// Experimental versions of the above metrics. Currently these are computed by
// considering the largest content seen so far, regardless of DOM node
// removal.
@@ -169,6 +172,11 @@ class CORE_EXPORT PerformanceTiming final : public ScriptWrappable,
base::Optional<base::TimeDelta> FirstScrollDelay() const;
// The hardware timestamp of the first scroll.
base::Optional<base::TimeDelta> FirstScrollTimestamp() const;
+ // TimeTicks for unload start and end.
+ base::Optional<base::TimeTicks> UnloadStart() const;
+ base::Optional<base::TimeTicks> UnloadEnd() const;
+ // The timestamp of when the commit navigation finished in the frame loader.
+ base::Optional<base::TimeTicks> CommitNavigationEnd() const;
uint64_t ParseStart() const;
uint64_t ParseStop() const;
diff --git a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
index e4aa78261c8..05da2ae0e57 100644
--- a/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/performance_user_timing.cc
@@ -42,11 +42,11 @@ void InsertPerformanceEntry(PerformanceEntryMap& performance_entry_map,
PerformanceEntryMap::iterator it = performance_entry_map.find(entry.name());
if (it != performance_entry_map.end()) {
DCHECK(it->value);
- it->value->push_back(entry);
+ it->value->push_back(&entry);
} else {
PerformanceEntryVector* vector =
MakeGarbageCollected<PerformanceEntryVector>();
- vector->push_back(entry);
+ vector->push_back(&entry);
performance_entry_map.Set(entry.name(), vector);
}
}
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
index 4404ed897f1..790ebdc3311 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -90,34 +90,50 @@ Profiler* ProfilerGroup::CreateProfiler(ScriptState* script_state,
: v8::CpuProfilingOptions::kNoSampleLimit,
static_cast<int>(sample_interval_us));
- cpu_profiler_->StartProfiling(V8String(isolate_, profiler_id), options);
-
- // Limit non-crossorigin script frames to the origin that started the
- // profiler.
- auto* execution_context = ExecutionContext::From(script_state);
- scoped_refptr<const SecurityOrigin> source_origin(
- execution_context->GetSecurityOrigin());
-
- // The V8 CPU profiler ticks in multiples of the base sampling interval. This
- // effectively means that we gather samples at the multiple of the base
- // sampling interval that's greater than or equal to the requested interval.
- int effective_sample_interval_ms =
- static_cast<int>(sample_interval.InMilliseconds());
- if (effective_sample_interval_ms % kBaseSampleIntervalMs != 0 ||
- effective_sample_interval_ms == 0) {
- effective_sample_interval_ms +=
- (kBaseSampleIntervalMs -
- effective_sample_interval_ms % kBaseSampleIntervalMs);
+ v8::CpuProfilingStatus status =
+ cpu_profiler_->StartProfiling(V8String(isolate_, profiler_id), options);
+
+ switch (status) {
+ case v8::CpuProfilingStatus::kErrorTooManyProfilers: {
+ exception_state.ThrowTypeError(
+ "Reached maximum concurrent amount of profilers");
+ return nullptr;
+ }
+ case v8::CpuProfilingStatus::kAlreadyStarted: {
+ // Since we increment the profiler id for every invocation of
+ // StartProfiling, we do not expect to hit kAlreadyStarted status
+ DCHECK(false);
+ return nullptr;
+ }
+ case v8::CpuProfilingStatus::kStarted: {
+ // Limit non-crossorigin script frames to the origin that started the
+ // profiler.
+ auto* execution_context = ExecutionContext::From(script_state);
+ scoped_refptr<const SecurityOrigin> source_origin(
+ execution_context->GetSecurityOrigin());
+
+ // The V8 CPU profiler ticks in multiples of the base sampling interval.
+ // This effectively means that we gather samples at the multiple of the
+ // base sampling interval that's greater than or equal to the requested
+ // interval.
+ int effective_sample_interval_ms =
+ static_cast<int>(sample_interval.InMilliseconds());
+ if (effective_sample_interval_ms % kBaseSampleIntervalMs != 0 ||
+ effective_sample_interval_ms == 0) {
+ effective_sample_interval_ms +=
+ (kBaseSampleIntervalMs -
+ effective_sample_interval_ms % kBaseSampleIntervalMs);
+ }
+
+ auto* profiler = MakeGarbageCollected<Profiler>(
+ this, script_state, profiler_id, effective_sample_interval_ms,
+ source_origin, time_origin);
+ profilers_.insert(profiler);
+
+ num_active_profilers_++;
+ return profiler;
+ }
}
-
- auto* profiler = MakeGarbageCollected<Profiler>(
- this, script_state, profiler_id, effective_sample_interval_ms,
- source_origin, time_origin);
- profilers_.insert(profiler);
-
- num_active_profilers_++;
-
- return profiler;
}
ProfilerGroup::~ProfilerGroup() {
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.h b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
index c775f27c1be..da540b773de 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.h
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
@@ -53,7 +53,7 @@ class CORE_EXPORT ProfilerGroup
// Cancels a profiler, discarding its associated trace.
void CancelProfiler(Profiler*);
- // Asynchronously cancels a profiler. Invoked on Profiler descrution.
+ // Asynchronously cancels a profiler. Invoked on Profiler destruction.
void CancelProfilerAsync(ScriptState*, Profiler*);
// Internal implementation of cancel.
void CancelProfilerImpl(String profiler_id);
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc b/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
index c0af8fdd41c..eb477f3852b 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group_test.cc
@@ -16,25 +16,10 @@ namespace blink {
namespace {
static constexpr int kLargeProfilerCount = 128;
+static constexpr int kMaxConcurrentProfilerCount = 100;
} // namespace
-// Tests that a leaked profiler doesn't crash the isolate on heap teardown.
-TEST(ProfilerGroupTest, LeakProfiler) {
- V8TestingScope scope;
-
- ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
-
- ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
- init_options->setSampleInterval(0);
- init_options->setMaxBufferSize(0);
- Profiler* profiler = profiler_group->CreateProfiler(
- scope.GetScriptState(), *init_options, base::TimeTicks(),
- scope.GetExceptionState());
-
- EXPECT_FALSE(profiler->stopped());
-}
-
TEST(ProfilerGroupTest, StopProfiler) {
V8TestingScope scope;
@@ -83,6 +68,9 @@ TEST(ProfilerGroupTest, CreateProfiler) {
EXPECT_FALSE(profiler->stopped());
EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+ // clean up
+ profiler->stop(scope.GetScriptState());
}
TEST(ProfilerGroupTest, ClampedSamplingIntervalZero) {
@@ -102,6 +90,9 @@ TEST(ProfilerGroupTest, ClampedSamplingIntervalZero) {
// interval.
EXPECT_EQ(profiler->sampleInterval(),
ProfilerGroup::GetBaseSampleInterval().InMilliseconds());
+
+ // clean up
+ profiler->stop(scope.GetScriptState());
}
TEST(ProfilerGroupTest, ClampedSamplingIntervalNext) {
@@ -123,6 +114,42 @@ TEST(ProfilerGroupTest, ClampedSamplingIntervalNext) {
// interval.
EXPECT_EQ(profiler->sampleInterval(),
(ProfilerGroup::GetBaseSampleInterval() * 2).InMilliseconds());
+
+ // clean up
+ profiler->stop(scope.GetScriptState());
+}
+
+TEST(ProfilerGroupTest, V8ProfileLimitThrowsExceptionWhenMaxConcurrentReached) {
+ V8TestingScope scope;
+
+ HeapVector<Member<Profiler>> profilers;
+ ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
+ ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
+
+ for (auto i = 0; i < kMaxConcurrentProfilerCount; i++) {
+ init_options->setSampleInterval(i);
+ profilers.push_back(profiler_group->CreateProfiler(
+ scope.GetScriptState(), *init_options, base::TimeTicks(),
+ scope.GetExceptionState()));
+ EXPECT_FALSE(scope.GetExceptionState().HadException());
+ }
+
+ // check kErrorTooManyProfilers
+ ProfilerGroup* extra_profiler_group = ProfilerGroup::From(scope.GetIsolate());
+ ProfilerInitOptions* extra_init_options = ProfilerInitOptions::Create();
+ extra_init_options->setSampleInterval(100);
+ for (auto i = kMaxConcurrentProfilerCount; i < kLargeProfilerCount; i++) {
+ extra_profiler_group->CreateProfiler(scope.GetScriptState(),
+ *extra_init_options, base::TimeTicks(),
+ scope.GetExceptionState());
+ EXPECT_TRUE(scope.GetExceptionState().HadException());
+ EXPECT_EQ(scope.GetExceptionState().Message(),
+ "Reached maximum concurrent amount of profilers");
+ }
+
+ for (auto profiler : profilers) {
+ profiler->stop(scope.GetScriptState());
+ }
}
TEST(ProfilerGroupTest, NegativeSamplingInterval) {
@@ -152,30 +179,6 @@ TEST(ProfilerGroupTest, OverflowSamplingInterval) {
EXPECT_TRUE(scope.GetExceptionState().HadException());
}
-// Tests behaviour when exceeding the maximum number of concurrent profiles
-// supported by the V8 profiling API (https://crbug.com/1052341).
-TEST(ProfilerGroupTest, V8ProfileLimit) {
- V8TestingScope scope;
-
- ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
-
- ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
- init_options->setSampleInterval(0);
-
- HeapVector<Member<Profiler>> profilers;
- for (auto i = 0; i < kLargeProfilerCount; i++) {
- // TODO(acomminos): The V8 public API should likely be changed to expose
- // exceeding the profile limit during creation. This would enable
- // instantiation of profiles to cause a promise rejection instead.
- profilers.push_back(profiler_group->CreateProfiler(
- scope.GetScriptState(), *init_options, base::TimeTicks(),
- scope.GetExceptionState()));
- }
- for (auto profiler : profilers) {
- profiler->stop(scope.GetScriptState());
- }
-}
-
TEST(ProfilerGroupTest, Bug1119865) {
class ExpectNoCallFunction : public ScriptFunction {
public:
@@ -208,6 +211,27 @@ TEST(ProfilerGroupTest, Bug1119865) {
profiler->stop(scope.GetScriptState()).Then(function);
}
+/*
+ * LEAK TESTS - SHOULD RUN LAST
+ */
+
+// Tests that a leaked profiler doesn't crash the isolate on heap teardown.
+// These should run last
+TEST(ProfilerGroupTest, LeakProfiler) {
+ V8TestingScope scope;
+
+ ProfilerGroup* profiler_group = ProfilerGroup::From(scope.GetIsolate());
+
+ ProfilerInitOptions* init_options = ProfilerInitOptions::Create();
+ init_options->setSampleInterval(0);
+ init_options->setMaxBufferSize(0);
+ Profiler* profiler = profiler_group->CreateProfiler(
+ scope.GetScriptState(), *init_options, base::TimeTicks(),
+ scope.GetExceptionState());
+
+ EXPECT_FALSE(profiler->stopped());
+}
+
// Tests that a leaked profiler doesn't crash when disposed alongside its
// context.
TEST(ProfilerGroupTest, LeakProfilerWithContext) {
diff --git a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
index 2588b14206b..67c00aa7793 100644
--- a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
+++ b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.cc
@@ -12,9 +12,9 @@ namespace blink {
TaskAttributionTiming::TaskAttributionTiming(const AtomicString& name,
const AtomicString& container_type,
- const String& container_src,
- const String& container_id,
- const String& container_name)
+ const AtomicString& container_src,
+ const AtomicString& container_id,
+ const AtomicString& container_name)
: PerformanceEntry(name, 0.0, 0.0),
container_type_(container_type),
container_src_(container_src),
diff --git a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
index 2c2ead9d6e1..7f33034e4c0 100644
--- a/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
+++ b/chromium/third_party/blink/renderer/core/timing/task_attribution_timing.h
@@ -28,9 +28,9 @@ class TaskAttributionTiming final : public PerformanceEntry {
TaskAttributionTiming(const AtomicString& type,
const AtomicString& container_type,
- const String& container_src,
- const String& container_id,
- const String& container_name);
+ const AtomicString& container_src,
+ const AtomicString& container_id,
+ const AtomicString& container_name);
~TaskAttributionTiming() override;
private:
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance.cc b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
index bf39c372991..8f068c7d8b9 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.cc
@@ -31,6 +31,7 @@
#include "third_party/blink/renderer/core/timing/window_performance.h"
+#include "base/trace_event/common/trace_event_common.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
@@ -44,6 +45,7 @@
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/page_hidden_state.h"
@@ -201,6 +203,10 @@ WindowPerformance::CreateNavigationTimingInstance() {
if (!DomWindow())
return nullptr;
DocumentLoader* document_loader = DomWindow()->document()->Loader();
+ // TODO(npm): figure out when |document_loader| can be null and add tests.
+ DCHECK(document_loader);
+ if (!document_loader)
+ return nullptr;
ResourceTimingInfo* info = document_loader->GetNavigationTimingInfo();
if (!info)
return nullptr;
@@ -314,7 +320,7 @@ void WindowPerformance::ReportLongTask(base::TimeTicks start_time,
if (!culprit_dom_window || !culprit_dom_window->GetFrame() ||
!culprit_dom_window->GetFrame()->DeprecatedLocalOwner()) {
AddLongTaskTiming(start_time, end_time, attribution.first, "window",
- g_empty_string, g_empty_string, g_empty_string);
+ g_empty_atom, g_empty_atom, g_empty_atom);
} else {
HTMLFrameOwnerElement* frame_owner =
culprit_dom_window->GetFrame()->DeprecatedLocalOwner();
@@ -346,40 +352,46 @@ void WindowPerformance::RegisterEventTiming(const AtomicString& event_type,
MonotonicTimeToDOMHighResTimeStamp(processing_start),
MonotonicTimeToDOMHighResTimeStamp(processing_end), cancelable, target);
// Add |entry| to the end of the queue along with the frame index at which is
- // is being queued to know when to queue a swap promise for it.
+ // is being queued to know when to queue a presentation promise for it.
event_timings_.push_back(entry);
event_frames_.push_back(frame_index_);
- bool should_queue_swap_promise = false;
- // If there are no pending swap promises, we should queue one. This ensures
- // that |event_timings_| are processed even if the Blink lifecycle does not
- // occur due to no DOM updates.
- if (pending_swap_promise_count_ == 0u) {
- should_queue_swap_promise = true;
+ bool should_queue_presentation_promise = false;
+ // If there are no pending presentation promises, we should queue one. This
+ // ensures that |event_timings_| are processed even if the Blink lifecycle
+ // does not occur due to no DOM updates.
+ if (pending_presentation_promise_count_ == 0u) {
+ should_queue_presentation_promise = true;
} else {
- // There are pending swap promises, so only queue one if the event
- // corresponds to a later frame than the one of the latest queued swap
- // promise.
- should_queue_swap_promise = frame_index_ > last_registered_frame_index_;
+ // There are pending presentation promises, so only queue one if the event
+ // corresponds to a later frame than the one of the latest queued
+ // presentation promise.
+ should_queue_presentation_promise =
+ frame_index_ > last_registered_frame_index_;
}
- if (should_queue_swap_promise) {
- DomWindow()->GetFrame()->GetChromeClient().NotifySwapTime(
+ if (should_queue_presentation_promise) {
+ DomWindow()->GetFrame()->GetChromeClient().NotifyPresentationTime(
*DomWindow()->GetFrame(),
CrossThreadBindOnce(&WindowPerformance::ReportEventTimings,
WrapCrossThreadWeakPersistent(this), frame_index_));
last_registered_frame_index_ = frame_index_;
- ++pending_swap_promise_count_;
+ ++pending_presentation_promise_count_;
}
}
void WindowPerformance::ReportEventTimings(uint64_t frame_index,
WebSwapResult result,
base::TimeTicks timestamp) {
- DCHECK(pending_swap_promise_count_);
- --pending_swap_promise_count_;
+ DCHECK(pending_presentation_promise_count_);
+ --pending_presentation_promise_count_;
// |event_timings_| and |event_frames_| should always have the same size.
DCHECK(event_timings_.size() == event_frames_.size());
if (event_timings_.IsEmpty())
return;
+
+ if (!DomWindow())
+ return;
+ InteractiveDetector* interactive_detector =
+ InteractiveDetector::From(*(DomWindow()->document()));
bool event_timing_enabled =
RuntimeEnabledFeatures::EventTimingEnabled(GetExecutionContext());
DOMHighResTimeStamp end_time = MonotonicTimeToDOMHighResTimeStamp(timestamp);
@@ -396,7 +408,35 @@ void WindowPerformance::ReportEventTimings(uint64_t frame_index,
event_frames_.pop_front();
int duration_in_ms = std::round((end_time - entry->startTime()) / 8) * 8;
+ base::TimeDelta input_delay = base::TimeDelta::FromMillisecondsD(
+ entry->processingStart() - entry->startTime());
+ base::TimeDelta processing_time = base::TimeDelta::FromMillisecondsD(
+ entry->processingEnd() - entry->processingStart());
+ base::TimeDelta time_to_next_paint =
+ base::TimeDelta::FromMillisecondsD(end_time - entry->processingEnd());
entry->SetDuration(duration_in_ms);
+ TRACE_EVENT2("devtools.timeline", "EventTiming", "data",
+ entry->ToTracedValue(), "frame",
+ ToTraceValue(DomWindow()->GetFrame()));
+ if (entry->name() == "pointerdown") {
+ pending_pointer_down_input_delay_ = input_delay;
+ pending_pointer_down_processing_time_ = processing_time;
+ pending_pointer_down_time_to_next_paint_ = time_to_next_paint;
+ } else if (entry->name() == "pointerup") {
+ if (pending_pointer_down_time_to_next_paint_.has_value() &&
+ interactive_detector) {
+ interactive_detector->RecordInputEventTimingUKM(
+ pending_pointer_down_input_delay_.value(),
+ pending_pointer_down_processing_time_.value(),
+ pending_pointer_down_time_to_next_paint_.value(), entry->name());
+ }
+ } else if ((entry->name() == "click" || entry->name() == "keydown" ||
+ entry->name() == "mousedown") &&
+ interactive_detector) {
+ interactive_detector->RecordInputEventTimingUKM(
+ input_delay, processing_time, time_to_next_paint, entry->name());
+ }
+
if (!first_input_timing_) {
if (entry->name() == "pointerdown") {
first_pointer_down_event_timing_ =
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance.h b/chromium/third_party/blink/renderer/core/timing/window_performance.h
index be9e535390b..7c33989791a 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance.h
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance.h
@@ -70,9 +70,9 @@ class CORE_EXPORT WindowPerformance final : public Performance,
bool FirstInputDetected() const { return !!first_input_timing_; }
- // This method creates a PerformanceEventTiming and if needed creates a swap
- // promise to calculate the |duration| attribute when such promise is
- // resolved.
+ // This method creates a PerformanceEventTiming and if needed creates a
+ // presentation promise to calculate the |duration| attribute when such
+ // promise is resolved.
void RegisterEventTiming(const AtomicString& event_type,
base::TimeTicks start_time,
base::TimeTicks processing_start,
@@ -123,8 +123,8 @@ class CORE_EXPORT WindowPerformance final : public Performance,
void BuildJSONValue(V8ObjectBuilder&) const override;
- // Method called once swap promise is resolved. It will add all event timings
- // that have not been added since the last swap promise.
+ // Method called once presentation promise is resolved. It will add all event
+ // timings that have not been added since the last presentation promise.
void ReportEventTimings(uint64_t frame_index,
WebSwapResult result,
base::TimeTicks timestamp);
@@ -133,13 +133,13 @@ class CORE_EXPORT WindowPerformance final : public Performance,
// Counter of the current frame index, based on calls to OnPaintFinished().
uint64_t frame_index_ = 1;
- // Monotonically increasing value with the last frame index on which a swap
- // promise was queued;
+ // Monotonically increasing value with the last frame index on which a
+ // presentation promise was queued;
uint64_t last_registered_frame_index_ = 0;
- // Number of pending swap promises.
- uint16_t pending_swap_promise_count_ = 0;
+ // Number of pending presentation promises.
+ uint16_t pending_presentation_promise_count_ = 0;
// PerformanceEventTiming entries that have not been sent to observers yet:
- // the event dispatch has been completed but the swap promise used to
+ // the event dispatch has been completed but the presentation promise used to
// determine |duration| has not yet been resolved. It is handled as a queue:
// FIFO.
HeapDeque<Member<PerformanceEventTiming>> event_timings_;
@@ -155,6 +155,9 @@ class CORE_EXPORT WindowPerformance final : public Performance,
Member<EventCounts> event_counts_;
mutable Member<PerformanceNavigation> navigation_;
mutable Member<PerformanceTiming> timing_;
+ base::Optional<base::TimeDelta> pending_pointer_down_input_delay_;
+ base::Optional<base::TimeDelta> pending_pointer_down_processing_time_;
+ base::Optional<base::TimeDelta> pending_pointer_down_time_to_next_paint_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc b/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
index 070c3f609e3..c2ae1bfcb68 100644
--- a/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
+++ b/chromium/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -184,7 +184,8 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
// Simulate changing the document while keeping the window.
std::unique_ptr<WebNavigationParams> params =
- WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url);
+ WebNavigationParams::CreateWithHTMLBufferForTesting(
+ SharedBuffer::Create(), url);
page_holder->GetFrame().Loader().CommitNavigation(std::move(params), nullptr);
EXPECT_EQ(perf, DOMWindowPerformance::performance(