1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_Performance_h
8 #define mozilla_dom_Performance_h
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/DOMEventTargetHelper.h"
12 #include "nsCOMPtr.h"
13 #include "nsDOMNavigationTiming.h"
14 #include "nsTObserverArray.h"
15 
16 class nsITimedChannel;
17 
18 namespace mozilla {
19 
20 class ErrorResult;
21 
22 namespace dom {
23 
24 class PerformanceEntry;
25 class PerformanceNavigation;
26 class PerformancePaintTiming;
27 class PerformanceObserver;
28 class PerformanceService;
29 class PerformanceStorage;
30 class PerformanceTiming;
31 class PerformanceEventTiming;
32 class WorkerPrivate;
33 class EventCounts;
34 
35 // Base class for main-thread and worker Performance API
36 class Performance : public DOMEventTargetHelper {
37  public:
38   NS_DECL_ISUPPORTS_INHERITED
39   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Performance, DOMEventTargetHelper)
40 
41   static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
42 
43   static already_AddRefed<Performance> CreateForMainThread(
44       nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
45       nsDOMNavigationTiming* aDOMTiming, nsITimedChannel* aChannel);
46 
47   static already_AddRefed<Performance> CreateForWorker(
48       WorkerPrivate* aWorkerPrivate);
49 
50   JSObject* WrapObject(JSContext* cx,
51                        JS::Handle<JSObject*> aGivenProto) override;
52 
53   virtual void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
54 
55   virtual void GetEntriesByType(const nsAString& aEntryType,
56                                 nsTArray<RefPtr<PerformanceEntry>>& aRetval);
57 
58   virtual void GetEntriesByTypeForObserver(
59       const nsAString& aEntryType, nsTArray<RefPtr<PerformanceEntry>>& aRetval);
60 
61   virtual void GetEntriesByName(const nsAString& aName,
62                                 const Optional<nsAString>& aEntryType,
63                                 nsTArray<RefPtr<PerformanceEntry>>& aRetval);
64 
65   virtual PerformanceStorage* AsPerformanceStorage() = 0;
66 
67   void ClearResourceTimings();
68 
69   DOMHighResTimeStamp Now();
70 
71   DOMHighResTimeStamp NowUnclamped() const;
72 
73   DOMHighResTimeStamp TimeOrigin();
74 
75   void Mark(const nsAString& aName, ErrorResult& aRv);
76 
77   void ClearMarks(const Optional<nsAString>& aName);
78 
79   void Measure(const nsAString& aName, const Optional<nsAString>& aStartMark,
80                const Optional<nsAString>& aEndMark, ErrorResult& aRv);
81 
82   void ClearMeasures(const Optional<nsAString>& aName);
83 
84   void SetResourceTimingBufferSize(uint64_t aMaxSize);
85 
86   void AddObserver(PerformanceObserver* aObserver);
87   void RemoveObserver(PerformanceObserver* aObserver);
88   MOZ_CAN_RUN_SCRIPT void NotifyObservers();
89   void CancelNotificationObservers();
90 
91   virtual PerformanceTiming* Timing() = 0;
92 
93   virtual PerformanceNavigation* Navigation() = 0;
94 
95   virtual void SetFCPTimingEntry(PerformancePaintTiming* aEntry) = 0;
96 
97   IMPL_EVENT_HANDLER(resourcetimingbufferfull)
98 
99   virtual void GetMozMemory(JSContext* aCx,
100                             JS::MutableHandle<JSObject*> aObj) = 0;
101 
102   virtual nsDOMNavigationTiming* GetDOMTiming() const = 0;
103 
104   virtual nsITimedChannel* GetChannel() const = 0;
105 
106   virtual TimeStamp CreationTimeStamp() const = 0;
107 
IsSystemPrincipal()108   bool IsSystemPrincipal() const { return mSystemPrincipal; }
109 
110   DOMHighResTimeStamp TimeStampToDOMHighResForRendering(TimeStamp) const;
111 
112   virtual uint64_t GetRandomTimelineSeed() = 0;
113 
114   void MemoryPressure();
115 
116   size_t SizeOfUserEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
117   size_t SizeOfResourceEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
SizeOfEventEntries(mozilla::MallocSizeOf aMallocSizeOf)118   virtual size_t SizeOfEventEntries(mozilla::MallocSizeOf aMallocSizeOf) const {
119     return 0;
120   }
121 
122   void InsertResourceEntry(PerformanceEntry* aEntry);
123 
124   virtual void InsertEventTimingEntry(PerformanceEventTiming* aEntry) = 0;
125 
126   virtual void BufferEventTimingEntryIfNeeded(
127       PerformanceEventTiming* aEntry) = 0;
128 
129   virtual class EventCounts* EventCounts() = 0;
130 
131   virtual void QueueNavigationTimingEntry() = 0;
132 
133   virtual void UpdateNavigationTimingEntry() = 0;
134 
135   virtual bool CrossOriginIsolated() const = 0;
136 
137   virtual void DispatchPendingEventTimingEntries() = 0;
138 
139   void QueueNotificationObserversTask();
140 
141  protected:
142   Performance(nsIGlobalObject* aGlobal, bool aSystemPrincipal);
143   Performance(nsPIDOMWindowInner* aWindow, bool aSystemPrincipal);
144 
145   virtual ~Performance();
146 
147   virtual void InsertUserEntry(PerformanceEntry* aEntry);
148 
149   void ClearUserEntries(const Optional<nsAString>& aEntryName,
150                         const nsAString& aEntryType);
151 
152   DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
153                                                ErrorResult& aRv);
154 
155   virtual void DispatchBufferFullEvent() = 0;
156 
157   virtual DOMHighResTimeStamp CreationTime() const = 0;
158 
IsPerformanceTimingAttribute(const nsAString & aName)159   virtual bool IsPerformanceTimingAttribute(const nsAString& aName) {
160     return false;
161   }
162 
GetPerformanceTimingFromString(const nsAString & aTimingName)163   virtual DOMHighResTimeStamp GetPerformanceTimingFromString(
164       const nsAString& aTimingName) {
165     return 0;
166   }
167 
168   void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
169   void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
170                           uint64_t epoch);
171 
172   void RunNotificationObserversTask();
173   void QueueEntry(PerformanceEntry* aEntry);
174 
175   nsTObserverArray<RefPtr<PerformanceObserver>> mObservers;
176 
177  protected:
178   static const uint64_t kDefaultResourceTimingBufferSize = 250;
179 
180   // When kDefaultResourceTimingBufferSize is increased or removed, these should
181   // be changed to use SegmentedVector
182   AutoTArray<RefPtr<PerformanceEntry>, kDefaultResourceTimingBufferSize>
183       mUserEntries;
184   AutoTArray<RefPtr<PerformanceEntry>, kDefaultResourceTimingBufferSize>
185       mResourceEntries;
186   AutoTArray<RefPtr<PerformanceEntry>, kDefaultResourceTimingBufferSize>
187       mSecondaryResourceEntries;
188 
189   uint64_t mResourceTimingBufferSize;
190   bool mPendingNotificationObserversTask;
191 
192   bool mPendingResourceTimingBufferFullEvent;
193 
194   RefPtr<PerformanceService> mPerformanceService;
195 
196   bool mSystemPrincipal;
197 
198  private:
199   MOZ_ALWAYS_INLINE bool CanAddResourceTimingEntry();
200   void BufferEvent();
201 };
202 
203 }  // namespace dom
204 }  // namespace mozilla
205 
206 #endif  // mozilla_dom_Performance_h
207