Bug 1444580: Devirtualize the IntersectionObserver bits. r=smaug
MozReview-Commit-ID: 65WtMQPu7f4
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12353,71 +12353,57 @@ nsDocument::ReportUseCounters(UseCounter
if (IsContentDocument() || IsResourceDoc()) {
uint16_t num = mIncCounters[eIncCounter_ScriptTag];
Telemetry::Accumulate(Telemetry::DOM_SCRIPT_EVAL_PER_DOCUMENT, num);
}
}
void
-nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver)
-{
- MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
- "Intersection observer already in the list");
- mIntersectionObservers.PutEntry(aObserver);
-}
-
-void
-nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver)
-{
- mIntersectionObservers.RemoveEntry(aObserver);
-}
-
-void
-nsDocument::UpdateIntersectionObservations()
+nsIDocument::UpdateIntersectionObservations()
{
if (mIntersectionObservers.IsEmpty()) {
return;
}
DOMHighResTimeStamp time = 0;
if (nsPIDOMWindowInner* window = GetInnerWindow()) {
Performance* perf = window->GetPerformance();
if (perf) {
time = perf->Now();
}
}
nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Get()->GetKey();
- observers.AppendElement(observer);
+ observers.AppendElement(observer);
}
for (const auto& observer : observers) {
if (observer) {
observer->Update(this, time);
}
}
}
void
-nsDocument::ScheduleIntersectionObserverNotification()
+nsIDocument::ScheduleIntersectionObserverNotification()
{
if (mIntersectionObservers.IsEmpty()) {
return;
}
MOZ_RELEASE_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> notification =
NewRunnableMethod("nsDocument::NotifyIntersectionObservers",
this,
&nsDocument::NotifyIntersectionObservers);
Dispatch(TaskCategory::Other, notification.forget());
}
void
-nsDocument::NotifyIntersectionObservers()
+nsIDocument::NotifyIntersectionObservers()
{
nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Get()->GetKey();
observers.AppendElement(observer);
}
for (const auto& observer : observers) {
if (observer) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -472,28 +472,16 @@ public:
// Flush use counters for the document and for its external resource
// documents. (Should only be necessary for tests, where we need
// flushing to happen synchronously and deterministically.)
eIncludeExternalResources,
};
void ReportUseCounters(UseCounterReportKind aKind = UseCounterReportKind::eDefault);
- virtual void AddIntersectionObserver(
- mozilla::dom::DOMIntersectionObserver* aObserver) override;
- virtual void RemoveIntersectionObserver(
- mozilla::dom::DOMIntersectionObserver* aObserver) override;
- virtual void UpdateIntersectionObservations() override;
- virtual void ScheduleIntersectionObserverNotification() override;
- virtual void NotifyIntersectionObservers() override;
- virtual bool HasIntersectionObservers() const override
- {
- return !mIntersectionObservers.IsEmpty();
- }
-
virtual void NotifyLayerManagerRecreated() override;
bool IsSynthesized();
// Check whether shadow DOM is enabled for the global of aObject.
static bool IsShadowDOMEnabled(JSContext* aCx, JSObject* aObject);
// Check whether shadow DOM is enabled for the document this node belongs to.
static bool IsShadowDOMEnabled(const nsINode* aNode);
@@ -845,20 +833,16 @@ protected:
// Apply the fullscreen state to the document, and trigger related
// events. It returns false if the fullscreen element ready check
// fails and nothing gets changed.
bool ApplyFullscreen(const FullscreenRequest& aRequest);
// Array of owning references to all children
nsAttrAndChildArray mChildren;
- // Array of intersection observers
- nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
- mIntersectionObservers;
-
// Tracker for animations that are waiting to start.
// nullptr until GetOrCreatePendingAnimationTracker is called.
RefPtr<mozilla::PendingAnimationTracker> mPendingAnimationTracker;
// Stack of full-screen elements. When we request full-screen we push the
// full-screen element onto this stack, and when we cancel full-screen we
// pop one off this stack, restoring the previous full-screen state
nsTArray<nsWeakPtr> mFullScreenStack;
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -3183,25 +3183,36 @@ public:
void ReportHasScrollLinkedEffect();
bool HasScrollLinkedEffect() const
{
return mHasScrollLinkedEffect;
}
mozilla::dom::DocGroup* GetDocGroup() const;
- virtual void AddIntersectionObserver(
- mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
- virtual void RemoveIntersectionObserver(
- mozilla::dom::DOMIntersectionObserver* aObserver) = 0;
-
- virtual void UpdateIntersectionObservations() = 0;
- virtual void ScheduleIntersectionObserverNotification() = 0;
- virtual void NotifyIntersectionObservers() = 0;
- virtual bool HasIntersectionObservers() const = 0;
+ void AddIntersectionObserver(mozilla::dom::DOMIntersectionObserver* aObserver)
+ {
+ MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
+ "Intersection observer already in the list");
+ mIntersectionObservers.PutEntry(aObserver);
+ }
+
+ void RemoveIntersectionObserver(mozilla::dom::DOMIntersectionObserver* aObserver)
+ {
+ mIntersectionObservers.RemoveEntry(aObserver);
+ }
+
+ bool HasIntersectionObservers() const
+ {
+ return !mIntersectionObservers.IsEmpty();
+ }
+
+ void UpdateIntersectionObservations();
+ void ScheduleIntersectionObserverNotification();
+ void NotifyIntersectionObservers();
// Dispatch a runnable related to the document.
virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) override;
virtual nsISerialEventTarget*
EventTargetFor(mozilla::TaskCategory aCategory) const override;
@@ -3984,16 +3995,20 @@ protected:
nsWeakPtr mAutoFocusElement;
// Weak reference to the scope object (aka the script global object)
// that, unlike mScriptGlobalObject, is never unset once set. This
// is a weak reference to avoid leaks due to circular references.
nsWeakPtr mScopeObject;
+ // Array of intersection observers
+ nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
+ mIntersectionObservers;
+
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
// Member to store out last-selected stylesheet set.
nsString mLastStyleSheetSet;
RefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
// We lazily calculate declaration blocks for SVG elements with mapped