diff options
Diffstat (limited to 'dom/base')
45 files changed, 451 insertions, 640 deletions
diff --git a/dom/base/Attr.cpp b/dom/base/Attr.cpp index 6eb3b49fd..71b559392 100644 --- a/dom/base/Attr.cpp +++ b/dom/base/Attr.cpp @@ -59,8 +59,6 @@ Attr::Attr(nsDOMAttributeMap *aAttrMap, NS_IMPL_CYCLE_COLLECTION_CLASS(Attr) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Attr) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS - if (!nsINode::Traverse(tmp, cb)) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 00ee3d42f..3f202d33b 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -138,7 +138,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementRegistry) } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWhenDefinedPromiseMap) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementRegistry) diff --git a/dom/base/DOMException.cpp b/dom/base/DOMException.cpp index dfda47316..9fbb2f242 100644 --- a/dom/base/DOMException.cpp +++ b/dom/base/DOMException.cpp @@ -165,7 +165,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Exception) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception) diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index e39abf1a6..389b93071 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -43,16 +43,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries) - tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries) @@ -153,30 +154,34 @@ DOMIntersectionObserver::Observe(Element& aTarget) return; } aTarget.RegisterIntersectionObserver(this); - mObservationTargets.PutEntry(&aTarget); + mObservationTargets.AppendElement(&aTarget); Connect(); } void DOMIntersectionObserver::Unobserve(Element& aTarget) { - if (UnlinkTarget(aTarget)) { - aTarget.UnregisterIntersectionObserver(this); + if (!mObservationTargets.Contains(&aTarget)) { + // You're not on the list, buddy! + return; } + + if (mObservationTargets.Length() == 1) { + Disconnect(); + return; + } + + mObservationTargets.RemoveElement(&aTarget); + aTarget.UnregisterIntersectionObserver(this); } -bool +void DOMIntersectionObserver::UnlinkTarget(Element& aTarget) { - if (!mObservationTargets.Contains(&aTarget)) { - return false; - } - if (mObservationTargets.Count() == 1) { - Disconnect(); - return false; - } - mObservationTargets.RemoveEntry(&aTarget); - return true; + mObservationTargets.RemoveElement(&aTarget); + if (mObservationTargets.Length() == 0) { + Disconnect(); + } } void @@ -185,10 +190,11 @@ DOMIntersectionObserver::Connect() if (mConnected) { return; } + mConnected = true; - - nsIDocument* document = mOwner->GetExtantDoc(); - document->AddIntersectionObserver(this); + if (mDocument) { + mDocument->AddIntersectionObserver(this); + } } void @@ -197,18 +203,17 @@ DOMIntersectionObserver::Disconnect() if (!mConnected) { return; } - for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) { - Element* target = iter.Get()->GetKey(); + + mConnected = false; + + for (size_t i = 0; i < mObservationTargets.Length(); ++i) { + Element* target = mObservationTargets.ElementAt(i); target->UnregisterIntersectionObserver(this); } mObservationTargets.Clear(); - if (mOwner) { - nsIDocument* document = mOwner->GetExtantDoc(); - if (document) { - document->RemoveIntersectionObserver(this); - } + if (mDocument) { + mDocument->RemoveIntersectionObserver(this); } - mConnected = false; } void @@ -269,17 +274,21 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time root = mRoot; rootFrame = root->GetPrimaryFrame(); if (rootFrame) { + nsRect rootRectRelativeToRootFrame; if (rootFrame->GetType() == nsGkAtoms::scrollFrame) { + // rootRectRelativeToRootFrame should be the content rect of rootFrame, not including the scrollbars. nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame); - rootRect = nsLayoutUtils::TransformFrameRectToAncestor( - rootFrame, - rootFrame->GetContentRectRelativeToSelf(), - scrollFrame->GetScrolledFrame()); + rootRectRelativeToRootFrame = scrollFrame->GetScrollPortRect(); } else { - rootRect = nsLayoutUtils::GetAllInFlowRectsUnion(rootFrame, - nsLayoutUtils::GetContainingBlockForClientRect(rootFrame), - nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS); + // rootRectRelativeToRootFrame should be the border rect of rootFrame. + rootRectRelativeToRootFrame = rootFrame->GetRectRelativeToSelf(); } + nsIFrame* containingBlock = + nsLayoutUtils::GetContainingBlockForClientRect(rootFrame); + rootRect = + nsLayoutUtils::TransformFrameRectToAncestor(rootFrame, + rootRectRelativeToRootFrame, + containingBlock); } } else { nsCOMPtr<nsIPresShell> presShell = aDocument->GetShell(); @@ -288,12 +297,25 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time if (rootFrame) { nsPresContext* presContext = rootFrame->PresContext(); while (!presContext->IsRootContentDocument()) { - presContext = rootFrame->PresContext()->GetParentPresContext(); - rootFrame = presContext->PresShell()->GetRootScrollFrame(); + // Walk up the tree + presContext = presContext->GetParentPresContext(); + if (!presContext) { + break; + } + nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame(); + if (rootScrollFrame) { + rootFrame = rootScrollFrame; + } else { + break; + } } root = rootFrame->GetContent()->AsElement(); nsIScrollableFrame* scrollFrame = do_QueryFrame(rootFrame); - rootRect = scrollFrame->GetScrollPortRect(); + // If we end up with a null root frame for some reason, we'll proceed + // with an empty root intersection rect. + if (scrollFrame) { + rootRect = scrollFrame->GetScrollPortRect(); + } } } } @@ -314,11 +336,12 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time rootMargin.Side(side) = nsLayoutUtils::ComputeCBDependentValue(basis, coord); } - for (auto iter = mObservationTargets.Iter(); !iter.Done(); iter.Next()) { - Element* target = iter.Get()->GetKey(); + for (size_t i = 0; i < mObservationTargets.Length(); ++i) { + Element* target = mObservationTargets.ElementAt(i); nsIFrame* targetFrame = target->GetPrimaryFrame(); nsRect targetRect; Maybe<nsRect> intersectionRect; + bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc(); if (rootFrame && targetFrame) { // If mRoot is set we are testing intersection with a container element @@ -327,7 +350,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time // Skip further processing of this target if it is not in the same // Document as the intersection root, e.g. if root is an element of // the main document and target an element from an embedded iframe. - if (target->GetComposedDoc() != root->GetComposedDoc()) { + if (!isSameDoc) { continue; } // Skip further processing of this target if is not a descendant of the @@ -344,7 +367,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time nsLayoutUtils::GetContainingBlockForClientRect(targetFrame), nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS ); - intersectionRect = Some(targetFrame->GetVisualOverflowRect()); + intersectionRect = Some(targetFrame->GetRectRelativeToSelf()); nsIFrame* containerFrame = nsLayoutUtils::GetCrossDocParentFrame(targetFrame); while (containerFrame && containerFrame != rootFrame) { @@ -399,29 +422,37 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time intersectionRectRelativeToRoot, rootIntersectionRect ); - if (intersectionRect.isSome()) { - intersectionRect = Some(nsLayoutUtils::TransformFrameRectToAncestor( - nsLayoutUtils::GetContainingBlockForClientRect(rootFrame), - intersectionRect.value(), - targetFrame->PresContext()->PresShell()->GetRootScrollFrame() - )); + if (intersectionRect.isSome() && !isSameDoc) { + nsRect rect = intersectionRect.value(); + nsPresContext* presContext = targetFrame->PresContext(); + nsLayoutUtils::TransformRect(rootFrame, + presContext->PresShell()->GetRootScrollFrame(), rect); + intersectionRect = Some(rect); } } - double targetArea = targetRect.width * targetRect.height; - double intersectionArea = !intersectionRect ? - 0 : intersectionRect->width * intersectionRect->height; - double intersectionRatio = targetArea > 0.0 ? intersectionArea / targetArea : 0.0; + int64_t targetArea = + (int64_t) targetRect.Width() * (int64_t) targetRect.Height(); + int64_t intersectionArea = !intersectionRect ? 0 : + (int64_t) intersectionRect->Width() * + (int64_t) intersectionRect->Height(); + + double intersectionRatio; + if (targetArea > 0.0) { + intersectionRatio = (double) intersectionArea / (double) targetArea; + } else { + intersectionRatio = intersectionRect.isSome() ? 1.0 : 0.0; + } - size_t threshold = -1; + int32_t threshold = -1; if (intersectionRatio > 0.0) { if (intersectionRatio >= 1.0) { intersectionRatio = 1.0; - threshold = mThresholds.Length(); + threshold = (int32_t)mThresholds.Length(); } else { for (size_t k = 0; k < mThresholds.Length(); ++k) { if (mThresholds[k] <= intersectionRatio) { - threshold = k + 1; + threshold = (int32_t)k + 1; } else { break; } @@ -468,6 +499,7 @@ DOMIntersectionObserver::QueueIntersectionObserverEntry(Element* aTarget, rootBounds.forget(), boundingClientRect.forget(), intersectionRect.forget(), + aIntersectionRect.isSome(), aTarget, aIntersectionRatio); mQueuedEntries.AppendElement(entry.forget()); } @@ -480,7 +512,7 @@ DOMIntersectionObserver::Notify() } mozilla::dom::Sequence<mozilla::OwningNonNull<DOMIntersectionObserverEntry>> entries; if (entries.SetCapacity(mQueuedEntries.Length(), mozilla::fallible)) { - for (uint32_t i = 0; i < mQueuedEntries.Length(); ++i) { + for (size_t i = 0; i < mQueuedEntries.Length(); ++i) { RefPtr<DOMIntersectionObserverEntry> next = mQueuedEntries[i]; *entries.AppendElement(mozilla::fallible) = next; } diff --git a/dom/base/DOMIntersectionObserver.h b/dom/base/DOMIntersectionObserver.h index 8144fc5c5..8674fe25d 100644 --- a/dom/base/DOMIntersectionObserver.h +++ b/dom/base/DOMIntersectionObserver.h @@ -30,6 +30,7 @@ public: RefPtr<DOMRect> aRootBounds, RefPtr<DOMRect> aBoundingClientRect, RefPtr<DOMRect> aIntersectionRect, + bool aIsIntersecting, Element* aTarget, double aIntersectionRatio) : mOwner(aOwner), @@ -37,6 +38,7 @@ public: mRootBounds(aRootBounds), mBoundingClientRect(aBoundingClientRect), mIntersectionRect(aIntersectionRect), + mIsIntersecting(aIsIntersecting), mTarget(aTarget), mIntersectionRatio(aIntersectionRatio) { @@ -74,6 +76,11 @@ public: return mIntersectionRect; } + bool IsIntersecting() + { + return mIsIntersecting; + } + double IntersectionRatio() { return mIntersectionRatio; @@ -90,6 +97,7 @@ protected: RefPtr<DOMRect> mRootBounds; RefPtr<DOMRect> mBoundingClientRect; RefPtr<DOMRect> mIntersectionRect; + bool mIsIntersecting; RefPtr<Element> mTarget; double mIntersectionRatio; }; @@ -101,12 +109,17 @@ protected: class DOMIntersectionObserver final : public nsISupports, public nsWrapperCache { - virtual ~DOMIntersectionObserver() { } + virtual ~DOMIntersectionObserver() { + Disconnect(); + } public: DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner, mozilla::dom::IntersectionCallback& aCb) - : mOwner(aOwner), mCallback(&aCb), mConnected(false) + : mOwner(aOwner) + , mDocument(mOwner->GetExtantDoc()) + , mCallback(&aCb) + , mConnected(false) { } NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -142,7 +155,7 @@ public: void Observe(Element& aTarget); void Unobserve(Element& aTarget); - bool UnlinkTarget(Element& aTarget); + void UnlinkTarget(Element& aTarget); void Disconnect(); void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal); @@ -164,11 +177,15 @@ protected: double aIntersectionRatio); nsCOMPtr<nsPIDOMWindowInner> mOwner; + RefPtr<nsIDocument> mDocument; RefPtr<mozilla::dom::IntersectionCallback> mCallback; RefPtr<Element> mRoot; nsCSSRect mRootMargin; nsTArray<double> mThresholds; - nsTHashtable<nsPtrHashKey<Element>> mObservationTargets; + + // Holds raw pointers which are explicitly cleared by UnlinkTarget(). + nsTArray<Element*> mObservationTargets; + nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries; bool mConnected; }; diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 79b36a314..5c3277e84 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -145,7 +145,6 @@ #include "mozilla/dom/KeyframeEffectBinding.h" #include "mozilla/dom/WindowBinding.h" #include "mozilla/dom/ElementBinding.h" -#include "mozilla/dom/VRDisplay.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Preferences.h" #include "nsComputedDOMStyle.h" @@ -688,19 +687,23 @@ Element::GetScrollFrame(nsIFrame **aStyledFrame, bool aFlushLayout) } void -Element::ScrollIntoView() +Element::ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject) { - ScrollIntoView(ScrollIntoViewOptions()); -} + if (aObject.IsScrollIntoViewOptions()) { + return ScrollIntoView(aObject.GetAsScrollIntoViewOptions()); + } + + MOZ_DIAGNOSTIC_ASSERT(aObject.IsBoolean()); -void -Element::ScrollIntoView(bool aTop) -{ ScrollIntoViewOptions options; - if (!aTop) { + if (aObject.GetAsBoolean()) { + options.mBlock = ScrollLogicalPosition::Start; + options.mInline = ScrollLogicalPosition::Nearest; + } else { options.mBlock = ScrollLogicalPosition::End; + options.mInline = ScrollLogicalPosition::Nearest; } - ScrollIntoView(options); + return ScrollIntoView(options); } void @@ -717,9 +720,41 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions) return; } - int16_t vpercent = (aOptions.mBlock == ScrollLogicalPosition::Start) - ? nsIPresShell::SCROLL_TOP - : nsIPresShell::SCROLL_BOTTOM; + int16_t vpercent = nsIPresShell::SCROLL_CENTER; + switch (aOptions.mBlock) { + case ScrollLogicalPosition::Start: + vpercent = nsIPresShell::SCROLL_TOP; + break; + case ScrollLogicalPosition::Center: + vpercent = nsIPresShell::SCROLL_CENTER; + break; + case ScrollLogicalPosition::End: + vpercent = nsIPresShell::SCROLL_BOTTOM; + break; + case ScrollLogicalPosition::Nearest: + vpercent = nsIPresShell::SCROLL_MINIMUM; + break; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value"); + } + + int16_t hpercent = nsIPresShell::SCROLL_CENTER; + switch (aOptions.mInline) { + case ScrollLogicalPosition::Start: + hpercent = nsIPresShell::SCROLL_LEFT; + break; + case ScrollLogicalPosition::Center: + hpercent = nsIPresShell::SCROLL_CENTER; + break; + case ScrollLogicalPosition::End: + hpercent = nsIPresShell::SCROLL_RIGHT; + break; + case ScrollLogicalPosition::Nearest: + hpercent = nsIPresShell::SCROLL_MINIMUM; + break; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected ScrollLogicalPosition value"); + } uint32_t flags = nsIPresShell::SCROLL_OVERFLOW_HIDDEN; if (aOptions.mBehavior == ScrollBehavior::Smooth) { @@ -732,7 +767,9 @@ Element::ScrollIntoView(const ScrollIntoViewOptions &aOptions) nsIPresShell::ScrollAxis( vpercent, nsIPresShell::SCROLL_ALWAYS), - nsIPresShell::ScrollAxis(), + nsIPresShell::ScrollAxis( + hpercent, + nsIPresShell::SCROLL_ALWAYS), flags); } @@ -3948,7 +3985,7 @@ Element::ClearDataset() slots->mDataset = nullptr; } -nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* +nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* Element::RegisteredIntersectionObservers() { nsDOMSlots* slots = DOMSlots(); @@ -3963,7 +4000,7 @@ enum nsPreviousIntersectionThreshold { void Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = + nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = RegisteredIntersectionObservers(); if (observers->Contains(aObserver)) { return; @@ -3980,7 +4017,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) void Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = + nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = RegisteredIntersectionObservers(); observers->Remove(aObserver); } @@ -3988,7 +4025,7 @@ Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) bool Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold) { - nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = + nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* observers = RegisteredIntersectionObservers(); if (!observers->Contains(aObserver)) { return false; diff --git a/dom/base/Element.h b/dom/base/Element.h index c269ab14a..ce84b74fb 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -818,9 +818,10 @@ public: return slots ? slots->mShadowRoot.get() : nullptr; } - void ScrollIntoView(); - void ScrollIntoView(bool aTop); +private: void ScrollIntoView(const ScrollIntoViewOptions &aOptions); +public: + void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject); void Scroll(double aXScroll, double aYScroll); void Scroll(const ScrollToOptions& aOptions); void ScrollTo(double aXScroll, double aYScroll); @@ -1382,7 +1383,8 @@ protected: nsDOMTokenList* GetTokenList(nsIAtom* aAtom, const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr); - nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t>* RegisteredIntersectionObservers(); + nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>* + RegisteredIntersectionObservers(); private: /** diff --git a/dom/base/File.cpp b/dom/base/File.cpp index 7d86dfe8a..1d5ab73e7 100755 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -138,7 +138,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Blob) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Blob) diff --git a/dom/base/FormData.cpp b/dom/base/FormData.cpp index 6095286be..52bdd9210 100644 --- a/dom/base/FormData.cpp +++ b/dom/base/FormData.cpp @@ -84,7 +84,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(FormData) "mFormData[i].GetAsBlob()", 0); } - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(FormData) diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index fde983e7c..9106778df 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -585,6 +585,12 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, mCustomElementData->mCallbackQueue[i]->Traverse(cb); } } + + for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { + DOMIntersectionObserver* observer = iter.Key(); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]"); + cb.NoteXPCOMChild(observer); + } } void @@ -1872,10 +1878,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement) NS_IMPL_CYCLE_COLLECTION_DESCRIBE(FragmentOrElement, tmp->mRefCnt.get()) } - // Always need to traverse script objects, so do that before we check - // if we're uncollectable. - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS - if (!nsINode::Traverse(tmp, cb)) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h index 7c74e9cd4..f0cc29f22 100644 --- a/dom/base/FragmentOrElement.h +++ b/dom/base/FragmentOrElement.h @@ -354,7 +354,8 @@ public: /** * Registered Intersection Observers on the element. */ - nsDataHashtable<nsPtrHashKey<DOMIntersectionObserver>, int32_t> mRegisteredIntersectionObservers; + nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t> + mRegisteredIntersectionObservers; }; protected: diff --git a/dom/base/Location.cpp b/dom/base/Location.cpp index 7b3722f09..1483c32f9 100644 --- a/dom/base/Location.cpp +++ b/dom/base/Location.cpp @@ -33,6 +33,7 @@ #include "nsCycleCollectionParticipant.h" #include "nsNullPrincipal.h" #include "ScriptSettings.h" +#include "mozilla/Unused.h" #include "mozilla/dom/LocationBinding.h" namespace mozilla { @@ -79,7 +80,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Location) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInnerWindow) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Location) @@ -716,9 +716,15 @@ Location::SetProtocol(const nsAString& aProtocol) return rv; } - rv = uri->SetScheme(NS_ConvertUTF16toUTF8(aProtocol)); + nsAString::const_iterator start, end; + aProtocol.BeginReading(start); + aProtocol.EndReading(end); + nsAString::const_iterator iter(start); + Unused << FindCharInReadable(':', iter, end); + + rv = uri->SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter))); if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; + return NS_ERROR_DOM_SYNTAX_ERR; } nsAutoCString newSpec; rv = uri->GetSpec(newSpec); @@ -728,9 +734,29 @@ Location::SetProtocol(const nsAString& aProtocol) // We may want a new URI class for the new URI, so recreate it: rv = NS_NewURI(getter_AddRefs(uri), newSpec); if (NS_FAILED(rv)) { + if (rv == NS_ERROR_MALFORMED_URI) { + rv = NS_ERROR_DOM_SYNTAX_ERR; + } + return rv; + } + + bool isHttp; + rv = uri->SchemeIs("http", &isHttp); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + bool isHttps; + rv = uri->SchemeIs("https", &isHttps); + if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } + if (!isHttp && !isHttps) { + // No-op, per spec. + return NS_OK; + } + return SetURI(uri); } @@ -763,10 +789,6 @@ Location::GetSearch(nsAString& aSearch) NS_IMETHODIMP Location::SetSearch(const nsAString& aSearch) { - if (aSearch.IsEmpty()) { - return NS_OK; // Ignore empty string - } - nsresult rv = SetSearchInternal(aSearch); if (NS_FAILED(rv)) { return rv; diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index ed96ee23b..fdf151b6c 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -44,7 +44,6 @@ #include "mozilla/dom/ServiceWorkerContainer.h" #include "mozilla/dom/StorageManager.h" #include "mozilla/dom/TCPSocket.h" -#include "mozilla/dom/VRDisplay.h" #include "mozilla/dom/workers/RuntimeService.h" #include "mozilla/Hal.h" #include "nsISiteSpecificUserAgent.h" @@ -224,7 +223,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest) #endif NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDisplaysPromises) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Navigator) @@ -684,8 +682,6 @@ Navigator::GetDoNotTrack(nsAString &aResult) bool Navigator::JavaEnabled(ErrorResult& aRv) { - Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer; - // Return true if we have a handler for the java mime nsAdoptingString javaMIME = Preferences::GetString("plugin.java.mime"); NS_ENSURE_TRUE(!javaMIME.IsEmpty(), false); @@ -1473,83 +1469,6 @@ Navigator::RequestGamepadServiceTest() } #endif -already_AddRefed<Promise> -Navigator::GetVRDisplays(ErrorResult& aRv) -{ - if (!mWindow || !mWindow->GetDocShell()) { - aRv.Throw(NS_ERROR_UNEXPECTED); - return nullptr; - } - - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); - win->NotifyVREventListenerAdded(); - - nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow); - RefPtr<Promise> p = Promise::Create(go, aRv); - if (aRv.Failed()) { - return nullptr; - } - - // We pass mWindow's id to RefreshVRDisplays, so NotifyVRDisplaysUpdated will - // be called asynchronously, resolving the promises in mVRGetDisplaysPromises. - if (!VRDisplay::RefreshVRDisplays(win->WindowID())) { - p->MaybeReject(NS_ERROR_FAILURE); - return p.forget(); - } - - mVRGetDisplaysPromises.AppendElement(p); - return p.forget(); -} - -void -Navigator::GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const -{ - /** - * Get only the active VR displays. - * Callers do not wish to VRDisplay::RefreshVRDisplays, as the enumeration may - * activate hardware that is not yet intended to be used. - */ - if (!mWindow || !mWindow->GetDocShell()) { - return; - } - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); - win->NotifyVREventListenerAdded(); - nsTArray<RefPtr<VRDisplay>> displays; - if (win->UpdateVRDisplays(displays)) { - for (auto display : displays) { - if (display->IsPresenting()) { - aDisplays.AppendElement(display); - } - } - } -} - -void -Navigator::NotifyVRDisplaysUpdated() -{ - // Synchronize the VR devices and resolve the promises in - // mVRGetDisplaysPromises - nsGlobalWindow* win = nsGlobalWindow::Cast(mWindow); - - nsTArray<RefPtr<VRDisplay>> vrDisplays; - if (win->UpdateVRDisplays(vrDisplays)) { - for (auto p : mVRGetDisplaysPromises) { - p->MaybeResolve(vrDisplays); - } - } else { - for (auto p : mVRGetDisplaysPromises) { - p->MaybeReject(NS_ERROR_FAILURE); - } - } - mVRGetDisplaysPromises.Clear(); -} - -void -Navigator::NotifyActiveVRDisplaysChanged() -{ - NavigatorBinding::ClearCachedActiveVRDisplaysValue(this); -} - //***************************************************************************** // Navigator::nsIMozNavigatorNetwork //***************************************************************************** diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index d47a80bc1..91b7fc15c 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -76,7 +76,6 @@ class Connection; class PowerManager; class Presentation; class LegacyMozTCPSocket; -class VRDisplay; class StorageManager; namespace time { @@ -204,8 +203,6 @@ public: void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv); GamepadServiceTest* RequestGamepadServiceTest(); #endif // MOZ_GAMEPAD - already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv); - void GetActiveVRDisplays(nsTArray<RefPtr<VRDisplay>>& aDisplays) const; #ifdef MOZ_TIME_MANAGER time::TimeManager* GetMozTime(ErrorResult& aRv); #endif // MOZ_TIME_MANAGER @@ -269,10 +266,6 @@ private: RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager; #endif -public: - void NotifyVRDisplaysUpdated(); - void NotifyActiveVRDisplaysChanged(); - private: virtual ~Navigator(); diff --git a/dom/base/Pose.cpp b/dom/base/Pose.cpp index 1eab4c173..5bc4ca6de 100644 --- a/dom/base/Pose.cpp +++ b/dom/base/Pose.cpp @@ -26,7 +26,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Pose) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Pose) diff --git a/dom/base/ProcessGlobal.cpp b/dom/base/ProcessGlobal.cpp index 641f49f98..6cd29ab7c 100644 --- a/dom/base/ProcessGlobal.cpp +++ b/dom/base/ProcessGlobal.cpp @@ -52,7 +52,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ProcessGlobal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal) tmp->TraverseHostObjectURIs(cb); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ProcessGlobal) diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp index b285ee003..9fd27262b 100644 --- a/dom/base/nsAttrAndChildArray.cpp +++ b/dom/base/nsAttrAndChildArray.cpp @@ -78,15 +78,8 @@ GetIndexFromCache(const nsAttrAndChildArray* aArray) } -/** - * Due to a compiler bug in VisualAge C++ for AIX, we need to return the - * address of the first index into mBuffer here, instead of simply returning - * mBuffer itself. - * - * See Bug 231104 for more information. - */ #define ATTRS(_impl) \ - reinterpret_cast<InternalAttr*>(&((_impl)->mBuffer[0])) + reinterpret_cast<InternalAttr*>((_impl)->mBuffer) #define NS_IMPL_EXTRA_SIZE \ diff --git a/dom/base/nsCCUncollectableMarker.cpp b/dom/base/nsCCUncollectableMarker.cpp index 861cda521..db4d0d351 100644 --- a/dom/base/nsCCUncollectableMarker.cpp +++ b/dom/base/nsCCUncollectableMarker.cpp @@ -188,23 +188,20 @@ MarkMessageManagers() } void -MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS, - bool aPrepareForCC) +MarkDocument(nsIDocument* aDoc, bool aCleanupJS, bool aPrepareForCC) { - if (!aViewer) { + if (!aDoc) { return; } - nsIDocument *doc = aViewer->GetDocument(); - if (doc && - doc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) { - doc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); + if (aDoc->GetMarkedCCGeneration() != nsCCUncollectableMarker::sGeneration) { + aDoc->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); if (aCleanupJS) { - EventListenerManager* elm = doc->GetExistingListenerManager(); + EventListenerManager* elm = aDoc->GetExistingListenerManager(); if (elm) { elm->MarkForCC(); } - nsCOMPtr<EventTarget> win = do_QueryInterface(doc->GetInnerWindow()); + nsCOMPtr<EventTarget> win = do_QueryInterface(aDoc->GetInnerWindow()); if (win) { elm = win->GetExistingListenerManager(); if (elm) { @@ -215,18 +212,27 @@ MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS, } else if (aPrepareForCC) { // Unfortunately we need to still mark user data just before running CC so // that it has the right generation. - doc->PropertyTable(DOM_USER_DATA)-> + aDoc->PropertyTable(DOM_USER_DATA)-> EnumerateAll(MarkUserData, &nsCCUncollectableMarker::sGeneration); } } - if (doc) { - if (nsPIDOMWindowInner* inner = doc->GetInnerWindow()) { - inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); - } - if (nsPIDOMWindowOuter* outer = doc->GetWindow()) { - outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); - } + if (nsPIDOMWindowInner* inner = aDoc->GetInnerWindow()) { + inner->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); + } + if (nsPIDOMWindowOuter* outer = aDoc->GetWindow()) { + outer->MarkUncollectableForCCGeneration(nsCCUncollectableMarker::sGeneration); + } +} + +void +MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS, + bool aPrepareForCC) +{ + if (!aViewer) { + return; } + + MarkDocument(aViewer->GetDocument(), aCleanupJS, aPrepareForCC); } void MarkDocShell(nsIDocShellTreeItem* aNode, bool aCleanupJS, diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 43e65777d..c98859ee3 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -54,7 +54,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElements) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsBaseContentList) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 34c7d23b8..3696195dd 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7597,6 +7597,24 @@ nsContentUtils::IsFileImage(nsIFile* aFile, nsACString& aType) } nsresult +nsContentUtils::CalculateBufferSizeForImage(const uint32_t& aStride, + const IntSize& aImageSize, + const SurfaceFormat& aFormat, + size_t* aMaxBufferSize, + size_t* aUsedBufferSize) +{ + CheckedInt32 requiredBytes = + CheckedInt32(aStride) * CheckedInt32(aImageSize.height); + if (!requiredBytes.isValid()) { + return NS_ERROR_FAILURE; + } + *aMaxBufferSize = requiredBytes.value(); + *aUsedBufferSize = *aMaxBufferSize - aStride + + (aImageSize.width * BytesPerPixel(aFormat)); + return NS_OK; +} + +nsresult nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem, imgIContainer** aContainer) { @@ -7611,6 +7629,22 @@ nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem, Shmem data = aItem.data().get_Shmem(); + // Validate shared memory buffer size + size_t imageBufLen = 0; + size_t maxBufLen = 0; + nsresult rv = CalculateBufferSizeForImage(imageDetails.stride(), + size, + static_cast<SurfaceFormat>( + imageDetails.format()), + &maxBufLen, + &imageBufLen); + if (NS_FAILED(rv)) { + return rv; + } + if (imageBufLen > data.Size<uint8_t>()) { + return NS_ERROR_FAILURE; + } + RefPtr<DataSourceSurface> image = CreateDataSourceSurfaceFromData(size, static_cast<SurfaceFormat>(imageDetails.format()), @@ -7950,20 +7984,19 @@ GetSurfaceDataImpl(mozilla::gfx::DataSourceSurface* aSurface, return GetSurfaceDataContext::NullValue(); } - mozilla::gfx::IntSize size = aSurface->GetSize(); - mozilla::CheckedInt32 requiredBytes = - mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height); - if (!requiredBytes.isValid()) { + size_t bufLen = 0; + size_t maxBufLen = 0; + nsresult rv = nsContentUtils::CalculateBufferSizeForImage(map.mStride, + aSurface->GetSize(), + aSurface->GetFormat(), + &maxBufLen, + &bufLen); + if (NS_FAILED(rv)) { + // Release mapped memory + aSurface->Unmap(); return GetSurfaceDataContext::NullValue(); } - size_t maxBufLen = requiredBytes.value(); - mozilla::gfx::SurfaceFormat format = aSurface->GetFormat(); - - // Surface data handling is totally nuts. This is the magic one needs to - // know to access the data. - size_t bufLen = maxBufLen - map.mStride + (size.width * BytesPerPixel(format)); - // nsDependentCString wants null-terminated string. typename GetSurfaceDataContext::ReturnType surfaceData = aContext.Allocate(maxBufLen + 1); if (GetSurfaceDataContext::GetBuffer(surfaceData)) { @@ -9787,3 +9820,19 @@ nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel) return reloadSucceeded; } + +/* static */ bool +nsContentUtils::IsLocalRefURL(const nsString& aString) +{ + // Find the first non-"C0 controls + space" character. + const char16_t* current = aString.get(); + for (; *current != '\0'; current++) { + if (*current > 0x20) { + // if the first non-"C0 controls + space" character is '#', this is a + // local-ref URL. + return *current == '#'; + } + } + + return false; +}
\ No newline at end of file diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 9ae6d2155..299a8e859 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -13,10 +13,6 @@ #include <float.h> #endif -#if defined(SOLARIS) -#include <ieeefp.h> -#endif - #include "js/TypeDecls.h" #include "js/Value.h" #include "js/RootingAPI.h" @@ -975,11 +971,17 @@ public: static bool PrefetchEnabled(nsIDocShell* aDocShell); + static nsresult CalculateBufferSizeForImage(const uint32_t& aStride, + const mozilla::gfx::IntSize& aImageSize, + const mozilla::gfx::SurfaceFormat& aFormat, + size_t* aMaxBufferSize, + size_t* aUsedBufferSize); + +private: /** * Fill (with the parameters given) the localized string named |aKey| in * properties file |aFile|. */ -private: static nsresult FormatLocalizedString(PropertiesFile aFile, const char* aKey, const char16_t** aParams, @@ -2730,6 +2732,13 @@ public: static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel); + /** + * Detect whether a string is a (CSS) local-url. + * https://drafts.csswg.org/css-values/#local-urls + */ + static bool + IsLocalRefURL(const nsString& aString); + private: static bool InitializeEventTable(); diff --git a/dom/base/nsDOMAttributeMap.cpp b/dom/base/nsDOMAttributeMap.cpp index 381f267cd..2a90df7e4 100644 --- a/dom/base/nsDOMAttributeMap.cpp +++ b/dom/base/nsDOMAttributeMap.cpp @@ -65,7 +65,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttributeMap) for (auto iter = tmp->mAttributeCache.Iter(); !iter.Done(); iter.Next()) { cb.NoteXPCOMChild(static_cast<nsINode*>(iter.Data().get())); } - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index d125e5ad1..1cfde6e1b 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -49,7 +49,6 @@ #include "nsContentUtils.h" #include "nsIDOMGlobalPropertyInitializer.h" #include "mozilla/Attributes.h" -#include "mozilla/Telemetry.h" // Window scriptable helper includes #include "nsScriptNameSpaceManager.h" @@ -1903,9 +1902,6 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global, nsPIDOMWindowInner *win, JS::MutableHandle<JS::PropertyDescriptor> desc) { - // Keep track of how often this happens. - Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true); - // Warn once. nsCOMPtr<nsIDocument> doc = win->GetExtantDoc(); if (doc) { diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 024ce5e2e..858a30ce5 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -506,7 +506,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationObserver) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReceivers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFirstPendingMutation) diff --git a/dom/base/nsDOMNavigationTiming.cpp b/dom/base/nsDOMNavigationTiming.cpp index 32ce8a8cb..9c732f2d8 100644 --- a/dom/base/nsDOMNavigationTiming.cpp +++ b/dom/base/nsDOMNavigationTiming.cpp @@ -15,7 +15,6 @@ #include "nsPrintfCString.h" #include "mozilla/dom/PerformanceNavigation.h" #include "mozilla/TimeStamp.h" -#include "mozilla/Telemetry.h" using namespace mozilla; @@ -203,12 +202,6 @@ nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument() mDocShellHasBeenActiveSinceNavigationStart ? "foreground tab" : "this tab was inactive some of the time between navigation start and first non-blank paint"); PROFILER_MARKER(marker.get()); } - - if (mDocShellHasBeenActiveSinceNavigationStart) { - Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_NON_BLANK_PAINT_MS, - mNavigationStart, - mNonBlankPaint); - } } void diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 291df5f27..2ab5937ac 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -4033,8 +4033,6 @@ nsDOMWindowUtils::ForceUseCounterFlush(nsIDOMNode *aNode) if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) { mozilla::css::ImageLoader* loader = doc->StyleImageLoader(); loader->FlushUseCounters(); - - static_cast<nsDocument*>(doc.get())->ReportUseCounters(); return NS_OK; } diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 8acfd901a..a6ed419df 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -25,7 +25,6 @@ #include "plstr.h" #include "mozilla/Sprintf.h" -#include "mozilla/Telemetry.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsILoadContext.h" @@ -1396,63 +1395,6 @@ nsDocument::~nsDocument() NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document"); - if (IsTopLevelContentDocument()) { - //don't report for about: pages - if (!IsAboutPage()) { - // Record the page load - uint32_t pageLoaded = 1; - Accumulate(Telemetry::MIXED_CONTENT_UNBLOCK_COUNTER, pageLoaded); - // Record the mixed content status of the docshell in Telemetry - enum { - NO_MIXED_CONTENT = 0, // There is no Mixed Content on the page - MIXED_DISPLAY_CONTENT = 1, // The page attempted to load Mixed Display Content - MIXED_ACTIVE_CONTENT = 2, // The page attempted to load Mixed Active Content - MIXED_DISPLAY_AND_ACTIVE_CONTENT = 3 // The page attempted to load Mixed Display & Mixed Active Content - }; - - bool mixedActiveLoaded = GetHasMixedActiveContentLoaded(); - bool mixedActiveBlocked = GetHasMixedActiveContentBlocked(); - - bool mixedDisplayLoaded = GetHasMixedDisplayContentLoaded(); - bool mixedDisplayBlocked = GetHasMixedDisplayContentBlocked(); - - bool hasMixedDisplay = (mixedDisplayBlocked || mixedDisplayLoaded); - bool hasMixedActive = (mixedActiveBlocked || mixedActiveLoaded); - - uint32_t mixedContentLevel = NO_MIXED_CONTENT; - if (hasMixedDisplay && hasMixedActive) { - mixedContentLevel = MIXED_DISPLAY_AND_ACTIVE_CONTENT; - } else if (hasMixedActive){ - mixedContentLevel = MIXED_ACTIVE_CONTENT; - } else if (hasMixedDisplay) { - mixedContentLevel = MIXED_DISPLAY_CONTENT; - } - Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel); - - // record mixed object subrequest telemetry - if (mHasMixedContentObjectSubrequest) { - /* mixed object subrequest loaded on page*/ - Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 1); - } else { - /* no mixed object subrequests loaded on page*/ - Accumulate(Telemetry::MIXED_CONTENT_OBJECT_SUBREQUEST, 0); - } - - // record CSP telemetry on this document - if (mHasCSP) { - Accumulate(Telemetry::CSP_DOCUMENTS_COUNT, 1); - } - if (mHasUnsafeInlineCSP) { - Accumulate(Telemetry::CSP_UNSAFE_INLINE_DOCUMENTS_COUNT, 1); - } - if (mHasUnsafeEvalCSP) { - Accumulate(Telemetry::CSP_UNSAFE_EVAL_DOCUMENTS_COUNT, 1); - } - } - } - - ReportUseCounters(); - mInDestructor = true; mInUnlinkOrDeletion = true; @@ -1648,10 +1590,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument) NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsDocument, tmp->mRefCnt.get()) } - // Always need to traverse script objects, so do that before we check - // if we're uncollectable. - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS - if (!nsINode::Traverse(tmp, cb)) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } @@ -1737,8 +1675,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntersectionObservers) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks) for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) { @@ -12356,134 +12292,27 @@ nsIDocument::InlineScriptAllowedByCSP() return allowsInlineScript; } -static bool -MightBeAboutOrChromeScheme(nsIURI* aURI) -{ - MOZ_ASSERT(aURI); - bool isAbout = true; - bool isChrome = true; - aURI->SchemeIs("about", &isAbout); - aURI->SchemeIs("chrome", &isChrome); - return isAbout || isChrome; -} - -void -nsDocument::ReportUseCounters() -{ - static const bool sDebugUseCounters = false; - if (mReportedUseCounters) { - return; - } - - mReportedUseCounters = true; - - if (Telemetry::HistogramUseCounterCount > 0 && - (IsContentDocument() || IsResourceDoc())) { - nsCOMPtr<nsIURI> uri; - NodePrincipal()->GetURI(getter_AddRefs(uri)); - if (!uri || MightBeAboutOrChromeScheme(uri)) { - return; - } - - if (sDebugUseCounters) { - nsCString spec = uri->GetSpecOrDefault(); - - // URIs can be rather long for data documents, so truncate them to - // some reasonable length. - spec.Truncate(std::min(128U, spec.Length())); - printf("-- Use counters for %s --\n", spec.get()); - } - - // We keep separate counts for individual documents and top-level - // pages to more accurately track how many web pages might break if - // certain features were removed. Consider the case of a single - // HTML document with several SVG images and/or iframes with - // sub-documents of their own. If we maintained a single set of use - // counters and all the sub-documents use a particular feature, then - // telemetry would indicate that we would be breaking N documents if - // that feature were removed. Whereas with a document/top-level - // page split, we can see that N documents would be affected, but - // only a single web page would be affected. - - // The difference between the values of these two histograms and the - // related use counters below tell us how many pages did *not* use - // the feature in question. For instance, if we see that a given - // session has destroyed 30 content documents, but a particular use - // counter shows only a count of 5, we can infer that the use - // counter was *not* used in 25 of those 30 documents. - // - // We do things this way, rather than accumulating a boolean flag - // for each use counter, to avoid sending histograms for features - // that don't get widely used. Doing things in this fashion means - // smaller telemetry payloads and faster processing on the server - // side. - Telemetry::Accumulate(Telemetry::CONTENT_DOCUMENTS_DESTROYED, 1); - if (IsTopLevelContentDocument()) { - Telemetry::Accumulate(Telemetry::TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED, 1); - } - - for (int32_t c = 0; - c < eUseCounter_Count; ++c) { - UseCounter uc = static_cast<UseCounter>(c); - - Telemetry::ID id = - static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter + uc * 2); - bool value = GetUseCounter(uc); - - if (value) { - if (sDebugUseCounters) { - const char* name = Telemetry::GetHistogramName(id); - if (name) { - printf(" %s", name); - } else { - printf(" #%d", id); - } - printf(": %d\n", value); - } - - Telemetry::Accumulate(id, 1); - } - - if (IsTopLevelContentDocument()) { - id = static_cast<Telemetry::ID>(Telemetry::HistogramFirstUseCounter + - uc * 2 + 1); - value = GetUseCounter(uc) || GetChildDocumentUseCounter(uc); - - if (value) { - if (sDebugUseCounters) { - const char* name = Telemetry::GetHistogramName(id); - if (name) { - printf(" %s", name); - } else { - printf(" #%d", id); - } - printf(": %d\n", value); - } - - Telemetry::Accumulate(id, 1); - } - } - } - } -} - void nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver) { - NS_ASSERTION(mIntersectionObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex, - "Intersection observer already in the list"); - mIntersectionObservers.AppendElement(aObserver); + MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver), + "Intersection observer already in the list"); + mIntersectionObservers.PutEntry(aObserver); } void nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver) { - mIntersectionObservers.RemoveElement(aObserver); + mIntersectionObservers.RemoveEntry(aObserver); } void nsDocument::UpdateIntersectionObservations() { + if (mIntersectionObservers.IsEmpty()) { + return; + } + DOMHighResTimeStamp time = 0; if (nsPIDOMWindowInner* window = GetInnerWindow()) { Performance* perf = window->GetPerformance(); @@ -12491,25 +12320,42 @@ nsDocument::UpdateIntersectionObservations() time = perf->Now(); } } - for (const auto& observer : mIntersectionObservers) { - observer->Update(this, time); + 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) { + observer->Update(this, time); + } } } void nsDocument::ScheduleIntersectionObserverNotification() { + if (mIntersectionObservers.IsEmpty()) { + return; + } + nsCOMPtr<nsIRunnable> notification = NewRunnableMethod(this, &nsDocument::NotifyIntersectionObservers); - NS_DispatchToCurrentThread(notification); + NS_DispatchToCurrentThread(notification.forget()); } void nsDocument::NotifyIntersectionObservers() { - nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers); + 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) { - observer->Notify(); + if (observer) { + observer->Notify(); + } } } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 3725b3c18..95fd57545 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -774,8 +774,6 @@ public: virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) override; - void ReportUseCounters(); - virtual void AddIntersectionObserver( mozilla::dom::DOMIntersectionObserver* aObserver) override; virtual void RemoveIntersectionObserver( @@ -1341,8 +1339,9 @@ protected: // Array of observers nsTObserverArray<nsIDocumentObserver*> mObservers; - // Array of intersection observers - nsTArray<RefPtr<mozilla::dom::DOMIntersectionObserver>> mIntersectionObservers; + // Hashtable of intersection observers + nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>> + mIntersectionObservers; // Tracker for animations that are waiting to start. // nullptr until GetOrCreatePendingAnimationTracker is called. @@ -1448,14 +1447,6 @@ public: // 'style-sheet-applicable-state-changed' notification. bool mSSApplicableStateNotificationPending:1; - // Whether we have reported use counters for this document with Telemetry yet. - // Normally this is only done at document destruction time, but for image - // documents (SVG documents) that are not guaranteed to be destroyed, we - // report use counters when the image cache no longer has any imgRequestProxys - // pointing to them. We track whether we ever reported use counters so - // that we only report them once for the document. - bool mReportedUseCounters:1; - // Whether we have filled our pres shell's style set with the document's // additional sheets and sheets from the nsStyleSheetService. bool mStyleSetFilled:1; diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 23067becd..2804f2d4c 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -588,6 +588,9 @@ nsFrameLoader::ReallyStartLoadingInternal() flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL; } + + // Notify that this load resulted from attribute changes. + loadInfo->SetIsFromProcessingFrameAttributes(true); // Kick off the load... bool tmpState = mNeedsAsyncDestroy; diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index 6fffd376b..bba4232aa 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -32,7 +32,6 @@ #include "mozilla/CycleCollectedJSContext.h" #include "mozilla/IntentionalCrash.h" #include "mozilla/Preferences.h" -#include "mozilla/Telemetry.h" #include "mozilla/dom/File.h" #include "mozilla/dom/MessagePort.h" #include "mozilla/dom/nsIContentParent.h" @@ -133,7 +132,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager) } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildManagers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentManager) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFrameMessageManager) @@ -707,18 +705,9 @@ nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName, static bool AllowMessage(size_t aDataLength, const nsAString& aMessageName) { - static const size_t kMinTelemetryMessageSize = 8192; - - if (aDataLength < kMinTelemetryMessageSize) { - return true; - } - NS_ConvertUTF16toUTF8 messageName(aMessageName); messageName.StripChars("0123456789"); - Telemetry::Accumulate(Telemetry::MESSAGE_MANAGER_MESSAGE_SIZE2, messageName, - aDataLength); - // A message includes more than structured clone data, so subtract // 20KB to make it more likely that a message within this bound won't // result in an overly large IPC message. @@ -727,9 +716,6 @@ AllowMessage(size_t aDataLength, const nsAString& aMessageName) return true; } - Telemetry::Accumulate(Telemetry::REJECTED_MESSAGE_MANAGER_MESSAGE, - messageName); - return false; } @@ -2248,7 +2234,6 @@ nsSameProcessAsyncMessageBase::Init(const nsAString& aMessage, nsIPrincipal* aPrincipal) { if (!mData.Copy(aData)) { - Telemetry::Accumulate(Telemetry::IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB, aData.DataLength()); return NS_ERROR_OUT_OF_MEMORY; } diff --git a/dom/base/nsGenericDOMDataNode.cpp b/dom/base/nsGenericDOMDataNode.cpp index 9688588e0..0ae15e09e 100644 --- a/dom/base/nsGenericDOMDataNode.cpp +++ b/dom/base/nsGenericDOMDataNode.cpp @@ -98,10 +98,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericDOMDataNode) NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsGenericDOMDataNode, tmp->mRefCnt.get()) } - // Always need to traverse script objects, so do that before we check - // if we're uncollectable. - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS - if (!nsINode::Traverse(tmp, cb)) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 884ad69ca..ac85e34c0 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -202,16 +202,12 @@ #include "mozilla/dom/GamepadManager.h" #endif -#include "mozilla/dom/VRDisplay.h" -#include "mozilla/dom/VREventObserver.h" - #include "nsRefreshDriver.h" #include "Layers.h" #include "mozilla/AddonPathService.h" #include "mozilla/BasePrincipal.h" #include "mozilla/Services.h" -#include "mozilla/Telemetry.h" #include "mozilla/dom/Location.h" #include "nsHTMLDocument.h" #include "nsWrapperCacheInlines.h" @@ -292,7 +288,6 @@ static bool gMouseDown = false; static bool gDragServiceDisabled = false; static FILE *gDumpFile = nullptr; static uint32_t gSerialCounter = 0; -static TimeStamp gLastRecordedRecentTimeouts; #define STATISTICS_INTERVAL (30 * PR_MSEC_PER_SEC) #ifdef DEBUG_jst @@ -1522,7 +1517,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mIsPopupSpam(false), mBlockScriptedClosingFlag(false), mWasOffline(false), - mHasHadSlowScript(false), mNotifyIdleObserversIdleOnThaw(false), mNotifyIdleObserversActiveOnThaw(false), mCreatingInnerWindow(false), @@ -1533,7 +1527,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mShowFocusRingForContent(false), mFocusByKeyOccurred(false), mHasGamepad(false), - mHasVREvents(false), #ifdef MOZ_GAMEPAD mHasSeenGamepadInput(false), #endif @@ -1759,9 +1752,6 @@ nsGlobalWindow::~nsGlobalWindow() DropOuterWindowDocs(); } else { - Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS, - mMutationBits ? 1 : 0); - if (mListenerManager) { mListenerManager->Disconnect(); mListenerManager = nullptr; @@ -1971,12 +1961,9 @@ nsGlobalWindow::CleanUp() if (IsInnerWindow()) { DisableGamepadUpdates(); mHasGamepad = false; - DisableVRUpdates(); - mHasVREvents = false; DisableIdleCallbackRequests(); } else { MOZ_ASSERT(!mHasGamepad); - MOZ_ASSERT(!mHasVREvents); } if (mCleanMessageManager) { @@ -2027,7 +2014,7 @@ nsGlobalWindow::ClearControllers() } void -nsGlobalWindow::FreeInnerObjects() +nsGlobalWindow::FreeInnerObjects(bool aForDocumentOpen) { NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window"); @@ -2086,8 +2073,10 @@ nsGlobalWindow::FreeInnerObjects() mDocumentURI = mDoc->GetDocumentURI(); mDocBaseURI = mDoc->GetDocBaseURI(); - while (mDoc->EventHandlingSuppressed()) { - mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false); + if (!aForDocumentOpen) { + while (mDoc->EventHandlingSuppressed()) { + mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false); + } } // Note: we don't have to worry about eAnimationsOnly suppressions because @@ -2120,9 +2109,6 @@ nsGlobalWindow::FreeInnerObjects() mHasGamepad = false; mGamepads.Clear(); #endif - DisableVRUpdates(); - mHasVREvents = false; - mVRDisplays.Clear(); } //***************************************************************************** @@ -2277,7 +2263,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow) #endif NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays) // Traverse stuff from nsPIDOMWindow NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler) @@ -2299,7 +2284,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow) tmp->TraverseHostObjectURIs(cb); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow) @@ -2354,7 +2338,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow) #endif NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays) // Unlink stuff from nsPIDOMWindow NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler) @@ -2695,7 +2678,6 @@ TreatAsRemoteXUL(nsIPrincipal* aPrincipal) static bool EnablePrivilege(JSContext* cx, unsigned argc, JS::Value* vp) { - Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true); return xpc::EnableUniversalXPConnect(cx); } @@ -3005,6 +2987,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState); NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?"); + bool handleDocumentOpen = false; + JS::Rooted<JSObject*> newInnerGlobal(cx); if (reUseInnerWindow) { // We're reusing the current inner window. @@ -3096,6 +3080,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, if (currentInner && currentInner->GetWrapperPreserveColor()) { if (oldDoc == aDocument) { + handleDocumentOpen = true; // Move the navigator from the old inner window to the new one since // this is a document.write. This is safe from a same-origin point of // view because document.write can only be used by the same origin. @@ -3120,7 +3105,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, // Don't free objects on our current inner window if it's going to be // held in the bfcache. if (!currentInner->IsFrozen()) { - currentInner->FreeInnerObjects(); + currentInner->FreeInnerObjects(handleDocumentOpen); } } @@ -3389,9 +3374,6 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument) mLastOpenedURI = aDocument->GetDocumentURI(); #endif - Telemetry::Accumulate(Telemetry::INNERWINDOWS_WITH_MUTATION_LISTENERS, - mMutationBits ? 1 : 0); - // Clear our mutation bitfield. mMutationBits = 0; } @@ -6848,8 +6830,6 @@ FullscreenTransitionTask::Run() Preferences::GetUint("full-screen-api.transition.timeout", 1000); mTimer->Init(observer, timeout, nsITimer::TYPE_ONE_SHOT); } else if (stage == eAfterToggle) { - Telemetry::AccumulateTimeDelta(Telemetry::FULLSCREEN_TRANSITION_BLACK_MS, - mFullscreenChangeStartTime); mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle, mDuration.mFadeOut, mTransitionData, this); @@ -10513,24 +10493,6 @@ nsGlobalWindow::DisableGamepadUpdates() } void -nsGlobalWindow::EnableVRUpdates() -{ - MOZ_ASSERT(IsInnerWindow()); - - if (mHasVREvents && !mVREventObserver) { - mVREventObserver = new VREventObserver(this); - } -} - -void -nsGlobalWindow::DisableVRUpdates() -{ - MOZ_ASSERT(IsInnerWindow()); - - mVREventObserver = nullptr; -} - -void nsGlobalWindow::SetChromeEventHandler(EventTarget* aChromeEventHandler) { MOZ_ASSERT(IsOuterWindow()); @@ -11577,13 +11539,6 @@ nsGlobalWindow::ShowSlowScriptDialog() unsigned lineno; bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno); - // Record the slow script event if we haven't done so already for this inner window - // (which represents a particular page to the user). - if (!mHasHadSlowScript) { - Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_PAGE_COUNT, 1); - } - mHasHadSlowScript = true; - if (XRE_IsContentProcess() && ProcessHangMonitor::Get()) { ProcessHangMonitor::SlowScriptAction action; @@ -11613,10 +11568,6 @@ nsGlobalWindow::ShowSlowScriptDialog() return ContinueSlowScriptAndKeepNotifying; } - // Reached only on non-e10s - once per slow script dialog. - // On e10s - we probe once at ProcessHangsMonitor.jsm - Telemetry::Accumulate(Telemetry::SLOW_SCRIPT_NOTICE_COUNT, 1); - // Get the nsIPrompt interface from the docshell nsCOMPtr<nsIDocShell> ds = GetDocShell(); NS_ENSURE_TRUE(ds, KillSlowScript); @@ -12224,7 +12175,6 @@ nsGlobalWindow::Suspend() ac->RemoveWindowListener(mEnabledSensors[i], this); } DisableGamepadUpdates(); - DisableVRUpdates(); mozilla::dom::workers::SuspendWorkersForWindow(AsInner()); @@ -12288,7 +12238,6 @@ nsGlobalWindow::Resume() ac->AddWindowListener(mEnabledSensors[i], this); } EnableGamepadUpdates(); - EnableVRUpdates(); // Resume all of the AudioContexts for this window for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { @@ -13445,13 +13394,6 @@ nsGlobalWindow::RunTimeout(Timeout* aTimeout) return; } - // Record telemetry information about timers set recently. - TimeDuration recordingInterval = TimeDuration::FromMilliseconds(STATISTICS_INTERVAL); - if (gLastRecordedRecentTimeouts.IsNull() || - now - gLastRecordedRecentTimeouts > recordingInterval) { - gLastRecordedRecentTimeouts = now; - } - // Insert a dummy timeout into the list of timeouts between the // portion of the list that we are about to process now and those // timeouts that will be processed in a future call to @@ -14044,19 +13986,6 @@ nsGlobalWindow::SetHasGamepadEventListener(bool aHasGamepad/* = true*/) void nsGlobalWindow::EventListenerAdded(nsIAtom* aType) { - if (aType == nsGkAtoms::onvrdisplayconnect || - aType == nsGkAtoms::onvrdisplaydisconnect || - aType == nsGkAtoms::onvrdisplaypresentchange) { - NotifyVREventListenerAdded(); - } -} - -void -nsGlobalWindow::NotifyVREventListenerAdded() -{ - MOZ_ASSERT(IsInnerWindow()); - mHasVREvents = true; - EnableVRUpdates(); } void @@ -14201,27 +14130,6 @@ nsGlobalWindow::SyncGamepadState() } #endif // MOZ_GAMEPAD -bool -nsGlobalWindow::UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDevices) -{ - FORWARD_TO_INNER(UpdateVRDisplays, (aDevices), false); - - VRDisplay::UpdateVRDisplays(mVRDisplays, AsInner()); - aDevices = mVRDisplays; - return true; -} - -void -nsGlobalWindow::NotifyActiveVRDisplaysChanged() -{ - MOZ_ASSERT(IsInnerWindow()); - - if (mNavigator) { - mNavigator->NotifyActiveVRDisplaysChanged(); - } -} - - // nsGlobalChromeWindow implementation NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow) diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 467bc6796..1f420895c 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -135,8 +135,6 @@ class SpeechSynthesis; class TabGroup; class Timeout; class U2F; -class VRDisplay; -class VREventObserver; class WakeLock; #if defined(MOZ_WIDGET_ANDROID) class WindowOrientationObserver; @@ -745,18 +743,6 @@ public: void EnableGamepadUpdates(); void DisableGamepadUpdates(); - // Inner windows only. - // Enable/disable updates for VR - void EnableVRUpdates(); - void DisableVRUpdates(); - - // Update the VR displays for this window - bool UpdateVRDisplays(nsTArray<RefPtr<mozilla::dom::VRDisplay>>& aDisplays); - - // Inner windows only. - // Called to inform that the set of active VR displays has changed. - void NotifyActiveVRDisplaysChanged(); - #define EVENT(name_, id_, type_, struct_) \ mozilla::dom::EventHandlerNonNull* GetOn##name_() \ { \ @@ -1380,7 +1366,7 @@ protected: } } - void FreeInnerObjects(); + void FreeInnerObjects(bool aForDocumentOpen = false); nsGlobalWindow *CallerInnerWindow(); // Only to be called on an inner window. @@ -1794,11 +1780,6 @@ protected: // Window offline status. Checked to see if we need to fire offline event bool mWasOffline : 1; - // Represents whether the inner window's page has had a slow script notice. - // Only used by inner windows; will always be false for outer windows. - // This is used to implement Telemetry measures such as SLOW_SCRIPT_PAGE_COUNT. - bool mHasHadSlowScript : 1; - // Track what sorts of events we need to fire when thawed bool mNotifyIdleObserversIdleOnThaw : 1; bool mNotifyIdleObserversActiveOnThaw : 1; @@ -1832,9 +1813,6 @@ protected: // Indicates whether this window wants gamepad input events bool mHasGamepad : 1; - // Inner windows only. - // Indicates whether this window wants VR events - bool mHasVREvents : 1; #ifdef MOZ_GAMEPAD nsCheapSet<nsUint32HashKey> mGamepadIndexSet; nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Gamepad> mGamepads; @@ -1989,11 +1967,6 @@ protected: // This is the CC generation the last time we called CanSkip. uint32_t mCanSkipCCGeneration; - // The VR Displays for this window - nsTArray<RefPtr<mozilla::dom::VRDisplay>> mVRDisplays; - - nsAutoPtr<mozilla::dom::VREventObserver> mVREventObserver; - friend class nsDOMScriptableHelper; friend class nsDOMWindowUtils; friend class mozilla::dom::PostMessageEvent; diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 7a73fae71..e5d12ab8f 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -3439,13 +3439,29 @@ nsINode::OwnerDocAsNode() const return OwnerDoc(); } +// ShouldUseXBLScope is defined here as a template so that we can get the faster +// version of IsInAnonymousSubtree if we're statically known to be an +// nsIContent. we could try defining ShouldUseXBLScope separately on nsINode +// and nsIContent, but then we couldn't put its nsINode implementation here +// (because this header does not include nsIContent) and we can't put it in +// nsIContent.h, because the definition of nsIContent::IsInAnonymousSubtree is +// in nsIContentInlines.h. And then we get include hell from people trying to +// call nsINode::GetParentObject but not including nsIContentInlines.h and with +// no really good way to include it. +template<typename T> +inline bool ShouldUseXBLScope(const T* aNode) +{ + return aNode->IsInAnonymousSubtree() && + !aNode->IsAnonymousContentInSVGUseSubtree(); +} + inline mozilla::dom::ParentObject nsINode::GetParentObject() const { mozilla::dom::ParentObject p(OwnerDoc()); // Note that mUseXBLScope is a no-op for chrome, and other places where we // don't use XBL scopes. - p.mUseXBLScope = IsInAnonymousSubtree() && !IsAnonymousContentInSVGUseSubtree(); + p.mUseXBLScope = ShouldUseXBLScope(this); return p; } diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 09e848710..ca507a5fc 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -27,6 +27,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/Event.h" #include "mozilla/dom/ShadowRoot.h" +#include "mozilla/dom/ScriptSettings.h" #include "nsAttrValueOrString.h" #include "nsBindingManager.h" #include "nsCCUncollectableMarker.h" @@ -1569,6 +1570,48 @@ CheckForOutdatedParent(nsINode* aParent, nsINode* aNode) return NS_OK; } +static nsresult +ReparentWrappersInSubtree(nsIContent* aRoot) +{ + MOZ_ASSERT(ShouldUseXBLScope(aRoot)); + // Start off with no global so we don't fire any error events on failure. + AutoJSAPI jsapi; + jsapi.Init(); + + JSContext* cx = jsapi.cx(); + + nsIGlobalObject* docGlobal = aRoot->OwnerDoc()->GetScopeObject(); + if (NS_WARN_IF(!docGlobal)) { + return NS_ERROR_UNEXPECTED; + } + + JS::Rooted<JSObject*> rootedGlobal(cx, docGlobal->GetGlobalJSObject()); + if (NS_WARN_IF(!rootedGlobal)) { + return NS_ERROR_UNEXPECTED; + } + + rootedGlobal = xpc::GetXBLScope(cx, rootedGlobal); + + nsresult rv; + JS::Rooted<JSObject*> reflector(cx); + for (nsIContent* cur = aRoot; cur; cur = cur->GetNextNode(aRoot)) { + if ((reflector = cur->GetWrapper())) { + JSAutoCompartment ac(cx, reflector); + rv = ReparentWrapper(cx, reflector); + if NS_FAILED(rv) { + // We _could_ consider BlastSubtreeToPieces here, but it's not really + // needed. Having some nodes in here accessible to content while others + // are not is probably OK. We just need to fail out of the actual + // insertion, so they're not in the DOM. Returning a failure here will + // do that. + return rv; + } + } + } + + return NS_OK; +} + nsresult nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex, bool aNotify, nsAttrAndChildArray& aChildArray) @@ -1606,9 +1649,15 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex, nsIContent* parent = IsNodeOfType(eDOCUMENT) ? nullptr : static_cast<nsIContent*>(this); + bool wasInXBLScope = ShouldUseXBLScope(aKid); rv = aKid->BindToTree(doc, parent, parent ? parent->GetBindingParent() : nullptr, true); + if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) { + MOZ_ASSERT(ShouldUseXBLScope(this), + "Why does the kid need to use an XBL scope?"); + rv = ReparentWrappersInSubtree(aKid); + } if (NS_FAILED(rv)) { if (GetFirstChild() == aKid) { mFirstChild = aKid->GetNextSibling(); diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 3be1a6d2f..dfd380fc2 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -70,7 +70,6 @@ #include "prthread.h" #include "mozilla/Preferences.h" -#include "mozilla/Telemetry.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/Attributes.h" #include "mozilla/dom/asmjscache/AsmJSCache.h" @@ -626,7 +625,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObjectRef) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSContext) @@ -1357,9 +1355,20 @@ nsJSContext::RunCycleCollectorSlice() TimeStamp now = TimeStamp::Now(); // Only run a limited slice if we're within the max running time. - if (TimeBetween(gCCStats.mBeginTime, now) < kMaxICCDuration) { - float sliceMultiplier = std::max(TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay, 1.0f); - budget = js::SliceBudget(js::TimeBudget(kICCSliceBudget * sliceMultiplier)); + uint32_t runningTime = TimeBetween(gCCStats.mBeginTime, now); + if (runningTime < kMaxICCDuration) { + // Try to make up for a delay in running this slice. + float sliceDelayMultiplier = TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay; + float delaySliceBudget = kICCSliceBudget * sliceDelayMultiplier; + + // Increase slice budgets up to |maxLaterSlice| as we approach + // half way through the ICC, to avoid large sync CCs. + float percentToHalfDone = std::min(2.0f * runningTime / kMaxICCDuration, 1.0f); + const float maxLaterSlice = 40.0f; + float laterSliceBudget = maxLaterSlice * percentToHalfDone; + + budget = js::SliceBudget(js::TimeBudget(std::max({delaySliceBudget, + laterSliceBudget, (float)kICCSliceBudget}))); } } } @@ -1477,22 +1486,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults) NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration)); } - // Log information about the CC via telemetry, JSON and the console. - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, gCCStats.mAnyLockedOut); - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE, gCCStats.mRanSyncForgetSkippable); - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration); - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE, gCCStats.mMaxSliceTime); - - if (!sLastCCEndTime.IsNull()) { - // TimeBetween returns milliseconds, but we want to report seconds. - uint32_t timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime) / 1000; - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween); - } sLastCCEndTime = endCCTimeStamp; - Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX, - sMaxForgetSkippableTime / PR_USEC_PER_MSEC); - PRTime delta = GetCollectionTimeDelta(); uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1; @@ -2633,7 +2628,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSArgArray) tmp->ReleaseJSObjects(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSArgArray) diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index 8736cd1dd..ce5d58385 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -151,7 +151,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler) if (tmp->mFunction) { NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFunction) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h index 9fa7572dd..f00b888b9 100644 --- a/dom/base/nsMappedAttributes.h +++ b/dom/base/nsMappedAttributes.h @@ -93,20 +93,13 @@ private: nsAttrValue mValue; }; - /** - * Due to a compiler bug in VisualAge C++ for AIX, we need to return the - * address of the first index into mAttrs here, instead of simply - * returning mAttrs itself. - * - * See Bug 231104 for more information. - */ const InternalAttr* Attrs() const { - return reinterpret_cast<const InternalAttr*>(&(mAttrs[0])); + return reinterpret_cast<const InternalAttr*>(mAttrs); } InternalAttr* Attrs() { - return reinterpret_cast<InternalAttr*>(&(mAttrs[0])); + return reinterpret_cast<InternalAttr*>(mAttrs); } uint16_t mAttrCount; diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp index 66c8c84cf..80f0aa786 100644 --- a/dom/base/nsNodeInfoManager.cpp +++ b/dom/base/nsNodeInfoManager.cpp @@ -392,9 +392,6 @@ nsNodeInfoManager::SetDocumentPrincipal(nsIPrincipal *aPrincipal) NS_ASSERTION(aPrincipal, "Must have principal by this point!"); MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsExpandedPrincipal(aPrincipal), "Documents shouldn't have an expanded principal"); - if (nsContentUtils::IsExpandedPrincipal(aPrincipal)) { - Telemetry::Accumulate(Telemetry::DOCUMENT_WITH_EXPANDED_PRINCIPAL, 1); - } mPrincipal = aPrincipal; } diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index ecea95dc1..75d408151 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -297,6 +297,16 @@ nsNodeUtils::LastRelease(nsINode* aNode) NodeWillBeDestroyed, (aNode)); } + if (aNode->IsElement()) { + Element* elem = aNode->AsElement(); + FragmentOrElement::nsDOMSlots* domSlots = + static_cast<FragmentOrElement::nsDOMSlots*>(slots); + for (auto iter = domSlots->mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { + DOMIntersectionObserver* observer = iter.Key(); + observer->UnlinkTarget(*elem); + } + } + delete slots; aNode->mSlots = nullptr; } diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index 9e9dacf01..c1b732258 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -85,7 +85,6 @@ #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventStates.h" -#include "mozilla/Telemetry.h" #include "mozilla/dom/HTMLObjectElementBinding.h" #include "mozilla/dom/HTMLSharedObjectElement.h" #include "nsChannelClassifier.h" @@ -1149,7 +1148,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, NS_LITERAL_STRING(" since it was found on an internal Firefox blocklist."); console->LogStringMessage(message.get()); } - Telemetry::Accumulate(Telemetry::PLUGIN_BLOCKED_FOR_STABILITY, 1); mContentBlockingEnabled = true; return NS_ERROR_FAILURE; } else if (status == NS_ERROR_TRACKING_URI) { @@ -1565,7 +1563,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI, } if (uri.Find("enablejsapi=1", true, 0, -1) != kNotFound) { - Telemetry::Accumulate(Telemetry::YOUTUBE_NONREWRITABLE_EMBED_SEEN, 1); return; } @@ -1585,11 +1582,6 @@ nsObjectLoadingContent::MaybeRewriteYoutubeEmbed(nsIURI* aURI, nsIURI* aBaseURI, } } - // If we've made it this far, we've got a rewritable embed. Log it in - // telemetry. - Telemetry::Accumulate(Telemetry::YOUTUBE_REWRITABLE_EMBED_SEEN, 1); - - // If we're pref'd off, return after telemetry has been logged. if (!Preferences::GetBool(kPrefYoutubeRewrite)) { return; } @@ -3800,8 +3792,6 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx, aRv.Throw(NS_ERROR_FAILURE); return; } - - Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true); } void diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index 4b4ce7885..d45a2c975 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -351,7 +351,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsRange) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndParent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelection) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsRange) diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp index a6d20e363..1e23d6c5f 100644 --- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -81,11 +81,19 @@ ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptLoadRequest) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_0(nsScriptLoadRequest) - NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptLoadRequest) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptLoadRequest) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptLoadRequest) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptLoadRequest) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptLoadRequest) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + nsScriptLoadRequest::~nsScriptLoadRequest() { js_free(mScriptTextBuf); @@ -345,7 +353,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsModuleScript) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsModuleScript) diff --git a/dom/base/nsWrapperCache.cpp b/dom/base/nsWrapperCache.cpp index b91d86598..c5993fe7b 100644 --- a/dom/base/nsWrapperCache.cpp +++ b/dom/base/nsWrapperCache.cpp @@ -133,7 +133,7 @@ nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder, // see through the COM layer, so we use a suppression to help it. JS::AutoSuppressGCAnalysis suppress; - aTracer->Traverse(aScriptObjectHolder, callback); + aTracer->TraverseNativeAndJS(aScriptObjectHolder, callback); MOZ_ASSERT(callback.mFound, "Cycle collection participant didn't traverse to preserved " "wrapper! This will probably crash."); diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 3c69a7ec4..56cae89ed 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -331,8 +331,7 @@ private: * causes between the native object and the JS object, so it is important that * any native object that supports preserving of its wrapper * traces/traverses/unlinks the cached JS object (see - * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER, - * NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS and + * NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER and * NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER). */ enum { WRAPPER_BIT_PRESERVED = 1 << 0 }; @@ -383,7 +382,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \ NS_IMPL_CYCLE_COLLECTION_UNLINK_END \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \ - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) @@ -395,7 +393,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID) NS_IMPL_CYCLE_COLLECTION_UNLINK_END \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__) \ - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) |