#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/timing/performance.h"
#include <algorithm>
#include <optional>
#include "base/containers/contains.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/default_clock.h"
#include "base/time/default_tick_clock.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/mojom/permissions_policy/document_policy_feature.mojom-blink.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/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_double_string.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_performancemeasureoptions_string.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_timing.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/event_target_names.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/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/back_forward_cache_restoration.h"
#include "third_party/blink/renderer/core/timing/background_tracing_helper.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.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"
#include "third_party/blink/renderer/core/timing/performance_element_timing.h"
#include "third_party/blink/renderer/core/timing/performance_entry.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/core/timing/performance_long_task_timing.h"
#include "third_party/blink/renderer/core/timing/performance_mark.h"
#include "third_party/blink/renderer/core/timing/performance_measure.h"
#include "third_party/blink/renderer/core/timing/performance_observer.h"
#include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
#include "third_party/blink/renderer/core/timing/performance_server_timing.h"
#include "third_party/blink/renderer/core/timing/performance_user_timing.h"
#include "third_party/blink/renderer/core/timing/profiler.h"
#include "third_party/blink/renderer/core/timing/profiler_group.h"
#include "third_party/blink/renderer/core/timing/soft_navigation_entry.h"
#include "third_party/blink/renderer/core/timing/time_clamper.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_utils.h"
#include "third_party/blink/renderer/platform/network/http_parsers.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "v8/include/v8-metrics.h"
namespace blink {
namespace {
constexpr size_t kLongTaskUkmSampleInterval = …;
const char kSwapsPerInsertionHistogram[] = …;
bool IsMeasureOptionsEmpty(const PerformanceMeasureOptions& options) { … }
base::TimeDelta GetUnixAtZeroMonotonic(const base::Clock* clock,
const base::TickClock* tick_clock) { … }
void RecordLongTaskUkm(ExecutionContext* execution_context,
base::TimeDelta start_time,
base::TimeDelta duration) { … }
PerformanceEntry::EntryType kDroppableEntryTypes[] = …;
void SwapEntries(PerformanceEntryVector& entries,
int leftIndex,
int rightIndex) { … }
inline bool CheckName(const PerformanceEntry* entry,
const AtomicString& maybe_name) { … }
void FilterEntriesTriggeredBySoftNavigationIfNeeded(
PerformanceEntryVector& input_entries,
PerformanceEntryVector** output_entries,
bool include_soft_navigation_observations) { … }
}
PerformanceEntryVector MergePerformanceEntryVectors(
const PerformanceEntryVector& first_entry_vector,
const PerformanceEntryVector& second_entry_vector,
const AtomicString& maybe_name) { … }
PerformanceObserverVector;
constexpr size_t kDefaultResourceTimingBufferSize = …;
constexpr size_t kDefaultEventTimingBufferSize = …;
constexpr size_t kDefaultElementTimingBufferSize = …;
constexpr size_t kDefaultLayoutShiftBufferSize = …;
constexpr size_t kDefaultLargestContenfulPaintSize = …;
constexpr size_t kDefaultLongTaskBufferSize = …;
constexpr size_t kDefaultLongAnimationFrameBufferSize = …;
constexpr size_t kDefaultBackForwardCacheRestorationBufferSize = …;
constexpr size_t kDefaultSoftNavigationBufferSize = …;
constexpr size_t kDefaultPaintEntriesBufferSize = …;
Performance::Performance(
base::TimeTicks time_origin,
bool cross_origin_isolated_capability,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
ExecutionContext* context)
: … { … }
Performance::~Performance() = default;
const AtomicString& Performance::InterfaceName() const { … }
PerformanceTiming* Performance::timing() const { … }
PerformanceNavigation* Performance::navigation() const { … }
MemoryInfo* Performance::memory(ScriptState*) const { … }
EventCounts* Performance::eventCounts() { … }
ScriptPromise<MemoryMeasurement> Performance::measureUserAgentSpecificMemory(
ScriptState* script_state,
ExceptionState& exception_state) const { … }
DOMHighResTimeStamp Performance::timeOrigin() const { … }
PerformanceEntryVector Performance::getEntries() { … }
PerformanceEntryVector Performance::getEntries(
ScriptState* script_state,
PerformanceEntryFilterOptions* options) { … }
PerformanceEntryVector Performance::GetEntriesForCurrentFrame(
const AtomicString& maybe_name) { … }
PerformanceEntryVector Performance::getBufferedEntriesByType(
const AtomicString& entry_type,
bool include_soft_navigation_observations) { … }
PerformanceEntryVector Performance::getEntriesByType(
const AtomicString& entry_type) { … }
PerformanceEntryVector Performance::GetEntriesByTypeForCurrentFrame(
const AtomicString& entry_type,
const AtomicString& maybe_name) { … }
PerformanceEntryVector Performance::getEntriesByTypeInternal(
PerformanceEntry::EntryType type,
const AtomicString& maybe_name,
bool include_soft_navigation_observations) { … }
PerformanceEntryVector Performance::getEntriesByName(
const AtomicString& name,
const AtomicString& entry_type) { … }
PerformanceEntryVector Performance::GetEntriesWithChildFrames(
ScriptState* script_state,
const AtomicString& maybe_type,
const AtomicString& maybe_name) { … }
void Performance::clearResourceTimings() { … }
void Performance::setResourceTimingBufferSize(unsigned size) { … }
void Performance::setBackForwardCacheRestorationBufferSizeForTest(
unsigned size) { … }
void Performance::setEventTimingBufferSizeForTest(unsigned size) { … }
void Performance::AddResourceTiming(mojom::blink::ResourceTimingInfoPtr info,
const AtomicString& initiator_type) { … }
void Performance::NotifyNavigationTimingToObservers() { … }
bool Performance::IsElementTimingBufferFull() const { … }
bool Performance::IsEventTimingBufferFull() const { … }
bool Performance::IsLongAnimationFrameBufferFull() const { … }
void Performance::CopySecondaryBuffer() { … }
void Performance::FireResourceTimingBufferFull(TimerBase*) { … }
void Performance::AddToElementTimingBuffer(PerformanceElementTiming& entry) { … }
void Performance::AddToEventTimingBuffer(PerformanceEventTiming& entry) { … }
void Performance::AddToLayoutShiftBuffer(LayoutShift& entry) { … }
void Performance::AddLargestContentfulPaint(LargestContentfulPaint* entry) { … }
void Performance::AddSoftNavigationToPerformanceTimeline(
SoftNavigationEntry* entry) { … }
void Performance::AddFirstPaintTiming(base::TimeTicks start_time,
bool is_triggered_by_soft_navigation) { … }
void Performance::AddFirstContentfulPaintTiming(
base::TimeTicks start_time,
bool is_triggered_by_soft_navigation) { … }
void Performance::AddPaintTiming(PerformancePaintTiming::PaintType type,
base::TimeTicks start_time,
bool is_triggered_by_soft_navigation) { … }
bool Performance::CanAddResourceTimingEntry() { … }
void Performance::AddLongTaskTiming(base::TimeTicks start_time,
base::TimeTicks end_time,
const AtomicString& name,
const AtomicString& container_type,
const AtomicString& container_src,
const AtomicString& container_id,
const AtomicString& container_name) { … }
void Performance::AddBackForwardCacheRestoration(
base::TimeTicks start_time,
base::TimeTicks pageshow_start_time,
base::TimeTicks pageshow_end_time) { … }
UserTiming& Performance::GetUserTiming() { … }
PerformanceMark* Performance::mark(ScriptState* script_state,
const AtomicString& mark_name,
PerformanceMarkOptions* mark_options,
ExceptionState& exception_state) { … }
void Performance::ProcessUserFeatureMark(
const PerformanceMarkOptions* mark_options) { … }
void Performance::clearMarks(const AtomicString& mark_name) { … }
PerformanceMeasure* Performance::measure(ScriptState* script_state,
const AtomicString& measure_name,
ExceptionState& exception_state) { … }
PerformanceMeasure* Performance::measure(
ScriptState* script_state,
const AtomicString& measure_name,
const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
ExceptionState& exception_state) { … }
PerformanceMeasure* Performance::measure(
ScriptState* script_state,
const AtomicString& measure_name,
const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
const String& end,
ExceptionState& exception_state) { … }
PerformanceMeasure* Performance::MeasureInternal(
ScriptState* script_state,
const AtomicString& measure_name,
const V8UnionPerformanceMeasureOptionsOrString* start_or_options,
std::optional<String> end_mark,
ExceptionState& exception_state) { … }
PerformanceMeasure* Performance::MeasureWithDetail(
ScriptState* script_state,
const AtomicString& measure_name,
const V8UnionDoubleOrString* start,
const std::optional<double>& duration,
const V8UnionDoubleOrString* end,
const ScriptValue& detail,
ExceptionState& exception_state) { … }
void Performance::clearMeasures(const AtomicString& measure_name) { … }
void Performance::RegisterPerformanceObserver(PerformanceObserver& observer) { … }
void Performance::UnregisterPerformanceObserver(
PerformanceObserver& old_observer) { … }
void Performance::UpdatePerformanceObserverFilterOptions() { … }
void Performance::NotifyObserversOfEntry(PerformanceEntry& entry) const { … }
bool Performance::HasObserverFor(
PerformanceEntry::EntryType filter_type) const { … }
void Performance::ActivateObserver(PerformanceObserver& observer) { … }
void Performance::SuspendObserver(PerformanceObserver& observer) { … }
void Performance::DeliverObservationsTimerFired(TimerBase*) { … }
int Performance::GetDroppedEntriesForTypes(PerformanceEntryTypeMask types) { … }
DOMHighResTimeStamp Performance::ClampTimeResolution(
base::TimeDelta time,
bool cross_origin_isolated_capability) { … }
DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
base::TimeTicks time_origin,
base::TimeTicks monotonic_time,
bool allow_negative_value,
bool cross_origin_isolated_capability) { … }
DOMHighResTimeStamp Performance::MonotonicTimeToDOMHighResTimeStamp(
base::TimeTicks monotonic_time) const { … }
DOMHighResTimeStamp Performance::now() const { … }
bool Performance::CanExposeNode(Node* node) { … }
ScriptValue Performance::toJSONForBinding(ScriptState* script_state) const { … }
void Performance::BuildJSONValue(V8ObjectBuilder& builder) const { … }
void Performance::InsertEntryIntoSortedBuffer(PerformanceEntryVector& entries,
PerformanceEntry& entry,
Metrics record) { … }
void Performance::Trace(Visitor* visitor) const { … }
void Performance::SetClocksForTesting(const base::Clock* clock,
const base::TickClock* tick_clock) { … }
void Performance::ResetTimeOriginForTesting(base::TimeTicks time_origin) { … }
bool Performance::softNavPaintMetricsSupported() const { … }
}