From 279b2f1b528280379fa278589d4156f69e645d46 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Fri, 26 Mar 2021 17:01:09 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1136897 - Don't evict expired entries from disk. r=michal (6af5d87e8) - Bug 1188745 - Rename nsTArray::SizeOfExcludingThis() as ShallowSizeOfExcludingThis(). r=froydnj. (3dbb2875a) - Bug 1150810 part 1 - Move DocumentTimeline methods up to AnimationTimeline; r=jwatt (3d8c679af) - Bug 1171817 part 1 - Cancel animations when destroying the property holding them; r=dbaron (6f28fbf46) - Bug 1171817 part 2 - Add CSSAnimation::GetOwningElement; r=dbaron (700decca6) - Bug 1171817 part 3 - Add CSSTransition::GetOwningElement; r=dbaron (e6da3c726) - Bug 1171817 part 4 - Add const version of AsCSSAnimation/AsCSSTransition methods; r=dbaron (f264ebad7) - Bug 1171817 part 5 - Add a sequence number member to Animations; r=dbaron (b041eeb6b) - Bug 1171817 part 6 - Add Animation::HasLowerCompositeOrderThan; r=dbaron (df97cf295) - Bug 1171817 part 7 - Add Animation::IsUsingCustomCompositeOrder; r=dbaron (5735f03a2) - Bug 1171817 part 8 - Override sequence numbers for CSS animations; r=dbaron (50671de0f) - Bug 1171817 part 9 - Add override of HasLowerCompositeOrderThan for CSS animations; r=dbaron (b467ffd3c) - Bug 1171817 part 10 - Override sequence numbers for transitions; r=dbron (3703102f6) - Bug 1171817 part 11 - Add CSSTransition::TransitionProperty(); r=dbaron (c889aa8ec) - Bug 1171817 part 13 - Add override of HasLowerCompositeOrderThan for CSS transitions; r=dbaron (8c628cac4) - Bug 1171817 part 14 - Add AnimationPtrComparator class; r=dbaron (c522180c9) - Bug 1171817 part 15 - Factor out common code for comparing owning elements into a separate class; r=dbaron (132998a2c) - Bug 1171817 part 16 - Always cancel transitions before removing them; r=dbaron (01113a650) - Bug 1150810 part 2 - Replace references to DocumentTimeline with AnimationTimeline; r=jwatt (d377ba63f) - Bug 1150810 part 3 - Make IsPossiblyOrphanedPendingAnimation return true when there is no rendered doc; r=jwatt (63b2b6760) - Bug 1150810 part 4 - Store global on Animation; r=smaug, jwatt (fd099d639) - Bug 1150810 part 5 - Handle Timeline() returning null; r=jwatt (641bd865d) --- dom/animation/Animation.cpp | 114 +++++++----- dom/animation/Animation.h | 47 +++-- dom/animation/AnimationComparator.h | 32 ++++ dom/animation/AnimationTimeline.h | 23 +++ dom/animation/DocumentTimeline.h | 25 +-- dom/animation/KeyframeEffect.h | 3 +- dom/animation/PendingAnimationTracker.cpp | 13 +- dom/animation/moz.build | 1 + .../file_element-get-animations.html | 30 ++++ .../file_element-get-animations.html | 43 ++++- dom/animation/test/testcommon.js | 5 +- dom/base/Element.cpp | 3 + dom/base/nsAttrValue.cpp | 2 +- dom/canvas/WebGLElementArrayCache.cpp | 5 +- dom/events/EventListenerManager.cpp | 2 +- dom/media/AudioSegment.h | 6 +- dom/media/AudioStream.cpp | 2 +- dom/media/MediaCache.cpp | 2 +- dom/media/MediaSegment.h | 2 +- dom/media/MediaStreamGraph.cpp | 12 +- dom/media/MediaStreamGraph.h | 2 +- dom/media/RtspMediaResource.cpp | 2 +- dom/media/StreamBuffer.h | 2 +- dom/media/TimeVarying.h | 2 +- dom/media/encoder/MediaEncoder.cpp | 4 +- dom/media/mediasource/ResourceQueue.cpp | 2 +- dom/media/webaudio/AnalyserNode.cpp | 4 +- dom/media/webaudio/AudioBuffer.cpp | 2 +- dom/media/webaudio/AudioContext.cpp | 2 +- dom/media/webaudio/AudioDestinationNode.cpp | 2 +- dom/media/webaudio/AudioListener.cpp | 2 +- dom/media/webaudio/AudioNode.cpp | 6 +- dom/media/webaudio/AudioNodeEngine.h | 2 +- dom/media/webaudio/AudioNodeStream.cpp | 2 +- dom/media/webaudio/AudioParam.h | 2 +- dom/media/webaudio/BiquadFilterNode.cpp | 2 +- dom/media/webaudio/DelayBuffer.cpp | 4 +- dom/media/webaudio/FFTBlock.h | 2 +- dom/media/webaudio/MediaBufferDecoder.cpp | 2 +- dom/media/webaudio/PannerNode.cpp | 2 +- dom/media/webaudio/ScriptProcessorNode.cpp | 2 +- dom/media/webaudio/WaveShaperNode.cpp | 4 +- dom/media/webaudio/blink/DirectConvolver.h | 2 +- .../webaudio/blink/DynamicsCompressor.cpp | 4 +- .../blink/DynamicsCompressorKernel.cpp | 2 +- dom/media/webaudio/blink/FFTConvolver.cpp | 6 +- dom/media/webaudio/blink/HRTFDatabase.cpp | 2 +- dom/media/webaudio/blink/HRTFElevation.cpp | 2 +- dom/media/webaudio/blink/HRTFPanner.cpp | 8 +- dom/media/webaudio/blink/PeriodicWave.cpp | 4 +- dom/media/webaudio/blink/Reverb.cpp | 2 +- .../webaudio/blink/ReverbAccumulationBuffer.h | 2 +- dom/media/webaudio/blink/ReverbConvolver.cpp | 4 +- .../webaudio/blink/ReverbConvolverStage.cpp | 6 +- dom/media/webaudio/blink/ReverbInputBuffer.h | 2 +- dom/svg/SVGPathData.cpp | 2 +- gfx/thebes/gfxDWriteFontList.cpp | 2 +- gfx/thebes/gfxFont.h | 4 +- gfx/thebes/gfxFontEntry.cpp | 4 +- gfx/thebes/gfxFontFamilyList.h | 8 +- gfx/thebes/gfxFontUtils.h | 2 +- gfx/thebes/gfxGDIFontList.cpp | 2 +- gfx/thebes/gfxGlyphExtents.cpp | 2 +- gfx/thebes/gfxPlatformFontList.cpp | 4 +- gfx/thebes/gfxTextRun.cpp | 2 +- image/SourceBuffer.cpp | 2 +- layout/base/FramePropertyTable.h | 2 +- layout/base/nsDisplayList.cpp | 31 ++-- layout/base/nsPresArena.h | 2 +- layout/generic/nsTextRunTransformations.cpp | 4 +- layout/style/AnimationCommon.cpp | 8 + layout/style/AnimationCommon.h | 61 ++++++- layout/style/CSSStyleSheet.cpp | 2 +- layout/style/Declaration.cpp | 2 +- layout/style/Loader.cpp | 2 +- layout/style/RuleProcessorCache.cpp | 4 +- layout/style/nsAnimationManager.cpp | 56 +++++- layout/style/nsAnimationManager.h | 72 +++++++- layout/style/nsCSSRuleProcessor.cpp | 24 +-- layout/style/nsCSSValue.cpp | 6 +- layout/style/nsStyleSet.cpp | 6 +- layout/style/nsTransitionManager.cpp | 66 ++++++- layout/style/nsTransitionManager.h | 73 +++++++- modules/libpref/Preferences.cpp | 4 +- netwerk/cache2/CacheEntry.cpp | 2 +- netwerk/cache2/CacheFile.cpp | 4 +- netwerk/cache2/CacheFileUtils.cpp | 2 +- netwerk/cache2/CacheIOThread.cpp | 2 +- netwerk/cache2/CacheIndex.cpp | 166 ++++-------------- netwerk/cache2/CacheIndex.h | 13 +- netwerk/cache2/CacheStorageService.cpp | 8 +- netwerk/cookie/nsCookieService.cpp | 4 +- netwerk/dns/nsHostResolver.cpp | 2 +- startupcache/StartupCache.cpp | 2 +- toolkit/components/places/History.h | 2 +- toolkit/components/telemetry/Telemetry.cpp | 2 +- xpcom/base/nsCycleCollector.cpp | 2 +- xpcom/components/nsComponentManager.cpp | 8 +- xpcom/glue/DeadlockDetector.h | 4 +- xpcom/glue/nsCOMArray.cpp | 2 +- xpcom/glue/nsTArray.h | 14 +- xpcom/glue/nsTObserverArray.h | 8 +- 102 files changed, 785 insertions(+), 395 deletions(-) create mode 100644 dom/animation/AnimationComparator.h diff --git a/dom/animation/Animation.cpp b/dom/animation/Animation.cpp index c6f8f92fc0..419092cbbf 100644 --- a/dom/animation/Animation.cpp +++ b/dom/animation/Animation.cpp @@ -18,7 +18,10 @@ namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Animation, mTimeline, +// Static members +uint64_t Animation::sNextSequenceNum = 0; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Animation, mGlobal, mTimeline, mEffect, mReady, mFinished) NS_IMPL_CYCLE_COLLECTING_ADDREF(Animation) NS_IMPL_CYCLE_COLLECTING_RELEASE(Animation) @@ -55,13 +58,7 @@ Animation::SetEffect(KeyframeEffectReadOnly* aEffect) void Animation::SetStartTime(const Nullable& aNewStartTime) { -#if 1 - // Bug 1096776: once we support inactive/missing timelines we'll want to take - // the disabled branch. - MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(), - "We don't support inactive/missing timelines yet"); -#else - Nullable timelineTime = mTimeline->GetCurrentTime(); + Nullable timelineTime; if (mTimeline) { // The spec says to check if the timeline is active (has a resolved time) // before using it here, but we don't need to since it's harmless to set @@ -71,7 +68,7 @@ Animation::SetStartTime(const Nullable& aNewStartTime) if (timelineTime.IsNull() && !aNewStartTime.IsNull()) { mHoldTime.SetNull(); } -#endif + Nullable previousCurrentTime = GetCurrentTime(); mStartTime = aNewStartTime; if (!aNewStartTime.IsNull()) { @@ -103,7 +100,7 @@ Animation::GetCurrentTime() const return result; } - if (!mStartTime.IsNull()) { + if (mTimeline && !mStartTime.IsNull()) { Nullable timelineTime = mTimeline->GetCurrentTime(); if (!timelineTime.IsNull()) { result.SetValue((timelineTime.Value() - mStartTime.Value()) @@ -170,21 +167,11 @@ Animation::PlayState() const return AnimationPlayState::Running; } -static inline already_AddRefed -CreatePromise(DocumentTimeline* aTimeline, ErrorResult& aRv) -{ - nsIGlobalObject* global = aTimeline->GetParentObject(); - if (global) { - return Promise::Create(global, aRv); - } - return nullptr; -} - Promise* Animation::GetReady(ErrorResult& aRv) { - if (!mReady) { - mReady = CreatePromise(mTimeline, aRv); // Lazily create on demand + if (!mReady && mGlobal) { + mReady = Promise::Create(mGlobal, aRv); // Lazily create on demand } if (!mReady) { aRv.Throw(NS_ERROR_FAILURE); @@ -197,8 +184,8 @@ Animation::GetReady(ErrorResult& aRv) Promise* Animation::GetFinished(ErrorResult& aRv) { - if (!mFinished) { - mFinished = CreatePromise(mTimeline, aRv); // Lazily create on demand + if (!mFinished && mGlobal) { + mFinished = Promise::Create(mGlobal, aRv); // Lazily create on demand } if (!mFinished) { aRv.Throw(NS_ERROR_FAILURE); @@ -322,6 +309,8 @@ Animation::Tick() // resuming. if (mPendingState != PendingState::NotPending && !mPendingReadyTime.IsNull() && + mTimeline && + !mTimeline->GetCurrentTime().IsNull() && mPendingReadyTime.Value() <= mTimeline->GetCurrentTime().Value()) { FinishPendingAt(mPendingReadyTime.Value()); mPendingReadyTime.SetNull(); @@ -355,10 +344,22 @@ Animation::TriggerOnNextTick(const Nullable& aReadyTime) void Animation::TriggerNow() { - MOZ_ASSERT(PlayState() == AnimationPlayState::Pending, - "Expected to start a pending animation"); - MOZ_ASSERT(mTimeline && !mTimeline->GetCurrentTime().IsNull(), - "Expected an active timeline"); + // Normally we expect the play state to be pending but when an animation + // is cancelled and its rendered document can't be reached, we can end up + // with the animation still in a pending player tracker even after it is + // no longer pending. + if (PlayState() != AnimationPlayState::Pending) { + return; + } + + // If we don't have an active timeline we can't trigger the animation. + // However, this is a test-only method that we don't expect to be used in + // conjunction with animations without an active timeline so generate + // a warning if we do find ourselves in that situation. + if (!mTimeline || mTimeline->GetCurrentTime().IsNull()) { + NS_WARNING("Failed to trigger an animation with an active timeline"); + return; + } FinishPendingAt(mTimeline->GetCurrentTime().Value()); } @@ -436,7 +437,7 @@ Animation::DoCancel() mHoldTime.SetNull(); mStartTime.SetNull(); - UpdateEffect(); + UpdateTiming(SeekFlag::NoSeek); } void @@ -453,6 +454,20 @@ Animation::UpdateRelevance() } } +bool +Animation::HasLowerCompositeOrderThan(const Animation& aOther) const +{ + // We only ever sort non-idle animations so we don't ever expect + // mSequenceNum to be set to kUnsequenced + MOZ_ASSERT(mSequenceNum != kUnsequenced && + aOther.mSequenceNum != kUnsequenced, + "Animations to compare should not be idle"); + MOZ_ASSERT(mSequenceNum != aOther.mSequenceNum || &aOther == this, + "Sequence numbers should be unique"); + + return mSequenceNum < aOther.mSequenceNum; +} + bool Animation::CanThrottle() const { @@ -539,7 +554,7 @@ Animation::ComposeStyle(nsRefPtr& aStyleRule, Nullable timeToUse = mPendingReadyTime; if (timeToUse.IsNull() && mTimeline && - !mTimeline->IsUnderTestControl()) { + mTimeline->TracksWallclockTime()) { timeToUse = mTimeline->ToTimelineTime(TimeStamp::Now()); } if (!timeToUse.IsNull()) { @@ -617,15 +632,14 @@ Animation::DoPlay(ErrorResult& aRv, LimitBehavior aLimitBehavior) mPendingState = PendingState::PlayPending; nsIDocument* doc = GetRenderedDocument(); - if (!doc) { + if (doc) { + PendingAnimationTracker* tracker = + doc->GetOrCreatePendingAnimationTracker(); + tracker->AddPlayPending(*this); + } else { TriggerOnNextTick(Nullable()); - return; } - PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); - tracker->AddPlayPending(*this); - - // We may have updated the current time when we set the hold time above. UpdateTiming(SeekFlag::NoSeek); } @@ -669,14 +683,14 @@ Animation::DoPause(ErrorResult& aRv) mPendingState = PendingState::PausePending; nsIDocument* doc = GetRenderedDocument(); - if (!doc) { + if (doc) { + PendingAnimationTracker* tracker = + doc->GetOrCreatePendingAnimationTracker(); + tracker->AddPausePending(*this); + } else { TriggerOnNextTick(Nullable()); - return; } - PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); - tracker->AddPausePending(*this); - UpdateTiming(SeekFlag::NoSeek); } @@ -735,6 +749,16 @@ Animation::PauseAt(const TimeDuration& aReadyTime) void Animation::UpdateTiming(SeekFlag aSeekFlag) { + // Update the sequence number each time we transition in or out of the + // idle state + if (!IsUsingCustomCompositeOrder()) { + if (PlayState() == AnimationPlayState::Idle) { + mSequenceNum = kUnsequenced; + } else if (mSequenceNum == kUnsequenced) { + mSequenceNum = sNextSequenceNum++; + } + } + // We call UpdateFinishedState before UpdateEffect because the former // can change the current time, which is used by the latter. UpdateFinishedState(aSeekFlag); @@ -768,10 +792,12 @@ Animation::UpdateFinishedState(SeekFlag aSeekFlag) mHoldTime.SetValue(0); } } else if (mPlaybackRate != 0.0 && - !currentTime.IsNull()) { + !currentTime.IsNull() && + mTimeline && + !mTimeline->GetCurrentTime().IsNull()) { if (aSeekFlag == SeekFlag::DidSeek && !mHoldTime.IsNull()) { mStartTime.SetValue(mTimeline->GetCurrentTime().Value() - - (mHoldTime.Value().MultDouble(1 / mPlaybackRate))); + (mHoldTime.Value().MultDouble(1 / mPlaybackRate))); } mHoldTime.SetNull(); } @@ -890,7 +916,7 @@ Animation::IsPossiblyOrphanedPendingAnimation() const // never starting/pausing the animation and is unlikely. nsIDocument* doc = GetRenderedDocument(); if (!doc) { - return false; + return true; } PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker(); diff --git a/dom/animation/Animation.h b/dom/animation/Animation.h index 65115df193..48b497a9eb 100644 --- a/dom/animation/Animation.h +++ b/dom/animation/Animation.h @@ -12,10 +12,11 @@ #include "mozilla/Attributes.h" #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration #include "mozilla/dom/AnimationBinding.h" // for AnimationPlayState -#include "mozilla/dom/DocumentTimeline.h" // for DocumentTimeline +#include "mozilla/dom/AnimationTimeline.h" // for AnimationTimeline #include "mozilla/dom/KeyframeEffect.h" // for KeyframeEffectReadOnly #include "mozilla/dom/Promise.h" // for Promise #include "nsCSSProperty.h" // for nsCSSProperty +#include "nsIGlobalObject.h" // X11 has a #define for CurrentTime. #ifdef CurrentTime @@ -53,10 +54,12 @@ protected: virtual ~Animation() {} public: - explicit Animation(DocumentTimeline* aTimeline) - : mTimeline(aTimeline) + explicit Animation(nsIGlobalObject* aGlobal, AnimationTimeline* aTimeline) + : mGlobal(aGlobal) + , mTimeline(aTimeline) , mPlaybackRate(1.0) , mPendingState(PendingState::NotPending) + , mSequenceNum(kUnsequenced) , mIsRunningOnCompositor(false) , mIsPreviousStateFinished(false) , mFinishedAtLastComposeStyle(false) @@ -67,12 +70,14 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Animation) - DocumentTimeline* GetParentObject() const { return mTimeline; } + AnimationTimeline* GetParentObject() const { return mTimeline; } virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; virtual CSSAnimation* AsCSSAnimation() { return nullptr; } + virtual const CSSAnimation* AsCSSAnimation() const { return nullptr; } virtual CSSTransition* AsCSSTransition() { return nullptr; } + virtual const CSSTransition* AsCSSTransition() const { return nullptr; } /** * Flag to pass to Play to indicate whether or not it should automatically @@ -89,7 +94,7 @@ public: KeyframeEffectReadOnly* GetEffect() const { return mEffect; } void SetEffect(KeyframeEffectReadOnly* aEffect); - DocumentTimeline* Timeline() const { return mTimeline; } + AnimationTimeline* Timeline() const { return mTimeline; } Nullable GetStartTime() const { return mStartTime; } void SetStartTime(const Nullable& aNewStartTime); Nullable GetCurrentTime() const; @@ -127,11 +132,10 @@ public: * CSSAnimation::PauseFromJS so we leave it for now. */ void PauseFromJS(ErrorResult& aRv) { Pause(aRv); } + // Wrapper functions for Animation DOM methods when called from style. - // - // Typically these DOM methods also notify style of changes but when - // we are calling from style we don't need to do this. - void CancelFromStyle() { DoCancel(); } + + virtual void CancelFromStyle() { DoCancel(); } void Tick(); @@ -255,6 +259,20 @@ public: } bool IsRelevant() const { return mIsRelevant; } void UpdateRelevance(); + + /** + * Returns true if this Animation has a lower composite order than aOther. + */ + virtual bool HasLowerCompositeOrderThan(const Animation& aOther) const; + /** + * Returns true if this Animation is involved in some sort of + * custom composite ordering (such as the ordering defined for CSS + * animations or CSS transitions). + * + * When this is true, this class will not update the sequence number. + */ + virtual bool IsUsingCustomCompositeOrder() const { return false; } + void SetIsRunningOnCompositor() { mIsRunningOnCompositor = true; } void ClearIsRunningOnCompositor() { mIsRunningOnCompositor = false; } /** @@ -324,7 +342,8 @@ protected: virtual css::CommonAnimationManager* GetAnimationManager() const = 0; AnimationCollection* GetCollection() const; - nsRefPtr mTimeline; + nsCOMPtr mGlobal; + nsRefPtr mTimeline; nsRefPtr mEffect; // The beginning of the delay period. Nullable mStartTime; // Timeline timescale @@ -355,6 +374,14 @@ protected: enum class PendingState { NotPending, PlayPending, PausePending }; PendingState mPendingState; + static uint64_t sNextSequenceNum; + static const uint64_t kUnsequenced = UINT64_MAX; + + // The sequence number assigned to this animation. This is kUnsequenced + // while the animation is in the idle state and is updated each time + // the animation transitions out of the idle state. + uint64_t mSequenceNum; + bool mIsRunningOnCompositor; // Indicates whether we were in the finished state during our // most recent unthrottled sample (our last ComposeStyle call). diff --git a/dom/animation/AnimationComparator.h b/dom/animation/AnimationComparator.h new file mode 100644 index 0000000000..ff665e82aa --- /dev/null +++ b/dom/animation/AnimationComparator.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_AnimationComparator_h +#define mozilla_AnimationComparator_h + +namespace mozilla { + +// Although this file is called AnimationComparator, we don't actually +// implement AnimationComparator (to compare const Animation& parameters) +// since it's not actually needed (yet). + +template +class AnimationPtrComparator { +public: + bool Equals(const AnimationPtrType& a, const AnimationPtrType& b) const + { + return a == b; + } + + bool LessThan(const AnimationPtrType& a, const AnimationPtrType& b) const + { + return a->HasLowerCompositeOrderThan(*b); + } +}; + +} // namespace mozilla + +#endif // mozilla_AnimationComparator_h diff --git a/dom/animation/AnimationTimeline.h b/dom/animation/AnimationTimeline.h index 98adea93ae..57df89e86f 100644 --- a/dom/animation/AnimationTimeline.h +++ b/dom/animation/AnimationTimeline.h @@ -47,6 +47,29 @@ public: return AnimationUtils::TimeDurationToDouble(GetCurrentTime()); } + /** + * Returns true if the times returned by GetCurrentTime() are convertible + * to and from wallclock-based TimeStamp (e.g. from TimeStamp::Now()) values + * using ToTimelineTime() and ToTimeStamp(). + * + * Typically this is true, but it will be false in the case when this + * timeline has no refresh driver or is tied to a refresh driver under test + * control. + */ + virtual bool TracksWallclockTime() const = 0; + + /** + * Converts a TimeStamp to the equivalent value in timeline time. + * Note that when TracksWallclockTime() is false, there is no correspondence + * between timeline time and wallclock time. In such a case, passing a + * timestamp from TimeStamp::Now() to this method will not return a + * meaningful result. + */ + virtual Nullable ToTimelineTime(const TimeStamp& + aTimeStamp) const = 0; + + virtual TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const = 0; + protected: nsCOMPtr mWindow; }; diff --git a/dom/animation/DocumentTimeline.h b/dom/animation/DocumentTimeline.h index 68396cb897..dcec9046bd 100644 --- a/dom/animation/DocumentTimeline.h +++ b/dom/animation/DocumentTimeline.h @@ -37,31 +37,22 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - // DocumentTimeline methods + // AnimationTimeline methods virtual Nullable GetCurrentTime() const override; - // Converts a TimeStamp to the equivalent value in timeline time. - // Note that when IsUnderTestControl() is true, there is no correspondence - // between timeline time and wallclock time. In such a case, passing a - // timestamp from TimeStamp::Now() to this method will not return a - // meaningful result. - Nullable ToTimelineTime(const TimeStamp& aTimeStamp) const; - TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const; - - nsRefreshDriver* GetRefreshDriver() const; - // Returns true if this timeline is driven by a refresh driver that is - // under test control. In such a case, there is no correspondence between - // TimeStamp values returned by the refresh driver and wallclock time. - // As a result, passing a value from TimeStamp::Now() to ToTimelineTime() - // would not return a meaningful result. - bool IsUnderTestControl() const + bool TracksWallclockTime() const override { nsRefreshDriver* refreshDriver = GetRefreshDriver(); - return refreshDriver && refreshDriver->IsTestControllingRefreshesEnabled(); + return !refreshDriver || + !refreshDriver->IsTestControllingRefreshesEnabled(); } + Nullable ToTimelineTime(const TimeStamp& aTimeStamp) const + override; + TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const override; protected: TimeStamp GetCurrentTimeStamp() const; + nsRefreshDriver* GetRefreshDriver() const; nsCOMPtr mDocument; diff --git a/dom/animation/KeyframeEffect.h b/dom/animation/KeyframeEffect.h index 758898a495..ea7f7fd386 100644 --- a/dom/animation/KeyframeEffect.h +++ b/dom/animation/KeyframeEffect.h @@ -210,7 +210,8 @@ public: JS::Handle aGivenProto) override; virtual ElementPropertyTransition* AsTransition() { return nullptr; } - virtual const ElementPropertyTransition* AsTransition() const { + virtual const ElementPropertyTransition* AsTransition() const + { return nullptr; } diff --git a/dom/animation/PendingAnimationTracker.cpp b/dom/animation/PendingAnimationTracker.cpp index 6f3c38f47b..46ab692ecc 100644 --- a/dom/animation/PendingAnimationTracker.cpp +++ b/dom/animation/PendingAnimationTracker.cpp @@ -6,7 +6,7 @@ #include "PendingAnimationTracker.h" -#include "mozilla/dom/DocumentTimeline.h" +#include "mozilla/dom/AnimationTimeline.h" #include "nsIFrame.h" #include "nsIPresShell.h" @@ -53,14 +53,21 @@ TriggerAnimationAtTime(nsRefPtrHashKey* aKey, void* aReadyTime) { dom::Animation* animation = aKey->GetKey(); - dom::DocumentTimeline* timeline = animation->Timeline(); + dom::AnimationTimeline* timeline = animation->Timeline(); + + // If the animation does not have a timeline, just drop it from the map. + // The animation will detect that it is not being tracked and will trigger + // itself on the next tick where it has a timeline. + if (!timeline) { + return PL_DHASH_REMOVE; + } // When the timeline's refresh driver is under test control, its values // have no correspondance to wallclock times so we shouldn't try to convert // aReadyTime (which is a wallclock time) to a timeline value. Instead, the // animation will be started/paused when the refresh driver is next // advanced since this will trigger a call to TriggerPendingAnimationsNow. - if (timeline->IsUnderTestControl()) { + if (!timeline->TracksWallclockTime()) { return PL_DHASH_NEXT; } diff --git a/dom/animation/moz.build b/dom/animation/moz.build index 3473b8b6a7..465a747693 100644 --- a/dom/animation/moz.build +++ b/dom/animation/moz.build @@ -16,6 +16,7 @@ EXPORTS.mozilla.dom += [ ] EXPORTS.mozilla += [ + 'AnimationComparator.h', 'AnimationUtils.h', 'PendingAnimationTracker.h', ] diff --git a/dom/animation/test/css-animations/file_element-get-animations.html b/dom/animation/test/css-animations/file_element-get-animations.html index 2625ddd2fd..df0476c025 100644 --- a/dom/animation/test/css-animations/file_element-get-animations.html +++ b/dom/animation/test/css-animations/file_element-get-animations.html @@ -274,6 +274,36 @@ test(function(t) { }, 'getAnimations for CSS Animations that are cancelled'); +async_test(function(t) { + var div = addDiv(t); + div.style.animation = 'anim2 100s'; + + div.getAnimations()[0].ready.then(t.step_func(function() { + // Prepend to the list and test that even though anim1 was triggered + // *after* anim2, it should come first because it appears first + // in the animation-name property. + div.style.animation = 'anim1 100s, anim2 100s'; + var anims = div.getAnimations(); + assert_equals(anims[0].animationName, 'anim1', + 'animation order after prepending to list'); + assert_equals(anims[1].animationName, 'anim2', + 'animation order after prepending to list'); + + // Normally calling cancel and play would this push anim1 to the top of + // the stack but it shouldn't for CSS animations that map an the + // animation-name property. + var anim1 = anims[0]; + anim1.cancel(); + anim1.play(); + anims = div.getAnimations(); + assert_equals(anims[0].animationName, 'anim1', + 'animation order after cancelling and restarting'); + assert_equals(anims[1].animationName, 'anim2', + 'animation order after cancelling and restarting'); + t.done(); + })); +}, 'getAnimations for CSS Animations follows animation-name order'); + done(); diff --git a/dom/animation/test/css-transitions/file_element-get-animations.html b/dom/animation/test/css-transitions/file_element-get-animations.html index bb85820f76..0ce145da04 100644 --- a/dom/animation/test/css-transitions/file_element-get-animations.html +++ b/dom/animation/test/css-transitions/file_element-get-animations.html @@ -37,7 +37,7 @@ async_test(function(t) { 'getAnimations returns Animations for all running CSS Transitions'); return waitForAllAnimations(animations); })).then(t.step_func(function() { - assert_true(animations[1].startTime < animations[2].startTime, + assert_less_than(animations[1].startTime, animations[2].startTime, 'Animation for additional CSS transition starts after the original' + ' transitions and appears later in the list'); t.done(); @@ -101,6 +101,47 @@ test(function(t) { + ' of an unsupported property'); }, 'getAnimations for transition on unsupported property'); +test(function(t) { + var div = addDiv(t, { style: 'transform: translate(0px); ' + + 'opacity: 0; ' + + 'border-width: 0px; ' + // Shorthand + 'border-style: solid' }); + getComputedStyle(div).transform; + + div.style.transition = 'all 100s'; + div.style.transform = 'translate(100px)'; + div.style.opacity = '1'; + div.style.borderWidth = '1px'; + + var animations = div.getAnimations(); + assert_equals(animations.length, 6, + 'Generated expected number of transitions'); + assert_equals(animations[0].transitionProperty, 'border-bottom-width'); + assert_equals(animations[1].transitionProperty, 'border-left-width'); + assert_equals(animations[2].transitionProperty, 'border-right-width'); + assert_equals(animations[3].transitionProperty, 'border-top-width'); + assert_equals(animations[4].transitionProperty, 'opacity'); + assert_equals(animations[5].transitionProperty, 'transform'); +}, 'getAnimations sorts simultaneous transitions by name'); + +test(function(t) { + var div = addDiv(t, { style: 'transform: translate(0px); ' + + 'opacity: 0' }); + getComputedStyle(div).transform; + + div.style.transition = 'all 100s'; + div.style.transform = 'translate(100px)'; + assert_equals(div.getAnimations().length, 1, + 'Initially there is only one (transform) transition'); + div.style.opacity = '1'; + assert_equals(div.getAnimations().length, 2, + 'Then a second (opacity) transition is added'); + + var animations = div.getAnimations(); + assert_equals(animations[0].transitionProperty, 'transform'); + assert_equals(animations[1].transitionProperty, 'opacity'); +}, 'getAnimations sorts transitions by when they were generated'); + done(); diff --git a/dom/animation/test/testcommon.js b/dom/animation/test/testcommon.js index ff4152b743..f3ba89edbc 100644 --- a/dom/animation/test/testcommon.js +++ b/dom/animation/test/testcommon.js @@ -49,8 +49,9 @@ function flushComputedStyle(elem) { } for (var funcName of ["async_test", "assert_not_equals", "assert_equals", - "assert_approx_equals", "assert_less_than_equal", - "assert_between_inclusive", "assert_true", "assert_false", + "assert_approx_equals", "assert_less_than", + "assert_less_than_equal", "assert_between_inclusive", + "assert_true", "assert_false", "assert_class_string", "assert_throws", "test"]) { window[funcName] = opener[funcName].bind(opener); } diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index f7ffea6b28..b4f14d893a 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -52,6 +52,7 @@ #include "nsDOMString.h" #include "nsIScriptSecurityManager.h" #include "nsIDOMMutationEvent.h" +#include "mozilla/AnimationComparator.h" #include "mozilla/AsyncEventDispatcher.h" #include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" @@ -3343,6 +3344,8 @@ Element::GetAnimations(nsTArray>& aAnimations) } } } + + aAnimations.Sort(AnimationPtrComparator>()); } NS_IMETHODIMP diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index bb2dee7491..81b7a52f65 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -1928,7 +1928,7 @@ nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const //n += container->mCSSStyleRule->SizeOfIncludingThis(aMallocSizeOf); } else if (Type() == eAtomArray && container->mValue.mAtomArray) { // Don't measure each nsIAtom, they are measured separatly. - n += container->mValue.mAtomArray->SizeOfIncludingThis(aMallocSizeOf); + n += container->mValue.mAtomArray->ShallowSizeOfIncludingThis(aMallocSizeOf); } break; } diff --git a/dom/canvas/WebGLElementArrayCache.cpp b/dom/canvas/WebGLElementArrayCache.cpp index f4012f8bdc..6bf8d82141 100644 --- a/dom/canvas/WebGLElementArrayCache.cpp +++ b/dom/canvas/WebGLElementArrayCache.cpp @@ -308,7 +308,8 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(this) + mTreeData.SizeOfExcludingThis(mallocSizeOf); + return mallocSizeOf(this) + + mTreeData.ShallowSizeOfExcludingThis(mallocSizeOf); } }; @@ -621,7 +622,7 @@ size_t WebGLElementArrayCache::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const { return mallocSizeOf(this) + - mBytes.SizeOfExcludingThis(mallocSizeOf) + + mBytes.ShallowSizeOfExcludingThis(mallocSizeOf) + SizeOfNullable(mallocSizeOf, mUint8Tree) + SizeOfNullable(mallocSizeOf, mUint16Tree) + SizeOfNullable(mallocSizeOf, mUint32Tree); diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index 7ca53829f5..5925db9ca6 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -1441,7 +1441,7 @@ size_t EventListenerManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mListeners.SizeOfExcludingThis(aMallocSizeOf); + n += mListeners.ShallowSizeOfExcludingThis(aMallocSizeOf); uint32_t count = mListeners.Length(); for (uint32_t i = 0; i < count; ++i) { JSEventHandler* jsEventHandler = diff --git a/dom/media/AudioSegment.h b/dom/media/AudioSegment.h index e0c77708fb..72df76d8c3 100644 --- a/dom/media/AudioSegment.h +++ b/dom/media/AudioSegment.h @@ -27,9 +27,9 @@ public: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t amount = 0; - amount += mBuffers.SizeOfExcludingThis(aMallocSizeOf); + amount += mBuffers.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mBuffers.Length(); i++) { - amount += mBuffers[i].SizeOfExcludingThis(aMallocSizeOf); + amount += mBuffers[i].ShallowSizeOfExcludingThis(aMallocSizeOf); } return amount; @@ -149,7 +149,7 @@ struct AudioChunk { } // Memory in the array is owned by mBuffer. - amount += mChannelData.SizeOfExcludingThis(aMallocSizeOf); + amount += mChannelData.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/AudioStream.cpp b/dom/media/AudioStream.cpp index 9cc18cc97c..0f2cbb457a 100644 --- a/dom/media/AudioStream.cpp +++ b/dom/media/AudioStream.cpp @@ -163,7 +163,7 @@ AudioStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const // - mLatencyLog // - mCubebStream - amount += mInserts.SizeOfExcludingThis(aMallocSizeOf); + amount += mInserts.ShallowSizeOfExcludingThis(aMallocSizeOf); amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf); return amount; diff --git a/dom/media/MediaCache.cpp b/dom/media/MediaCache.cpp index 7c4207a344..61b6692625 100644 --- a/dom/media/MediaCache.cpp +++ b/dom/media/MediaCache.cpp @@ -391,7 +391,7 @@ size_t MediaCacheStream::SizeOfExcludingThis( // Looks like these are not owned: // - mClient // - mPrincipal - size_t size = mBlocks.SizeOfExcludingThis(aMallocSizeOf); + size_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf); size += mReadaheadBlocks.SizeOfExcludingThis(aMallocSizeOf); size += mMetadataBlocks.SizeOfExcludingThis(aMallocSizeOf); size += mPlayedBlocks.SizeOfExcludingThis(aMallocSizeOf); diff --git a/dom/media/MediaSegment.h b/dom/media/MediaSegment.h index a6821e5508..76be32869f 100644 --- a/dom/media/MediaSegment.h +++ b/dom/media/MediaSegment.h @@ -291,7 +291,7 @@ public: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { - size_t amount = mChunks.SizeOfExcludingThis(aMallocSizeOf); + size_t amount = mChunks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mChunks.Length(); i++) { amount += mChunks[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf); } diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 264aa1eaa8..954e7de2b5 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1960,15 +1960,15 @@ MediaStream::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const // - mAudioOutputStream - elements amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf); - amount += mAudioOutputs.SizeOfExcludingThis(aMallocSizeOf); - amount += mVideoOutputs.SizeOfExcludingThis(aMallocSizeOf); + amount += mAudioOutputs.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += mVideoOutputs.ShallowSizeOfExcludingThis(aMallocSizeOf); amount += mExplicitBlockerCount.SizeOfExcludingThis(aMallocSizeOf); - amount += mListeners.SizeOfExcludingThis(aMallocSizeOf); - amount += mMainThreadListeners.SizeOfExcludingThis(aMallocSizeOf); - amount += mDisabledTrackIDs.SizeOfExcludingThis(aMallocSizeOf); + amount += mListeners.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += mMainThreadListeners.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += mDisabledTrackIDs.ShallowSizeOfExcludingThis(aMallocSizeOf); amount += mBlocked.SizeOfExcludingThis(aMallocSizeOf); amount += mGraphUpdateIndices.SizeOfExcludingThis(aMallocSizeOf); - amount += mConsumers.SizeOfExcludingThis(aMallocSizeOf); + amount += mConsumers.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index c660f1a2a7..2c01ee311f 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -1192,7 +1192,7 @@ public: size_t amount = MediaStream::SizeOfExcludingThis(aMallocSizeOf); // Not owned: // - mInputs elements - amount += mInputs.SizeOfExcludingThis(aMallocSizeOf); + amount += mInputs.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/RtspMediaResource.cpp b/dom/media/RtspMediaResource.cpp index 3c659bd6b0..5465df128b 100644 --- a/dom/media/RtspMediaResource.cpp +++ b/dom/media/RtspMediaResource.cpp @@ -541,7 +541,7 @@ size_t RtspMediaResource::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t size = BaseMediaResource::SizeOfExcludingThis(aMallocSizeOf); - size += mTrackBuffer.SizeOfExcludingThis(aMallocSizeOf); + size += mTrackBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); // Include the size of each track buffer. for (size_t i = 0; i < mTrackBuffer.Length(); i++) { diff --git a/dom/media/StreamBuffer.h b/dom/media/StreamBuffer.h index 2c1ae896a7..79af493911 100644 --- a/dom/media/StreamBuffer.h +++ b/dom/media/StreamBuffer.h @@ -169,7 +169,7 @@ public: size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = 0; - amount += mTracks.SizeOfExcludingThis(aMallocSizeOf); + amount += mTracks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mTracks.Length(); i++) { amount += mTracks[i]->SizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/TimeVarying.h b/dom/media/TimeVarying.h index a319559a12..1babfc2faf 100644 --- a/dom/media/TimeVarying.h +++ b/dom/media/TimeVarying.h @@ -217,7 +217,7 @@ public: size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { - return mChanges.SizeOfExcludingThis(aMallocSizeOf); + return mChanges.ShallowSizeOfExcludingThis(aMallocSizeOf); } private: diff --git a/dom/media/encoder/MediaEncoder.cpp b/dom/media/encoder/MediaEncoder.cpp index 37bd1db144..0c734f4f04 100644 --- a/dom/media/encoder/MediaEncoder.cpp +++ b/dom/media/encoder/MediaEncoder.cpp @@ -211,7 +211,7 @@ MediaEncoder::GetEncodedData(nsTArray >* aOutputBufs, rv = mWriter->GetContainerData(aOutputBufs, ContainerWriter::GET_HEADER); if (aOutputBufs != nullptr) { - mSizeOfBuffer = aOutputBufs->SizeOfExcludingThis(MallocSizeOf); + mSizeOfBuffer = aOutputBufs->ShallowSizeOfExcludingThis(MallocSizeOf); } if (NS_FAILED(rv)) { LOG(LogLevel::Error,("Error! writer fail to generate header!")); @@ -246,7 +246,7 @@ MediaEncoder::GetEncodedData(nsTArray >* aOutputBufs, isAudioCompleted && isVideoCompleted ? ContainerWriter::FLUSH_NEEDED : 0); if (aOutputBufs != nullptr) { - mSizeOfBuffer = aOutputBufs->SizeOfExcludingThis(MallocSizeOf); + mSizeOfBuffer = aOutputBufs->ShallowSizeOfExcludingThis(MallocSizeOf); } if (NS_SUCCEEDED(rv)) { // Successfully get the copy of final container data from writer. diff --git a/dom/media/mediasource/ResourceQueue.cpp b/dom/media/mediasource/ResourceQueue.cpp index 83f4ee0780..84c481d074 100644 --- a/dom/media/mediasource/ResourceQueue.cpp +++ b/dom/media/mediasource/ResourceQueue.cpp @@ -32,7 +32,7 @@ ResourceItem::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const size_t size = aMallocSizeOf(this); // size excluding this - size += mData->SizeOfExcludingThis(aMallocSizeOf); + size += mData->ShallowSizeOfExcludingThis(aMallocSizeOf); return size; } diff --git a/dom/media/webaudio/AnalyserNode.cpp b/dom/media/webaudio/AnalyserNode.cpp index 8c3642c97c..373d605792 100644 --- a/dom/media/webaudio/AnalyserNode.cpp +++ b/dom/media/webaudio/AnalyserNode.cpp @@ -101,8 +101,8 @@ AnalyserNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf); amount += mAnalysisBlock.SizeOfExcludingThis(aMallocSizeOf); - amount += mChunks.SizeOfExcludingThis(aMallocSizeOf); - amount += mOutputBuffer.SizeOfExcludingThis(aMallocSizeOf); + amount += mChunks.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += mOutputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/AudioBuffer.cpp b/dom/media/webaudio/AudioBuffer.cpp index 0ad4d55fce..069b8ae9f9 100644 --- a/dom/media/webaudio/AudioBuffer.cpp +++ b/dom/media/webaudio/AudioBuffer.cpp @@ -260,7 +260,7 @@ size_t AudioBuffer::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += mJSChannels.SizeOfExcludingThis(aMallocSizeOf); + amount += mJSChannels.ShallowSizeOfExcludingThis(aMallocSizeOf); if (mSharedChannels) { amount += mSharedChannels->SizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp index ed82af16ae..ae99809ccd 100644 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -1007,7 +1007,7 @@ AudioContext::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const if (mListener) { amount += mListener->SizeOfIncludingThis(aMallocSizeOf); } - amount += mDecodeJobs.SizeOfExcludingThis(aMallocSizeOf); + amount += mDecodeJobs.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mDecodeJobs.Length(); ++i) { amount += mDecodeJobs[i]->SizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/AudioDestinationNode.cpp b/dom/media/webaudio/AudioDestinationNode.cpp index 80f81a6740..8b889218e1 100644 --- a/dom/media/webaudio/AudioDestinationNode.cpp +++ b/dom/media/webaudio/AudioDestinationNode.cpp @@ -186,7 +186,7 @@ public: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); - amount += mInputChannels.SizeOfExcludingThis(aMallocSizeOf); + amount += mInputChannels.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/AudioListener.cpp b/dom/media/webaudio/AudioListener.cpp index 6b08531e46..0bd11156a4 100644 --- a/dom/media/webaudio/AudioListener.cpp +++ b/dom/media/webaudio/AudioListener.cpp @@ -122,7 +122,7 @@ AudioListener::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); // AudioNodes are tracked separately - amount += mPanners.SizeOfExcludingThis(aMallocSizeOf); + amount += mPanners.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/AudioNode.cpp b/dom/media/webaudio/AudioNode.cpp index 5d84e54a96..0cc9fea781 100644 --- a/dom/media/webaudio/AudioNode.cpp +++ b/dom/media/webaudio/AudioNode.cpp @@ -92,16 +92,16 @@ AudioNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const // - mStream size_t amount = 0; - amount += mInputNodes.SizeOfExcludingThis(aMallocSizeOf); + amount += mInputNodes.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mInputNodes.Length(); i++) { amount += mInputNodes[i].SizeOfExcludingThis(aMallocSizeOf); } // Just measure the array. The entire audio node graph is measured via the // MediaStreamGraph's streams, so we don't want to double-count the elements. - amount += mOutputNodes.SizeOfExcludingThis(aMallocSizeOf); + amount += mOutputNodes.ShallowSizeOfExcludingThis(aMallocSizeOf); - amount += mOutputParams.SizeOfExcludingThis(aMallocSizeOf); + amount += mOutputParams.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mOutputParams.Length(); i++) { amount += mOutputParams[i]->SizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/AudioNodeEngine.h b/dom/media/webaudio/AudioNodeEngine.h index 7b8d84a2cc..05d932e470 100644 --- a/dom/media/webaudio/AudioNodeEngine.h +++ b/dom/media/webaudio/AudioNodeEngine.h @@ -96,7 +96,7 @@ public: virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override { size_t amount = ThreadSharedObject::SizeOfExcludingThis(aMallocSizeOf); - amount += mContents.SizeOfExcludingThis(aMallocSizeOf); + amount += mContents.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mContents.Length(); i++) { amount += mContents[i].SizeOfExcludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/AudioNodeStream.cpp b/dom/media/webaudio/AudioNodeStream.cpp index ecbfbc4810..030ef19e05 100644 --- a/dom/media/webaudio/AudioNodeStream.cpp +++ b/dom/media/webaudio/AudioNodeStream.cpp @@ -62,7 +62,7 @@ AudioNodeStream::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const // - mEngine amount += ProcessedMediaStream::SizeOfExcludingThis(aMallocSizeOf); - amount += mLastChunks.SizeOfExcludingThis(aMallocSizeOf); + amount += mLastChunks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mLastChunks.Length(); i++) { // NB: This is currently unshared only as there are instances of // double reporting in DMD otherwise. diff --git a/dom/media/webaudio/AudioParam.h b/dom/media/webaudio/AudioParam.h index 289833e85b..b006608be5 100644 --- a/dom/media/webaudio/AudioParam.h +++ b/dom/media/webaudio/AudioParam.h @@ -169,7 +169,7 @@ public: // - mNode // Just count the array, actual nodes are counted in mNode. - amount += mInputNodes.SizeOfExcludingThis(aMallocSizeOf); + amount += mInputNodes.ShallowSizeOfExcludingThis(aMallocSizeOf); if (mNodeStreamPort) { amount += mNodeStreamPort->SizeOfIncludingThis(aMallocSizeOf); diff --git a/dom/media/webaudio/BiquadFilterNode.cpp b/dom/media/webaudio/BiquadFilterNode.cpp index b5bf83a70d..643d1a0679 100644 --- a/dom/media/webaudio/BiquadFilterNode.cpp +++ b/dom/media/webaudio/BiquadFilterNode.cpp @@ -218,7 +218,7 @@ public: // - mDestination - probably not owned // - AudioParamTimelines - counted in the AudioNode size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); - amount += mBiquads.SizeOfExcludingThis(aMallocSizeOf); + amount += mBiquads.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/DelayBuffer.cpp b/dom/media/webaudio/DelayBuffer.cpp index 1bf0a480ae..97c3b173af 100644 --- a/dom/media/webaudio/DelayBuffer.cpp +++ b/dom/media/webaudio/DelayBuffer.cpp @@ -16,12 +16,12 @@ size_t DelayBuffer::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = 0; - amount += mChunks.SizeOfExcludingThis(aMallocSizeOf); + amount += mChunks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mChunks.Length(); i++) { amount += mChunks[i].SizeOfExcludingThis(aMallocSizeOf, false); } - amount += mUpmixChannels.SizeOfExcludingThis(aMallocSizeOf); + amount += mUpmixChannels.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/FFTBlock.h b/dom/media/webaudio/FFTBlock.h index fc4d57bdc9..d61356c235 100644 --- a/dom/media/webaudio/FFTBlock.h +++ b/dom/media/webaudio/FFTBlock.h @@ -175,7 +175,7 @@ public: size_t amount = 0; amount += aMallocSizeOf(mKissFFT); amount += aMallocSizeOf(mKissIFFT); - amount += mOutputBuffer.SizeOfExcludingThis(aMallocSizeOf); + amount += mOutputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/MediaBufferDecoder.cpp b/dom/media/webaudio/MediaBufferDecoder.cpp index 10a6117416..382af0e21d 100644 --- a/dom/media/webaudio/MediaBufferDecoder.cpp +++ b/dom/media/webaudio/MediaBufferDecoder.cpp @@ -618,7 +618,7 @@ WebAudioDecodeJob::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const if (mOutput) { amount += mOutput->SizeOfIncludingThis(aMallocSizeOf); } - amount += mChannelBuffers.SizeOfExcludingThis(aMallocSizeOf); + amount += mChannelBuffers.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mChannelBuffers.Length(); ++i) { amount += mChannelBuffers[i].SizeOfExcludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/PannerNode.cpp b/dom/media/webaudio/PannerNode.cpp index 20964a28c9..6bfb7ee01d 100644 --- a/dom/media/webaudio/PannerNode.cpp +++ b/dom/media/webaudio/PannerNode.cpp @@ -257,7 +257,7 @@ size_t PannerNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf); - amount += mSources.SizeOfExcludingThis(aMallocSizeOf); + amount += mSources.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/ScriptProcessorNode.cpp b/dom/media/webaudio/ScriptProcessorNode.cpp index f0eb3b82aa..62aa4b5fc7 100644 --- a/dom/media/webaudio/ScriptProcessorNode.cpp +++ b/dom/media/webaudio/ScriptProcessorNode.cpp @@ -316,7 +316,7 @@ public: // - mSource (probably) // - mDestination (probably) size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); - amount += mInputChannels.SizeOfExcludingThis(aMallocSizeOf); + amount += mInputChannels.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < mInputChannels.Length(); i++) { amount += mInputChannels[i].SizeOfExcludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/WaveShaperNode.cpp b/dom/media/webaudio/WaveShaperNode.cpp index 089da6dbfd..e288d2bf32 100644 --- a/dom/media/webaudio/WaveShaperNode.cpp +++ b/dom/media/webaudio/WaveShaperNode.cpp @@ -135,7 +135,7 @@ public: // Future: properly measure speex memory amount += aMallocSizeOf(mUpSampler); amount += aMallocSizeOf(mDownSampler); - amount += mBuffer.SizeOfExcludingThis(aMallocSizeOf); + amount += mBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } @@ -259,7 +259,7 @@ public: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); - amount += mCurve.SizeOfExcludingThis(aMallocSizeOf); + amount += mCurve.ShallowSizeOfExcludingThis(aMallocSizeOf); amount += mResampler.SizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/blink/DirectConvolver.h b/dom/media/webaudio/blink/DirectConvolver.h index 1ac6bfcb74..5732da6496 100644 --- a/dom/media/webaudio/blink/DirectConvolver.h +++ b/dom/media/webaudio/blink/DirectConvolver.h @@ -45,7 +45,7 @@ public: size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += m_buffer.SizeOfExcludingThis(aMallocSizeOf); + amount += m_buffer.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/blink/DynamicsCompressor.cpp b/dom/media/webaudio/blink/DynamicsCompressor.cpp index 51ad079f43..746356d1d0 100644 --- a/dom/media/webaudio/blink/DynamicsCompressor.cpp +++ b/dom/media/webaudio/blink/DynamicsCompressor.cpp @@ -55,14 +55,14 @@ DynamicsCompressor::DynamicsCompressor(float sampleRate, unsigned numberOfChanne size_t DynamicsCompressor::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += m_preFilterPacks.SizeOfExcludingThis(aMallocSizeOf); + amount += m_preFilterPacks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_preFilterPacks.Length(); i++) { if (m_preFilterPacks[i]) { amount += m_preFilterPacks[i]->sizeOfIncludingThis(aMallocSizeOf); } } - amount += m_postFilterPacks.SizeOfExcludingThis(aMallocSizeOf); + amount += m_postFilterPacks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_postFilterPacks.Length(); i++) { if (m_postFilterPacks[i]) { amount += m_postFilterPacks[i]->sizeOfIncludingThis(aMallocSizeOf); diff --git a/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp b/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp index 882c7a1911..eec04528ca 100644 --- a/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp +++ b/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp @@ -76,7 +76,7 @@ DynamicsCompressorKernel::DynamicsCompressorKernel(float sampleRate, unsigned nu size_t DynamicsCompressorKernel::sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = 0; - amount += m_preDelayBuffers.SizeOfExcludingThis(aMallocSizeOf); + amount += m_preDelayBuffers.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_preDelayBuffers.Length(); i++) { amount += m_preDelayBuffers[i].SizeOfExcludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/blink/FFTConvolver.cpp b/dom/media/webaudio/blink/FFTConvolver.cpp index 558ed753d4..9d3305c7d1 100644 --- a/dom/media/webaudio/blink/FFTConvolver.cpp +++ b/dom/media/webaudio/blink/FFTConvolver.cpp @@ -49,9 +49,9 @@ size_t FFTConvolver::sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) co { size_t amount = 0; amount += m_frame.SizeOfExcludingThis(aMallocSizeOf); - amount += m_inputBuffer.SizeOfExcludingThis(aMallocSizeOf); - amount += m_outputBuffer.SizeOfExcludingThis(aMallocSizeOf); - amount += m_lastOverlapBuffer.SizeOfExcludingThis(aMallocSizeOf); + amount += m_inputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_outputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_lastOverlapBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/blink/HRTFDatabase.cpp b/dom/media/webaudio/blink/HRTFDatabase.cpp index a223da1a82..ef236c8554 100644 --- a/dom/media/webaudio/blink/HRTFDatabase.cpp +++ b/dom/media/webaudio/blink/HRTFDatabase.cpp @@ -82,7 +82,7 @@ HRTFDatabase::HRTFDatabase(float sampleRate) size_t HRTFDatabase::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += m_elevations.SizeOfExcludingThis(aMallocSizeOf); + amount += m_elevations.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_elevations.Length(); i++) { amount += m_elevations[i]->sizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/blink/HRTFElevation.cpp b/dom/media/webaudio/blink/HRTFElevation.cpp index d782cac05a..2d9dd2984c 100644 --- a/dom/media/webaudio/blink/HRTFElevation.cpp +++ b/dom/media/webaudio/blink/HRTFElevation.cpp @@ -54,7 +54,7 @@ size_t HRTFElevation::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) c { size_t amount = aMallocSizeOf(this); - amount += m_kernelListL.SizeOfExcludingThis(aMallocSizeOf); + amount += m_kernelListL.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_kernelListL.Length(); i++) { amount += m_kernelListL[i]->sizeOfIncludingThis(aMallocSizeOf); } diff --git a/dom/media/webaudio/blink/HRTFPanner.cpp b/dom/media/webaudio/blink/HRTFPanner.cpp index 7107e56cfd..54f08e21bf 100644 --- a/dom/media/webaudio/blink/HRTFPanner.cpp +++ b/dom/media/webaudio/blink/HRTFPanner.cpp @@ -80,10 +80,10 @@ size_t HRTFPanner::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) cons amount += m_convolverL2.sizeOfExcludingThis(aMallocSizeOf); amount += m_convolverR2.sizeOfExcludingThis(aMallocSizeOf); amount += m_delayLine.SizeOfExcludingThis(aMallocSizeOf); - amount += m_tempL1.SizeOfExcludingThis(aMallocSizeOf); - amount += m_tempL2.SizeOfExcludingThis(aMallocSizeOf); - amount += m_tempR1.SizeOfExcludingThis(aMallocSizeOf); - amount += m_tempR2.SizeOfExcludingThis(aMallocSizeOf); + amount += m_tempL1.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_tempL2.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_tempR1.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_tempR2.ShallowSizeOfExcludingThis(aMallocSizeOf); return amount; } diff --git a/dom/media/webaudio/blink/PeriodicWave.cpp b/dom/media/webaudio/blink/PeriodicWave.cpp index 2a0d313f0f..d587a27c15 100644 --- a/dom/media/webaudio/blink/PeriodicWave.cpp +++ b/dom/media/webaudio/blink/PeriodicWave.cpp @@ -99,10 +99,10 @@ size_t PeriodicWave::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) co { size_t amount = aMallocSizeOf(this); - amount += m_bandLimitedTables.SizeOfExcludingThis(aMallocSizeOf); + amount += m_bandLimitedTables.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_bandLimitedTables.Length(); i++) { if (m_bandLimitedTables[i]) { - amount += m_bandLimitedTables[i]->SizeOfIncludingThis(aMallocSizeOf); + amount += m_bandLimitedTables[i]->ShallowSizeOfIncludingThis(aMallocSizeOf); } } diff --git a/dom/media/webaudio/blink/Reverb.cpp b/dom/media/webaudio/blink/Reverb.cpp index e705dd0460..42137595eb 100644 --- a/dom/media/webaudio/blink/Reverb.cpp +++ b/dom/media/webaudio/blink/Reverb.cpp @@ -108,7 +108,7 @@ Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulse size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += m_convolvers.SizeOfExcludingThis(aMallocSizeOf); + amount += m_convolvers.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_convolvers.Length(); i++) { if (m_convolvers[i]) { amount += m_convolvers[i]->sizeOfIncludingThis(aMallocSizeOf); diff --git a/dom/media/webaudio/blink/ReverbAccumulationBuffer.h b/dom/media/webaudio/blink/ReverbAccumulationBuffer.h index e90d198175..e07e71061c 100644 --- a/dom/media/webaudio/blink/ReverbAccumulationBuffer.h +++ b/dom/media/webaudio/blink/ReverbAccumulationBuffer.h @@ -61,7 +61,7 @@ public: size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return m_buffer.SizeOfExcludingThis(aMallocSizeOf); + return m_buffer.ShallowSizeOfExcludingThis(aMallocSizeOf); } private: diff --git a/dom/media/webaudio/blink/ReverbConvolver.cpp b/dom/media/webaudio/blink/ReverbConvolver.cpp index 45e63e44da..34212864d9 100644 --- a/dom/media/webaudio/blink/ReverbConvolver.cpp +++ b/dom/media/webaudio/blink/ReverbConvolver.cpp @@ -154,14 +154,14 @@ ReverbConvolver::~ReverbConvolver() size_t ReverbConvolver::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t amount = aMallocSizeOf(this); - amount += m_stages.SizeOfExcludingThis(aMallocSizeOf); + amount += m_stages.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_stages.Length(); i++) { if (m_stages[i]) { amount += m_stages[i]->sizeOfIncludingThis(aMallocSizeOf); } } - amount += m_backgroundStages.SizeOfExcludingThis(aMallocSizeOf); + amount += m_backgroundStages.ShallowSizeOfExcludingThis(aMallocSizeOf); for (size_t i = 0; i < m_backgroundStages.Length(); i++) { if (m_backgroundStages[i]) { amount += m_backgroundStages[i]->sizeOfIncludingThis(aMallocSizeOf); diff --git a/dom/media/webaudio/blink/ReverbConvolverStage.cpp b/dom/media/webaudio/blink/ReverbConvolverStage.cpp index cf44e67693..fe6a0929cb 100644 --- a/dom/media/webaudio/blink/ReverbConvolverStage.cpp +++ b/dom/media/webaudio/blink/ReverbConvolverStage.cpp @@ -99,9 +99,9 @@ size_t ReverbConvolverStage::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSi amount += m_fftConvolver->sizeOfIncludingThis(aMallocSizeOf); } - amount += m_preDelayBuffer.SizeOfExcludingThis(aMallocSizeOf); - amount += m_temporaryBuffer.SizeOfExcludingThis(aMallocSizeOf); - amount += m_directKernel.SizeOfExcludingThis(aMallocSizeOf); + amount += m_preDelayBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_temporaryBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_directKernel.ShallowSizeOfExcludingThis(aMallocSizeOf); if (m_directConvolver) { amount += m_directConvolver->sizeOfIncludingThis(aMallocSizeOf); diff --git a/dom/media/webaudio/blink/ReverbInputBuffer.h b/dom/media/webaudio/blink/ReverbInputBuffer.h index 8d843971ca..906021c0d1 100644 --- a/dom/media/webaudio/blink/ReverbInputBuffer.h +++ b/dom/media/webaudio/blink/ReverbInputBuffer.h @@ -57,7 +57,7 @@ public: size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return m_buffer.SizeOfExcludingThis(aMallocSizeOf); + return m_buffer.ShallowSizeOfExcludingThis(aMallocSizeOf); } diff --git a/dom/svg/SVGPathData.cpp b/dom/svg/SVGPathData.cpp index b43c796e12..2294eb4509 100644 --- a/dom/svg/SVGPathData.cpp +++ b/dom/svg/SVGPathData.cpp @@ -861,7 +861,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray *aMarks) const size_t SVGPathData::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { - return mData.SizeOfExcludingThis(aMallocSizeOf); + return mData.ShallowSizeOfExcludingThis(aMallocSizeOf); } size_t diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index b2dcb87dad..d1d5be737d 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -1345,7 +1345,7 @@ gfxDWriteFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, aMallocSizeOf); aSizes->mFontListSize += - mNonExistingFonts.SizeOfExcludingThis(aMallocSizeOf); + mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mNonExistingFonts.Length(); ++i) { aSizes->mFontListSize += mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf); diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 47adc89533..7906740b99 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1062,8 +1062,8 @@ protected: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) { return aMallocSizeOf(this) + - mDetails.SizeOfExcludingThis(aMallocSizeOf) + - mOffsetToIndex.SizeOfExcludingThis(aMallocSizeOf); + mDetails.ShallowSizeOfExcludingThis(aMallocSizeOf) + + mOffsetToIndex.ShallowSizeOfExcludingThis(aMallocSizeOf); } private: diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index 80214611c9..1b43d91dd8 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -566,7 +566,7 @@ public: } size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { - return mTableData.SizeOfExcludingThis(aMallocSizeOf); + return mTableData.ShallowSizeOfExcludingThis(aMallocSizeOf); } size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); @@ -1837,7 +1837,7 @@ gfxFontFamily::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, mFamilyCharacterMap.SizeOfExcludingThis(aMallocSizeOf); aSizes->mFontListSize += - mAvailableFonts.SizeOfExcludingThis(aMallocSizeOf); + mAvailableFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mAvailableFonts.Length(); ++i) { gfxFontEntry *fe = mAvailableFonts[i]; if (fe) { diff --git a/gfx/thebes/gfxFontFamilyList.h b/gfx/thebes/gfxFontFamilyList.h index 7e3be5cc30..6bd7c47001 100644 --- a/gfx/thebes/gfxFontFamilyList.h +++ b/gfx/thebes/gfxFontFamilyList.h @@ -149,12 +149,12 @@ struct FontFamilyName final { } // memory reporting - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { + size_t SizeOfExcludingThis2(mozilla::MallocSizeOf aMallocSizeOf) const { return mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); } - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); + size_t SizeOfIncludingThis2(mozilla::MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this) + SizeOfExcludingThis2(aMallocSizeOf); } FontFamilyType mType; @@ -337,7 +337,7 @@ public: // memory reporting size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return mFontlist.SizeOfExcludingThis(aMallocSizeOf); + return mFontlist.ShallowSizeOfExcludingThis(aMallocSizeOf); } size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index 88e975d7bf..dba58fb893 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -246,7 +246,7 @@ public: } size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - size_t total = mBlocks.SizeOfExcludingThis(aMallocSizeOf); + size_t total = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mBlocks.Length(); i++) { if (mBlocks[i]) { total += aMallocSizeOf(mBlocks[i]); diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index 1509748e8f..7370012f3d 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -946,7 +946,7 @@ gfxGDIFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, mFontSubstitutes.SizeOfExcludingThis(SizeOfFamilyNameEntryExcludingThis, aMallocSizeOf); aSizes->mFontListSize += - mNonExistingFonts.SizeOfExcludingThis(aMallocSizeOf); + mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mNonExistingFonts.Length(); ++i) { aSizes->mFontListSize += mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf); diff --git a/gfx/thebes/gfxGlyphExtents.cpp b/gfx/thebes/gfxGlyphExtents.cpp index 2a946456ce..87202aaf6b 100644 --- a/gfx/thebes/gfxGlyphExtents.cpp +++ b/gfx/thebes/gfxGlyphExtents.cpp @@ -79,7 +79,7 @@ uint32_t gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { uint32_t i; - uint32_t size = mBlocks.SizeOfExcludingThis(aMallocSizeOf); + uint32_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (i = 0; i < mBlocks.Length(); ++i) { uintptr_t bits = mBlocks[i]; if (bits && !(bits & 0x1)) { diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 4c0ed0f15b..d6799d8061 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -1132,7 +1132,7 @@ SizeOfPrefFontEntryExcludingThis // again, we only care about the size of the array itself; we don't follow // the refPtrs stored in it, because they point to entries already owned // and accounted-for by the main font list - return aList.SizeOfExcludingThis(aMallocSizeOf); + return aList.ShallowSizeOfExcludingThis(aMallocSizeOf); } static size_t @@ -1174,7 +1174,7 @@ gfxPlatformFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, aSizes->mFontListSize += mCodepointsWithNoFonts.SizeOfExcludingThis(aMallocSizeOf); aSizes->mFontListSize += - mFontFamiliesToLoad.SizeOfExcludingThis(aMallocSizeOf); + mFontFamiliesToLoad.ShallowSizeOfExcludingThis(aMallocSizeOf); aSizes->mFontListSize += mPrefFonts.SizeOfExcludingThis(SizeOfPrefFontEntryExcludingThis, diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 1189a5faf9..30f49269dd 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -1479,7 +1479,7 @@ gfxTextRun::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) { // The second arg is how much gfxTextRun::AllocateStorage would have // allocated. - size_t total = mGlyphRuns.SizeOfExcludingThis(aMallocSizeOf); + size_t total = mGlyphRuns.ShallowSizeOfExcludingThis(aMallocSizeOf); if (mDetailedGlyphs) { total += mDetailedGlyphs->SizeOfIncludingThis(aMallocSizeOf); diff --git a/image/SourceBuffer.cpp b/image/SourceBuffer.cpp index f5c875e395..7b425e9494 100644 --- a/image/SourceBuffer.cpp +++ b/image/SourceBuffer.cpp @@ -397,7 +397,7 @@ SourceBuffer::SizeOfIncludingThisWithComputedFallback(MallocSizeOf MutexAutoLock lock(mMutex); size_t n = aMallocSizeOf(this); - n += mChunks.SizeOfExcludingThis(aMallocSizeOf); + n += mChunks.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0 ; i < mChunks.Length() ; ++i) { size_t chunkSize = aMallocSizeOf(mChunks[i].Data()); diff --git a/layout/base/FramePropertyTable.h b/layout/base/FramePropertyTable.h index fcd8fca1bc..188f5304f2 100644 --- a/layout/base/FramePropertyTable.h +++ b/layout/base/FramePropertyTable.h @@ -169,7 +169,7 @@ protected: // their types are opaque. if (IsArray()) { nsTArray* array = ToArray(); - n += array->SizeOfExcludingThis(aMallocSizeOf); + n += array->ShallowSizeOfExcludingThis(aMallocSizeOf); } return n; } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index e5b910fc2c..26b14e51b2 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -363,6 +363,11 @@ AddAnimationForProperty(nsIFrame* aFrame, const AnimationProperty& aProperty, MOZ_ASSERT(aLayer->AsContainerLayer(), "Should only animate ContainerLayer"); MOZ_ASSERT(aAnimation->GetEffect(), "Should not be adding an animation without an effect"); + MOZ_ASSERT(!aAnimation->GetCurrentOrPendingStartTime().IsNull() || + (aAnimation->Timeline() && + aAnimation->Timeline()->TracksWallclockTime()), + "Animation should either have a resolved start time or " + "a timeline that tracks wallclock time"); nsStyleContext* styleContext = aFrame->StyleContext(); nsPresContext* presContext = aFrame->PresContext(); TransformReferenceBox refBox(aFrame); @@ -449,20 +454,20 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, MOZ_ASSERT(property->mWinsInCascade, "GetAnimationOfProperty already tested mWinsInCascade"); - // Don't add animations that are pending when their corresponding - // refresh driver is under test control. This is because any pending - // animations on layers will have their start time updated with the - // current timestamp but when the refresh driver is under test control - // its refresh times are unrelated to timestamp values. + // Don't add animations that are pending if their timeline does not + // track wallclock time. This is because any pending animations on layers + // will have their start time updated with the current wallclock time. + // If we can't convert that wallclock time back to an equivalent timeline + // time, we won't be able to update the content animation and it will end + // up being out of sync with the layer animation. // - // Instead we leave the animation running on the main thread and the - // next time the refresh driver is advanced it will trigger any pending - // animations. - if (anim->PlayState() == AnimationPlayState::Pending) { - nsRefreshDriver* driver = anim->Timeline()->GetRefreshDriver(); - if (driver && driver->IsTestControllingRefreshesEnabled()) { - continue; - } + // Currently this only happens when the timeline is driven by a refresh + // driver under test control. In this case, the next time the refresh + // driver is advanced it will trigger any pending animations. + if (anim->PlayState() == AnimationPlayState::Pending && + (!anim->Timeline() || + !anim->Timeline()->TracksWallclockTime())) { + continue; } AddAnimationForProperty(aFrame, *property, anim, aLayer, aData, aPending); diff --git a/layout/base/nsPresArena.h b/layout/base/nsPresArena.h index 807c19074a..dcf5ba586d 100644 --- a/layout/base/nsPresArena.h +++ b/layout/base/nsPresArena.h @@ -137,7 +137,7 @@ private: { return NS_PTR_TO_INT32(aKey); } size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const - { return mEntries.SizeOfExcludingThis(aMallocSizeOf); } + { return mEntries.ShallowSizeOfExcludingThis(aMallocSizeOf); } enum { ALLOW_MEMMOVE = false }; }; diff --git a/layout/generic/nsTextRunTransformations.cpp b/layout/generic/nsTextRunTransformations.cpp index 72e81d6721..6a0f5a572b 100644 --- a/layout/generic/nsTextRunTransformations.cpp +++ b/layout/generic/nsTextRunTransformations.cpp @@ -87,8 +87,8 @@ size_t nsTransformedTextRun::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) { size_t total = gfxTextRun::SizeOfExcludingThis(aMallocSizeOf); - total += mStyles.SizeOfExcludingThis(aMallocSizeOf); - total += mCapitalize.SizeOfExcludingThis(aMallocSizeOf); + total += mStyles.ShallowSizeOfExcludingThis(aMallocSizeOf); + total += mCapitalize.ShallowSizeOfExcludingThis(aMallocSizeOf); if (mOwnsFactory) { total += aMallocSizeOf(mFactory); } diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 84550c298b..32e68ed505 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -13,6 +13,7 @@ #include "nsCSSPropertySet.h" #include "nsCSSValue.h" #include "nsCycleCollectionParticipant.h" +#include "nsDOMMutationObserver.h" #include "nsStyleContext.h" #include "nsIFrame.h" #include "nsLayoutUtils.h" @@ -761,6 +762,13 @@ AnimationCollection::PropertyDtor(void *aObject, nsIAtom *aPropertyName, MOZ_ASSERT(!collection->mCalledPropertyDtor, "can't call dtor twice"); collection->mCalledPropertyDtor = true; #endif + { + nsAutoAnimationMutationBatch mb(collection->mElement); + + for (size_t animIdx = collection->mAnimations.Length(); animIdx-- != 0; ) { + collection->mAnimations[animIdx]->CancelFromStyle(); + } + } delete collection; } diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index cac9b0b9d0..5989503c67 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -22,6 +22,7 @@ #include "mozilla/Attributes.h" #include "mozilla/Assertions.h" #include "mozilla/FloatingPoint.h" +#include "nsContentUtils.h" #include "nsCSSPseudoElements.h" #include "nsCycleCollectionParticipant.h" #include "nsCSSPropertySet.h" @@ -266,9 +267,6 @@ struct AnimationCollection : public PRCList void Destroy() { - for (size_t animIdx = mAnimations.Length(); animIdx-- != 0; ) { - mAnimations[animIdx]->CancelFromStyle(); - } // This will call our destructor. mElement->DeleteProperty(mElementProperty); } @@ -452,6 +450,61 @@ public: #endif }; -} +/** + * Utility class for referencing the element that created a CSS animation or + * transition. It is non-owning (i.e. it uses a raw pointer) since it is only + * expected to be set by the owned animation while it actually being managed + * by the owning element. + * + * This class also abstracts the comparison of an element/pseudo-class pair + * for the sake of composite ordering since this logic is common to both CSS + * animations and transitions. + * + * (We call this OwningElementRef instead of just OwningElement so that we can + * call the getter on CSSAnimation/CSSTransition OwningElement() without + * clashing with this object's contructor.) + */ +class OwningElementRef final +{ +public: + OwningElementRef() + : mElement(nullptr) + , mPseudoType(nsCSSPseudoElements::ePseudo_NotPseudoElement) + { } + + OwningElementRef(dom::Element& aElement, + nsCSSPseudoElements::Type aPseudoType) + : mElement(&aElement) + , mPseudoType(aPseudoType) + { } + + bool Equals(const OwningElementRef& aOther) const + { + return mElement == aOther.mElement && + mPseudoType == aOther.mPseudoType; + } + + bool LessThan(const OwningElementRef& aOther) const + { + MOZ_ASSERT(mElement && aOther.mElement, + "Elements to compare should not be null"); + + if (mElement != aOther.mElement) { + return nsContentUtils::PositionIsBefore(mElement, aOther.mElement); + } + + return mPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement || + (mPseudoType == nsCSSPseudoElements::ePseudo_before && + aOther.mPseudoType == nsCSSPseudoElements::ePseudo_after); + } + + bool IsSet() const { return !!mElement; } + +private: + dom::Element* MOZ_NON_OWNING_REF mElement; + nsCSSPseudoElements::Type mPseudoType; +}; + +} // namespace mozilla #endif /* !defined(mozilla_css_AnimationCommon_h) */ diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index f2cf9420f7..17804bd195 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -420,7 +420,7 @@ size_t nsDocumentRuleResultCacheKey::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - n += mMatchingRules.SizeOfExcludingThis(aMallocSizeOf); + n += mMatchingRules.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 675085ff1b..fefb832952 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -1390,7 +1390,7 @@ size_t Declaration::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mOrder.SizeOfExcludingThis(aMallocSizeOf); + n += mOrder.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mData ? mData ->SizeOfIncludingThis(aMallocSizeOf) : 0; n += mImportantData ? mImportantData->SizeOfIncludingThis(aMallocSizeOf) : 0; if (mVariables) { diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index 81c95ecdf5..adeca8e8f3 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -2575,7 +2575,7 @@ Loader::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const if (mSheets) { s += mSheets->mCompleteSheets.SizeOfExcludingThis(CountSheetMemory, aMallocSizeOf); } - s += mObservers.SizeOfExcludingThis(aMallocSizeOf); + s += mObservers.ShallowSizeOfExcludingThis(aMallocSizeOf); // Measurement of the following members may be added later if DMD finds it is // worthwhile: diff --git a/layout/style/RuleProcessorCache.cpp b/layout/style/RuleProcessorCache.cpp index 576b974d82..a21cf74920 100644 --- a/layout/style/RuleProcessorCache.cpp +++ b/layout/style/RuleProcessorCache.cpp @@ -259,9 +259,9 @@ RuleProcessorCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) size_t n = aMallocSizeOf(this); int count = 0; - n += mEntries.SizeOfExcludingThis(aMallocSizeOf); + n += mEntries.ShallowSizeOfExcludingThis(aMallocSizeOf); for (Entry& e : mEntries) { - n += e.mDocumentEntries.SizeOfExcludingThis(aMallocSizeOf); + n += e.mDocumentEntries.ShallowSizeOfExcludingThis(aMallocSizeOf); for (DocumentEntry& de : e.mDocumentEntries) { count++; n += de.mRuleProcessor->SizeOfIncludingThis(aMallocSizeOf); diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index f264feba82..2737f77c7a 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -10,6 +10,7 @@ #include "mozilla/EventDispatcher.h" #include "mozilla/MemoryReporting.h" #include "mozilla/StyleAnimationValue.h" +#include "mozilla/dom/DocumentTimeline.h" #include "mozilla/dom/KeyframeEffect.h" #include "nsPresContext.h" @@ -112,6 +113,50 @@ CSSAnimation::PauseFromStyle() } } +bool +CSSAnimation::HasLowerCompositeOrderThan(const Animation& aOther) const +{ + // 0. Object-equality case + if (&aOther == this) { + return false; + } + + // 1. Transitions sort lower + // + // FIXME: We need to differentiate between transitions and generic Animations. + // Generic animations don't exist yet (that's bug 1096773) so for now we're + // ok. + const CSSAnimation* otherAnimation = aOther.AsCSSAnimation(); + if (!otherAnimation) { + MOZ_ASSERT(aOther.AsCSSTransition(), + "Animation being compared is a CSS transition"); + return false; + } + + // 2. CSS animations using custom composite ordering (i.e. those that + // correspond to an animation-name property) sort lower than other CSS + // animations (e.g. those created or kept-alive by script). + if (!IsUsingCustomCompositeOrder()) { + return !aOther.IsUsingCustomCompositeOrder() ? + Animation::HasLowerCompositeOrderThan(aOther) : + false; + } + if (!aOther.IsUsingCustomCompositeOrder()) { + return true; + } + + // 3. Sort by document order + MOZ_ASSERT(mOwningElement.IsSet() && otherAnimation->OwningElement().IsSet(), + "Animations using custom composite order should have an " + "owning element"); + if (!mOwningElement.Equals(otherAnimation->OwningElement())) { + return mOwningElement.LessThan(otherAnimation->OwningElement()); + } + + // 4. (Same element and pseudo): Sort by position in animation-name + return mSequenceNum < otherAnimation->mSequenceNum; +} + void CSSAnimation::QueueEvents(EventArray& aEventsToDispatch) { @@ -408,6 +453,8 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, } } + oldAnim->CopyAnimationIndex(*newAnim->AsCSSAnimation()); + if (animationChanged) { nsNodeUtils::AnimationChanged(oldAnim); } @@ -511,7 +558,7 @@ ResolvedStyleCache::Get(nsPresContext *aPresContext, void nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, dom::Element* aTarget, - dom::DocumentTimeline* aTimeline, + dom::AnimationTimeline* aTimeline, AnimationPtrArray& aAnimations) { MOZ_ASSERT(aAnimations.IsEmpty(), "expect empty array"); @@ -539,7 +586,12 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, continue; } - nsRefPtr dest = new CSSAnimation(aTimeline, src.GetName()); + nsRefPtr dest = + new CSSAnimation(mPresContext->Document()->GetScopeObject(), aTimeline, + src.GetName()); + dest->SetOwningElement( + OwningElementRef(*aTarget, aStyleContext->GetPseudoType())); + dest->SetAnimationIndex(static_cast(animIdx)); aAnimations.AppendElement(dest); AnimationTiming timing; diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 84e94cb77e..811ae94d74 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -13,6 +13,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/TimeStamp.h" +class nsIGlobalObject; class nsStyleContext; namespace mozilla { @@ -56,9 +57,10 @@ namespace dom { class CSSAnimation final : public Animation { public: - explicit CSSAnimation(DocumentTimeline* aTimeline, + explicit CSSAnimation(nsIGlobalObject* aGlobal, + dom::AnimationTimeline* aTimeline, const nsSubstring& aAnimationName) - : Animation(aTimeline) + : dom::Animation(aGlobal, aTimeline) , mAnimationName(aAnimationName) , mIsStylePaused(false) , mPauseShouldStick(false) @@ -73,7 +75,8 @@ public: JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - virtual CSSAnimation* AsCSSAnimation() override { return this; } + CSSAnimation* AsCSSAnimation() override { return this; } + const CSSAnimation* AsCSSAnimation() const override { return this; } // CSSAnimation interface void GetAnimationName(nsString& aRetVal) const { aRetVal = mAnimationName; } @@ -92,11 +95,62 @@ public: void PlayFromStyle(); void PauseFromStyle(); + void CancelFromStyle() override + { + mOwningElement = OwningElementRef(); + Animation::CancelFromStyle(); + MOZ_ASSERT(mSequenceNum == kUnsequenced); + } bool IsStylePaused() const { return mIsStylePaused; } + bool HasLowerCompositeOrderThan(const Animation& aOther) const override; + bool IsUsingCustomCompositeOrder() const override + { + return mOwningElement.IsSet(); + } + + void SetAnimationIndex(uint64_t aIndex) + { + MOZ_ASSERT(IsUsingCustomCompositeOrder()); + mSequenceNum = aIndex; + } + void CopyAnimationIndex(const CSSAnimation& aOther) + { + MOZ_ASSERT(IsUsingCustomCompositeOrder() && + aOther.IsUsingCustomCompositeOrder()); + mSequenceNum = aOther.mSequenceNum; + } + void QueueEvents(EventArray& aEventsToDispatch); + // Returns the element or pseudo-element whose animation-name property + // this CSSAnimation corresponds to (if any). This is used for determining + // the relative composite order of animations generated from CSS markup. + // + // Typically this will be the same as the target element of the keyframe + // effect associated with this animation. However, it can differ in the + // following circumstances: + // + // a) If script removes or replaces the effect of this animation, + // b) If this animation is cancelled (e.g. by updating the + // animation-name property or removing the owning element from the + // document), + // c) If this object is generated from script using the CSSAnimation + // constructor. + // + // For (b) and (c) the returned owning element will return !IsSet(). + const OwningElementRef& OwningElement() const { return mOwningElement; } + + // Sets the owning element which is used for determining the composite + // order of CSSAnimation objects generated from CSS markup. + // + // @see OwningElement() + void SetOwningElement(const OwningElementRef& aElement) + { + mOwningElement = aElement; + } + // Is this animation currently in effect for the purposes of computing // mWinsInCascade. (In general, this can be computed from the timing // function. This boolean remembers the state as of the last time we @@ -105,13 +159,21 @@ public: bool mInEffectForCascadeResults; protected: - virtual ~CSSAnimation() { } + virtual ~CSSAnimation() + { + MOZ_ASSERT(!mOwningElement.IsSet(), "Owning element should be cleared " + "before a CSS animation is destroyed"); + } virtual css::CommonAnimationManager* GetAnimationManager() const override; static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType); nsString mAnimationName; + // The (pseudo-)element whose computed animation-name refers to this + // animation (if any). + OwningElementRef mOwningElement; + // When combining animation-play-state with play() / pause() the following // behavior applies: // 1. pause() is sticky and always overrides the underlying @@ -249,7 +311,7 @@ protected: private: void BuildAnimations(nsStyleContext* aStyleContext, mozilla::dom::Element* aTarget, - mozilla::dom::DocumentTimeline* aTimeline, + mozilla::dom::AnimationTimeline* aTimeline, mozilla::AnimationPtrArray& aAnimations); bool BuildSegment(InfallibleTArray& aSegments, diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index a040fe9d19..d7901c8457 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -746,7 +746,7 @@ static size_t SizeOfRuleHashTableEntry(PLDHashEntryHdr* aHdr, MallocSizeOf aMallocSizeOf, void *) { RuleHashTableEntry* entry = static_cast(aHdr); - return entry->mRules.SizeOfExcludingThis(aMallocSizeOf); + return entry->mRules.ShallowSizeOfExcludingThis(aMallocSizeOf); } size_t @@ -770,7 +770,7 @@ RuleHash::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const SizeOfRuleHashTableEntry, aMallocSizeOf); - n += mUniversalRules.SizeOfExcludingThis(aMallocSizeOf); + n += mUniversalRules.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } @@ -950,7 +950,7 @@ static size_t SizeOfSelectorsEntry(PLDHashEntryHdr* aHdr, MallocSizeOf aMallocSizeOf, void *) { AtomSelectorEntry* entry = static_cast(aHdr); - return entry->mSelectors.SizeOfExcludingThis(aMallocSizeOf); + return entry->mSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); } static size_t @@ -980,15 +980,15 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const n += mPseudoElementRuleHashes[i]->SizeOfIncludingThis(aMallocSizeOf); } - n += mStateSelectors.SizeOfExcludingThis(aMallocSizeOf); + n += mStateSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); n += PL_DHashTableSizeOfExcludingThis(&mIdSelectors, SizeOfSelectorsEntry, aMallocSizeOf); n += PL_DHashTableSizeOfExcludingThis(&mClassSelectors, SizeOfSelectorsEntry, aMallocSizeOf); - n += mPossiblyNegatedClassSelectors.SizeOfExcludingThis(aMallocSizeOf); - n += mPossiblyNegatedIDSelectors.SizeOfExcludingThis(aMallocSizeOf); + n += mPossiblyNegatedClassSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mPossiblyNegatedIDSelectors.ShallowSizeOfExcludingThis(aMallocSizeOf); n += PL_DHashTableSizeOfExcludingThis(&mAttributeSelectors, SizeOfSelectorsEntry, aMallocSizeOf); @@ -999,11 +999,11 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const SizeOfRuleHashTableEntry, aMallocSizeOf); #endif - n += mFontFaceRules.SizeOfExcludingThis(aMallocSizeOf); - n += mKeyframesRules.SizeOfExcludingThis(aMallocSizeOf); - n += mFontFeatureValuesRules.SizeOfExcludingThis(aMallocSizeOf); - n += mPageRules.SizeOfExcludingThis(aMallocSizeOf); - n += mCounterStyleRules.SizeOfExcludingThis(aMallocSizeOf); + n += mFontFaceRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mKeyframesRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mFontFeatureValuesRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mPageRules.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mCounterStyleRules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mKeyframesRuleTable.SizeOfExcludingThis(SizeOfKeyframesRuleEntryExcludingThis, aMallocSizeOf, nullptr); @@ -3015,7 +3015,7 @@ nsCSSRuleProcessor::CloneMQCacheKey() nsCSSRuleProcessor::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = 0; - n += mSheets.SizeOfExcludingThis(aMallocSizeOf); + n += mSheets.ShallowSizeOfExcludingThis(aMallocSizeOf); for (RuleCascadeData* cascade = mRuleCascades; cascade; cascade = cascade->mNext) { n += cascade->SizeOfIncludingThis(aMallocSizeOf); diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 61e25bb086..49fca13eb4 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -2558,7 +2558,7 @@ nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) con n += mAngle.SizeOfExcludingThis(aMallocSizeOf); n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf); n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf); - n += mStops.SizeOfExcludingThis(aMallocSizeOf); + n += mStops.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mStops.Length(); i++) { n += mStops[i].SizeOfExcludingThis(aMallocSizeOf); } @@ -2718,7 +2718,7 @@ nsCSSCornerSizes::corners[4] = { size_t mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - size_t n = mNamedAreas.SizeOfExcludingThis(aMallocSizeOf); - n += mTemplates.SizeOfExcludingThis(aMallocSizeOf); + size_t n = mNamedAreas.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mTemplates.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 46f0bf556f..8198aa0da4 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -226,10 +226,10 @@ nsStyleSet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const for (uint32_t i = 0; i < mScopedDocSheetRuleProcessors.Length(); i++) { n += mScopedDocSheetRuleProcessors[i]->SizeOfIncludingThis(aMallocSizeOf); } - n += mScopedDocSheetRuleProcessors.SizeOfExcludingThis(aMallocSizeOf); + n += mScopedDocSheetRuleProcessors.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += mRoots.SizeOfExcludingThis(aMallocSizeOf); - n += mOldRuleTrees.SizeOfExcludingThis(aMallocSizeOf); + n += mRoots.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mOldRuleTrees.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 32e748d491..a7cc463f88 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -22,6 +22,7 @@ #include "mozilla/EventDispatcher.h" #include "mozilla/ContentEvents.h" #include "mozilla/StyleAnimationValue.h" +#include "mozilla/dom/DocumentTimeline.h" #include "mozilla/dom/Element.h" #include "nsIFrame.h" #include "Layers.h" @@ -120,6 +121,61 @@ CSSTransition::GetAnimationManager() const return context->TransitionManager(); } +nsCSSProperty +CSSTransition::TransitionProperty() const +{ + // FIXME: Once we support replacing/removing the effect (bug 1049975) + // we'll need to store the original transition property so we keep + // returning the same value in that case. + dom::KeyframeEffectReadOnly* effect = GetEffect(); + MOZ_ASSERT(effect && effect->AsTransition(), + "Transition should have a transition effect"); + return effect->AsTransition()->TransitionProperty(); +} + +bool +CSSTransition::HasLowerCompositeOrderThan(const Animation& aOther) const +{ + // 0. Object-equality case + if (&aOther == this) { + return false; + } + + // 1. Transitions sort lowest + const CSSTransition* otherTransition = aOther.AsCSSTransition(); + if (!otherTransition) { + return true; + } + + // 2. CSS transitions that correspond to a transition-property property sort + // lower than CSS transitions owned by script. + if (!IsUsingCustomCompositeOrder()) { + return !aOther.IsUsingCustomCompositeOrder() ? + Animation::HasLowerCompositeOrderThan(aOther) : + false; + } + if (!aOther.IsUsingCustomCompositeOrder()) { + return true; + } + + // 3. Sort by document order + MOZ_ASSERT(mOwningElement.IsSet() && otherTransition->OwningElement().IsSet(), + "Transitions using custom composite order should have an owning " + "element"); + if (!mOwningElement.Equals(otherTransition->OwningElement())) { + return mOwningElement.LessThan(otherTransition->OwningElement()); + } + + // 4. (Same element and pseudo): Sort by transition generation + if (mSequenceNum != otherTransition->mSequenceNum) { + return mSequenceNum < otherTransition->mSequenceNum; + } + + // 5. (Same transition generation): Sort by transition property + return nsCSSProps::GetStringValue(TransitionProperty()) < + nsCSSProps::GetStringValue(otherTransition->TransitionProperty()); +} + /***************************************************************************** * nsTransitionManager * *****************************************************************************/ @@ -351,9 +407,9 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, currentValue != segment.mToValue) { // stop the transition if (!anim->GetEffect()->IsFinishedTransition()) { - anim->CancelFromStyle(); collection->UpdateAnimationGeneration(mPresContext); } + anim->CancelFromStyle(); animations.RemoveElementAt(i); } } while (i != 0); @@ -576,7 +632,12 @@ nsTransitionManager::ConsiderStartingTransition( segment.mToKey = 1; segment.mTimingFunction.Init(tf); - nsRefPtr animation = new CSSTransition(timeline); + nsRefPtr animation = + new CSSTransition(mPresContext->Document()->GetScopeObject(), timeline); + animation->SetOwningElement( + OwningElementRef(*aElement, aNewStyleContext->GetPseudoType())); + animation->SetCreationSequence( + mPresContext->RestyleManager()->GetAnimationGeneration()); // The order of the following two calls is important since PlayFromStyle // will add the animation to the PendingAnimationTracker of its effect's // document. When we come to make effect writeable (bug 1049975) we should @@ -662,6 +723,7 @@ nsTransitionManager::PruneCompletedTransitions(mozilla::dom::Element* aElement, if (!ExtractComputedValueForTransition(prop.mProperty, aNewStyleContext, currentValue) || currentValue != segment.mToValue) { + anim->CancelFromStyle(); animations.RemoveElementAt(i); } } while (i != 0); diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 9ca0a74cc3..9d2c315139 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -15,6 +15,7 @@ #include "AnimationCommon.h" #include "nsCSSPseudoElements.h" +class nsIGlobalObject; class nsStyleContext; class nsPresContext; class nsCSSPropertySet; @@ -38,8 +39,11 @@ struct ElementPropertyTransition : public dom::KeyframeEffectReadOnly : dom::KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType, aTiming) { } - virtual ElementPropertyTransition* AsTransition() override { return this; } - virtual const ElementPropertyTransition* AsTransition() const override { return this; } + ElementPropertyTransition* AsTransition() override { return this; } + const ElementPropertyTransition* AsTransition() const override + { + return this; + } nsCSSProperty TransitionProperty() const { MOZ_ASSERT(Properties().Length() == 1, @@ -76,15 +80,17 @@ namespace dom { class CSSTransition final : public Animation { public: - explicit CSSTransition(DocumentTimeline* aTimeline) - : Animation(aTimeline) + explicit CSSTransition(nsIGlobalObject* aGlobal, + dom::AnimationTimeline* aTimeline) + : dom::Animation(aGlobal, aTimeline) { } JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - virtual CSSTransition* AsCSSTransition() override { return this; } + CSSTransition* AsCSSTransition() override { return this; } + const CSSTransition* AsCSSTransition() const override { return this; } // CSSTransition interface void GetTransitionProperty(nsString& aRetVal) const; @@ -103,10 +109,65 @@ public: MOZ_ASSERT(!rv.Failed(), "Unexpected exception playing transition"); } + void CancelFromStyle() override + { + mOwningElement = OwningElementRef(); + Animation::CancelFromStyle(); + MOZ_ASSERT(mSequenceNum == kUnsequenced); + } + + nsCSSProperty TransitionProperty() const; + + bool HasLowerCompositeOrderThan(const Animation& aOther) const override; + bool IsUsingCustomCompositeOrder() const override + { + return mOwningElement.IsSet(); + } + + void SetCreationSequence(uint64_t aIndex) + { + MOZ_ASSERT(IsUsingCustomCompositeOrder()); + mSequenceNum = aIndex; + } + + // Returns the element or pseudo-element whose transition-property property + // this CSSTransition corresponds to (if any). This is used for determining + // the relative composite order of transitions generated from CSS markup. + // + // Typically this will be the same as the target element of the keyframe + // effect associated with this transition. However, it can differ in the + // following circumstances: + // + // a) If script removes or replaces the effect of this transition, + // b) If this transition is cancelled (e.g. by updating the + // transition-property or removing the owning element from the document), + // c) If this object is generated from script using the CSSTransition + // constructor. + // + // For (b) and (c) the returned owning element will return !IsSet(). + const OwningElementRef& OwningElement() const { return mOwningElement; } + + // Sets the owning element which is used for determining the composite + // oder of CSSTransition objects generated from CSS markup. + // + // @see OwningElement() + void SetOwningElement(const OwningElementRef& aElement) + { + mOwningElement = aElement; + } + protected: - virtual ~CSSTransition() { } + virtual ~CSSTransition() + { + MOZ_ASSERT(!mOwningElement.IsSet(), "Owning element should be cleared " + "before a CSS transition is destroyed"); + } virtual css::CommonAnimationManager* GetAnimationManager() const override; + + // The (pseudo-)element whose computed transition-property refers to this + // transition (if any). + OwningElementRef mOwningElement; }; } // namespace dom diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index a024527167..0ec4272311 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -223,7 +223,7 @@ SizeOfObserverEntryExcludingThis(ValueObserverHashKey* aKey, { size_t n = 0; n += aKey->mPrefName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); - n += aData->mClosures.SizeOfExcludingThis(aMallocSizeOf); + n += aData->mClosures.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } @@ -241,7 +241,7 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO n += PL_DHashTableSizeOfExcludingThis(gHashTable, nullptr, aMallocSizeOf); } if (gCacheData) { - n += gCacheData->SizeOfIncludingThis(aMallocSizeOf); + n += gCacheData->ShallowSizeOfIncludingThis(aMallocSizeOf); for (uint32_t i = 0, count = gCacheData->Length(); i < count; ++i) { n += aMallocSizeOf((*gCacheData)[i]); } diff --git a/netwerk/cache2/CacheEntry.cpp b/netwerk/cache2/CacheEntry.cpp index b349d8f689..4b94c5aa51 100644 --- a/netwerk/cache2/CacheEntry.cpp +++ b/netwerk/cache2/CacheEntry.cpp @@ -1639,7 +1639,7 @@ size_t CacheEntry::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const size_t n = 0; nsCOMPtr sizeOf; - n += mCallbacks.SizeOfExcludingThis(mallocSizeOf); + n += mCallbacks.ShallowSizeOfExcludingThis(mallocSizeOf); if (mFile) { n += mFile->SizeOfIncludingThis(mallocSizeOf); } diff --git a/netwerk/cache2/CacheFile.cpp b/netwerk/cache2/CacheFile.cpp index 753a838bde..805cc46266 100644 --- a/netwerk/cache2/CacheFile.cpp +++ b/netwerk/cache2/CacheFile.cpp @@ -1975,7 +1975,7 @@ CacheFile::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const } // Input streams are not elsewhere reported. - n += mInputs.SizeOfExcludingThis(mallocSizeOf); + n += mInputs.ShallowSizeOfExcludingThis(mallocSizeOf); for (uint32_t i = 0; i < mInputs.Length(); ++i) { n += mInputs[i]->SizeOfIncludingThis(mallocSizeOf); } @@ -1987,7 +1987,7 @@ CacheFile::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const // The listeners are usually classes reported just above. n += mChunkListeners.SizeOfExcludingThis(nullptr, mallocSizeOf); - n += mObjsToRelease.SizeOfExcludingThis(mallocSizeOf); + n += mObjsToRelease.ShallowSizeOfExcludingThis(mallocSizeOf); // mHandle reported directly from CacheFileIOManager. diff --git a/netwerk/cache2/CacheFileUtils.cpp b/netwerk/cache2/CacheFileUtils.cpp index a82f31b97d..dfe747aeda 100644 --- a/netwerk/cache2/CacheFileUtils.cpp +++ b/netwerk/cache2/CacheFileUtils.cpp @@ -415,7 +415,7 @@ ValidityMap::Clear() size_t ValidityMap::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mMap.SizeOfExcludingThis(mallocSizeOf); + return mMap.ShallowSizeOfExcludingThis(mallocSizeOf); } ValidityPair& diff --git a/netwerk/cache2/CacheIOThread.cpp b/netwerk/cache2/CacheIOThread.cpp index be238954a6..72ecbc0a50 100644 --- a/netwerk/cache2/CacheIOThread.cpp +++ b/netwerk/cache2/CacheIOThread.cpp @@ -335,7 +335,7 @@ size_t CacheIOThread::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) co size_t n = 0; n += mallocSizeOf(mThread); for (uint32_t level = 0; level < LAST_LEVEL; ++level) { - n += mEventQueue[level].SizeOfExcludingThis(mallocSizeOf); + n += mEventQueue[level].ShallowSizeOfExcludingThis(mallocSizeOf); // Events referenced by the queues are arbitrary objects we cannot be sure // are reported elsewhere as well as probably not implementing nsISizeOf // interface. Deliberatly omitting them from reporting here. diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index 7f886616d5..0ec1707006 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -36,8 +36,8 @@ namespace mozilla { namespace net { /** - * This helper class is responsible for keeping CacheIndex::mIndexStats, - * CacheIndex::mFrecencyArray and CacheIndex::mExpirationArray up to date. + * This helper class is responsible for keeping CacheIndex::mIndexStats and + * CacheIndex::mFrecencyArray up to date. */ class CacheIndexEntryAutoManage { @@ -46,7 +46,6 @@ public: : mIndex(aIndex) , mOldRecord(nullptr) , mOldFrecency(0) - , mOldExpirationTime(nsICacheEntry::NO_EXPIRATION_TIME) , mDoNotSearchInIndex(false) , mDoNotSearchInUpdates(false) { @@ -58,7 +57,6 @@ public: if (entry && entry->IsInitialized() && !entry->IsRemoved()) { mOldRecord = entry->mRec; mOldFrecency = entry->mRec->mFrecency; - mOldExpirationTime = entry->mRec->mExpirationTime; } } @@ -74,44 +72,30 @@ public: if (entry && !mOldRecord) { mIndex->InsertRecordToFrecencyArray(entry->mRec); - mIndex->InsertRecordToExpirationArray(entry->mRec); mIndex->AddRecordToIterators(entry->mRec); } else if (!entry && mOldRecord) { mIndex->RemoveRecordFromFrecencyArray(mOldRecord); - mIndex->RemoveRecordFromExpirationArray(mOldRecord); mIndex->RemoveRecordFromIterators(mOldRecord); } else if (entry && mOldRecord) { bool replaceFrecency = false; - bool replaceExpiration = false; if (entry->mRec != mOldRecord) { // record has a different address, we have to replace it - replaceFrecency = replaceExpiration = true; + replaceFrecency = true; mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec); - } else { - if (entry->mRec->mFrecency == 0 && - entry->mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME) { - // This is a special case when we want to make sure that the entry is - // placed at the end of the lists even when the values didn't change. - replaceFrecency = replaceExpiration = true; - } else { - if (entry->mRec->mFrecency != mOldFrecency) { - replaceFrecency = true; - } - if (entry->mRec->mExpirationTime != mOldExpirationTime) { - replaceExpiration = true; - } - } + } else if (entry->mRec->mFrecency == 0 && + entry->mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME) { + // This is a special case when we want to make sure that the entry is + // placed at the end of the lists even when the values didn't change. + replaceFrecency = true; + } else if (entry->mRec->mFrecency != mOldFrecency) { + replaceFrecency = true; } if (replaceFrecency) { mIndex->RemoveRecordFromFrecencyArray(mOldRecord); mIndex->InsertRecordToFrecencyArray(entry->mRec); } - if (replaceExpiration) { - mIndex->RemoveRecordFromExpirationArray(mOldRecord); - mIndex->InsertRecordToExpirationArray(entry->mRec); - } } else { // both entries were removed or not initialized, do nothing } @@ -156,7 +140,6 @@ private: nsRefPtr mIndex; CacheIndexRecord *mOldRecord; uint32_t mOldFrecency; - uint32_t mOldExpirationTime; bool mDoNotSearchInIndex; bool mDoNotSearchInUpdates; }; @@ -1093,7 +1076,6 @@ CacheIndex::RemoveAll() index->mIndexStats.Clear(); index->mFrecencyArray.Clear(); - index->mExpirationArray.Clear(); index->mIndex.Clear(); } @@ -1188,83 +1170,36 @@ CacheIndex::GetEntryForEviction(bool aIgnoreEmptyEntries, SHA1Sum::Hash *aHash, return NS_ERROR_NOT_AVAILABLE; } - MOZ_ASSERT(index->mFrecencyArray.Length() == - index->mExpirationArray.Length()); - - if (index->mExpirationArray.Length() == 0) - return NS_ERROR_NOT_AVAILABLE; - SHA1Sum::Hash hash; bool foundEntry = false; - uint32_t i = 0, j = 0; - uint32_t now = PR_Now() / PR_USEC_PER_SEC; + uint32_t i; - // find the first expired, non-forced valid entry - for (i = 0; i < index->mExpirationArray.Length(); i++) { - if (index->mExpirationArray[i]->mExpirationTime < now) { - memcpy(&hash, &index->mExpirationArray[i]->mHash, sizeof(SHA1Sum::Hash)); + // find first non-forced valid entry with the lowest frecency + for (i = 0; i < index->mFrecencyArray.Length(); ++i) { + memcpy(&hash, &index->mFrecencyArray[i]->mHash, sizeof(SHA1Sum::Hash)); - if (IsForcedValidEntry(&hash)) { - continue; - } - - if (aIgnoreEmptyEntries && - !CacheIndexEntry::GetFileSize(index->mExpirationArray[i])) { - continue; - } - - foundEntry = true; - break; - } else { - // all further entries have not expired yet - break; - } - } - - if (foundEntry) { - *aCnt = index->mExpirationArray.Length() - i; - - LOG(("CacheIndex::GetEntryForEviction() - returning entry from expiration " - "array [hash=%08x%08x%08x%08x%08x, cnt=%u, expTime=%u, now=%u, " - "frecency=%u]", LOGSHA1(&hash), *aCnt, - index->mExpirationArray[i]->mExpirationTime, now, - index->mExpirationArray[i]->mFrecency)); - } - else { - // check if we've already tried all the entries - if (i == index->mExpirationArray.Length()) - return NS_ERROR_NOT_AVAILABLE; - - // find first non-forced valid entry with the lowest frecency - for (j = 0; j < index->mFrecencyArray.Length(); j++) { - memcpy(&hash, &index->mFrecencyArray[j]->mHash, sizeof(SHA1Sum::Hash)); - - if (IsForcedValidEntry(&hash)) { - continue; - } - - if (aIgnoreEmptyEntries && - !CacheIndexEntry::GetFileSize(index->mFrecencyArray[j])) { - continue; - } - - foundEntry = true; - break; + if (IsForcedValidEntry(&hash)) { + continue; } - if (!foundEntry) - return NS_ERROR_NOT_AVAILABLE; + if (aIgnoreEmptyEntries && + !CacheIndexEntry::GetFileSize(index->mFrecencyArray[i])) { + continue; + } - // forced valid entries skipped in both arrays could overlap, just use max - *aCnt = index->mFrecencyArray.Length() - std::max(i, j); - - LOG(("CacheIndex::GetEntryForEviction() - returning entry from frecency " - "array [hash=%08x%08x%08x%08x%08x, cnt=%u, expTime=%u, now=%u, " - "frecency=%u]", LOGSHA1(&hash), *aCnt, - index->mFrecencyArray[j]->mExpirationTime, now, - index->mFrecencyArray[j]->mFrecency)); + foundEntry = true; + break; } + if (!foundEntry) + return NS_ERROR_NOT_AVAILABLE; + + *aCnt = index->mFrecencyArray.Length() - i; + + LOG(("CacheIndex::GetEntryForEviction() - returning entry from frecency " + "array [hash=%08x%08x%08x%08x%08x, cnt=%u, frecency=%u]", + LOGSHA1(&hash), *aCnt, index->mFrecencyArray[i]->mFrecency)); + memcpy(aHash, &hash, sizeof(SHA1Sum::Hash)); return NS_OK; @@ -3240,17 +3175,6 @@ public: } }; -class ExpirationComparator -{ -public: - bool Equals(CacheIndexRecord* a, CacheIndexRecord* b) const { - return a->mExpirationTime == b->mExpirationTime; - } - bool LessThan(CacheIndexRecord* a, CacheIndexRecord* b) const { - return a->mExpirationTime < b->mExpirationTime; - } -}; - } // namespace void @@ -3263,16 +3187,6 @@ CacheIndex::InsertRecordToFrecencyArray(CacheIndexRecord *aRecord) mFrecencyArray.InsertElementSorted(aRecord, FrecencyComparator()); } -void -CacheIndex::InsertRecordToExpirationArray(CacheIndexRecord *aRecord) -{ - LOG(("CacheIndex::InsertRecordToExpirationArray() [record=%p, hash=%08x%08x" - "%08x%08x%08x]", aRecord, LOGSHA1(aRecord->mHash))); - - MOZ_ASSERT(!mExpirationArray.Contains(aRecord)); - mExpirationArray.InsertElementSorted(aRecord, ExpirationComparator()); -} - void CacheIndex::RemoveRecordFromFrecencyArray(CacheIndexRecord *aRecord) { @@ -3283,16 +3197,6 @@ CacheIndex::RemoveRecordFromFrecencyArray(CacheIndexRecord *aRecord) MOZ_ASSERT(removed); } -void -CacheIndex::RemoveRecordFromExpirationArray(CacheIndexRecord *aRecord) -{ - LOG(("CacheIndex::RemoveRecordFromExpirationArray() [record=%p]", aRecord)); - - DebugOnly removed; - removed = mExpirationArray.RemoveElement(aRecord); - MOZ_ASSERT(removed); -} - void CacheIndex::AddRecordToIterators(CacheIndexRecord *aRecord) { @@ -3665,11 +3569,9 @@ CacheIndex::SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) cons n += mPendingUpdates.SizeOfExcludingThis(mallocSizeOf); n += mTmpJournal.SizeOfExcludingThis(mallocSizeOf); - // mFrecencyArray and mExpirationArray items are reported by - // mIndex/mPendingUpdates - n += mFrecencyArray.SizeOfExcludingThis(mallocSizeOf); - n += mExpirationArray.SizeOfExcludingThis(mallocSizeOf); - n += mDiskConsumptionObservers.SizeOfExcludingThis(mallocSizeOf); + // mFrecencyArray items are reported by mIndex/mPendingUpdates + n += mFrecencyArray.ShallowSizeOfExcludingThis(mallocSizeOf); + n += mDiskConsumptionObservers.ShallowSizeOfExcludingThis(mallocSizeOf); return n; } diff --git a/netwerk/cache2/CacheIndex.h b/netwerk/cache2/CacheIndex.h index c372768a2a..cf586c2215 100644 --- a/netwerk/cache2/CacheIndex.h +++ b/netwerk/cache2/CacheIndex.h @@ -912,9 +912,7 @@ private: // Methods used by CacheIndexEntryAutoManage to keep the arrays up to date. void InsertRecordToFrecencyArray(CacheIndexRecord *aRecord); - void InsertRecordToExpirationArray(CacheIndexRecord *aRecord); void RemoveRecordFromFrecencyArray(CacheIndexRecord *aRecord); - void RemoveRecordFromExpirationArray(CacheIndexRecord *aRecord); // Methods used by CacheIndexEntryAutoManage to keep the iterators up to date. void AddRecordToIterators(CacheIndexRecord *aRecord); @@ -1016,14 +1014,11 @@ private: // of the journal fails or the hash does not match. nsTHashtable mTmpJournal; - // Arrays that keep entry records ordered by eviction preference. When looking - // for an entry to evict, we first try to find an expired entry. If there is - // no expired entry, we take the entry with lowest valid frecency. Zero - // frecency is an initial value and such entries are stored at the end of the - // array. Uninitialized entries and entries marked as deleted are not present - // in these arrays. + // An array that keeps entry records ordered by eviction preference; we take + // the entry with lowest valid frecency. Zero frecency is an initial value + // and such entries are stored at the end of the array. Uninitialized entries + // and entries marked as deleted are not present in this array. nsTArray mFrecencyArray; - nsTArray mExpirationArray; nsTArray mIterators; diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp index d5811d92bd..a3b2c9d0b1 100644 --- a/netwerk/cache2/CacheStorageService.cpp +++ b/netwerk/cache2/CacheStorageService.cpp @@ -1859,10 +1859,10 @@ CacheStorageService::SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) con size_t n = 0; // The elemets are referenced by sGlobalEntryTables and are reported from there - n += Pool(true).mFrecencyArray.SizeOfExcludingThis(mallocSizeOf); - n += Pool(true).mExpirationArray.SizeOfExcludingThis(mallocSizeOf); - n += Pool(false).mFrecencyArray.SizeOfExcludingThis(mallocSizeOf); - n += Pool(false).mExpirationArray.SizeOfExcludingThis(mallocSizeOf); + n += Pool(true).mFrecencyArray.ShallowSizeOfExcludingThis(mallocSizeOf); + n += Pool(true).mExpirationArray.ShallowSizeOfExcludingThis(mallocSizeOf); + n += Pool(false).mFrecencyArray.ShallowSizeOfExcludingThis(mallocSizeOf); + n += Pool(false).mExpirationArray.ShallowSizeOfExcludingThis(mallocSizeOf); // Entries reported manually in CacheStorageService::CollectReports callback if (sGlobalEntryTables) { n += sGlobalEntryTables->SizeOfIncludingThis(nullptr, mallocSizeOf); diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index e6731686a2..afa3de6d81 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -601,7 +601,7 @@ nsCookieEntry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { size_t amount = nsCookieKey::SizeOfExcludingThis(aMallocSizeOf); - amount += mCookies.SizeOfExcludingThis(aMallocSizeOf); + amount += mCookies.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < mCookies.Length(); ++i) { amount += mCookies[i]->SizeOfIncludingThis(aMallocSizeOf); } @@ -627,7 +627,7 @@ DBState::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const amount += aMallocSizeOf(this); amount += hostTable.SizeOfExcludingThis(aMallocSizeOf); - amount += hostArray.SizeOfExcludingThis(aMallocSizeOf); + amount += hostArray.ShallowSizeOfExcludingThis(aMallocSizeOf); for (uint32_t i = 0; i < hostArray.Length(); ++i) { amount += hostArray[i].SizeOfExcludingThis(aMallocSizeOf); } diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index df64bfbad6..d173408787 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -345,7 +345,7 @@ nsHostRecord::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const n += addr_info ? addr_info->SizeOfIncludingThis(mallocSizeOf) : 0; n += mallocSizeOf(addr); - n += mBlacklistedItems.SizeOfExcludingThis(mallocSizeOf); + n += mBlacklistedItems.ShallowSizeOfExcludingThis(mallocSizeOf); for (size_t i = 0; i < mBlacklistedItems.Length(); i++) { n += mBlacklistedItems[i].SizeOfExcludingThisMustBeUnshared(mallocSizeOf); } diff --git a/startupcache/StartupCache.cpp b/startupcache/StartupCache.cpp index f2bc6fb27b..779561e6fc 100644 --- a/startupcache/StartupCache.cpp +++ b/startupcache/StartupCache.cpp @@ -383,7 +383,7 @@ StartupCache::HeapSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) // DMD to be significant. They can be added later if necessary. return aMallocSizeOf(this) + mTable.SizeOfExcludingThis(SizeOfEntryExcludingThis, aMallocSizeOf) + - mPendingWrites.SizeOfExcludingThis(aMallocSizeOf); + mPendingWrites.ShallowSizeOfExcludingThis(aMallocSizeOf); } /* static */ size_t diff --git a/toolkit/components/places/History.h b/toolkit/components/places/History.h index 4051792a64..cfd1529a06 100644 --- a/toolkit/components/places/History.h +++ b/toolkit/components/places/History.h @@ -181,7 +181,7 @@ private: } size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return array.SizeOfExcludingThis(aMallocSizeOf); + return array.ShallowSizeOfExcludingThis(aMallocSizeOf); } ObserverArray array; }; diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index 4c5f20ca17..879fa03876 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -414,7 +414,7 @@ public: size_t size; size = mFileStats.SizeOfExcludingThis(SizeOfFileIOEntryTypeExcludingThis, aMallocSizeOf) + - mSafeDirs.SizeOfExcludingThis(aMallocSizeOf); + mSafeDirs.ShallowSizeOfExcludingThis(aMallocSizeOf); uint32_t safeDirsLen = mSafeDirs.Length(); for (uint32_t i = 0; i < safeDirsLen; ++i) { size += mSafeDirs[i].SizeOfExcludingThis(aMallocSizeOf); diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 52b9e23162..4fb4e155a8 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -877,7 +877,7 @@ public: // We don't measure what the WeakMappings point to, because the // pointers are non-owning. - *aWeakMapsSize = mWeakMaps.SizeOfExcludingThis(aMallocSizeOf); + *aWeakMapsSize = mWeakMaps.ShallowSizeOfExcludingThis(aMallocSizeOf); } }; diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index e73802e408..cba2e3135a 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -1852,15 +1852,15 @@ nsComponentManagerImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) n += mContractIDs.SizeOfExcludingThis(SizeOfContractIDsEntryExcludingThis, aMallocSizeOf); - n += sStaticModules->SizeOfIncludingThis(aMallocSizeOf); - n += sModuleLocations->SizeOfIncludingThis(aMallocSizeOf); + n += sStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf); + n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf); - n += mKnownStaticModules.SizeOfExcludingThis(aMallocSizeOf); + n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mKnownModules.SizeOfExcludingThis(nullptr, aMallocSizeOf); n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf); - n += mPendingServices.SizeOfExcludingThis(aMallocSizeOf); + n += mPendingServices.ShallowSizeOfExcludingThis(aMallocSizeOf); // Measurement of the following members may be added later if DMD finds it is // worthwhile: diff --git a/xpcom/glue/DeadlockDetector.h b/xpcom/glue/DeadlockDetector.h index d560e9c6d9..93855ac4f0 100644 --- a/xpcom/glue/DeadlockDetector.h +++ b/xpcom/glue/DeadlockDetector.h @@ -97,8 +97,8 @@ private: SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { size_t n = aMallocSizeOf(this); - n += mOrderedLT.SizeOfExcludingThis(aMallocSizeOf); - n += mExternalRefs.SizeOfExcludingThis(aMallocSizeOf); + n += mOrderedLT.ShallowSizeOfExcludingThis(aMallocSizeOf); + n += mExternalRefs.ShallowSizeOfExcludingThis(aMallocSizeOf); return n; } diff --git a/xpcom/glue/nsCOMArray.cpp b/xpcom/glue/nsCOMArray.cpp index 570e7a3813..c259176392 100644 --- a/xpcom/glue/nsCOMArray.cpp +++ b/xpcom/glue/nsCOMArray.cpp @@ -297,7 +297,7 @@ nsCOMArray_base::SizeOfExcludingThis( nsBaseArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, mozilla::MallocSizeOf aMallocSizeOf, void* aData) const { - size_t n = mArray.SizeOfExcludingThis(aMallocSizeOf); + size_t n = mArray.ShallowSizeOfExcludingThis(aMallocSizeOf); if (aSizeOfElementIncludingThis) { for (uint32_t index = 0; index < mArray.Length(); ++index) { diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index 5881976588..ec1c55d924 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -955,8 +955,10 @@ public: } // @return The amount of memory used by this nsTArray_Impl, excluding - // sizeof(*this). - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + // sizeof(*this). If you want to measure anything hanging off the array, you + // must iterate over the elements and measure them individually; hence the + // "Shallow" prefix. + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { if (this->UsesAutoArrayBuffer() || Hdr() == EmptyHdr()) { return 0; @@ -965,10 +967,12 @@ public: } // @return The amount of memory used by this nsTArray_Impl, including - // sizeof(*this). - size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + // sizeof(*this). If you want to measure anything hanging off the array, you + // must iterate over the elements and measure them individually; hence the + // "Shallow" prefix. + size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); + return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf); } // diff --git a/xpcom/glue/nsTObserverArray.h b/xpcom/glue/nsTObserverArray.h index 43eb590670..7036a7c35e 100644 --- a/xpcom/glue/nsTObserverArray.h +++ b/xpcom/glue/nsTObserverArray.h @@ -261,10 +261,12 @@ public: void Compact() { mArray.Compact(); } // Returns the number of bytes on the heap taken up by this object, not - // including sizeof(*this). - size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + // including sizeof(*this). If you want to measure anything hanging off the + // array, you must iterate over the elements and measure them individually; + // hence the "Shallow" prefix. + size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { - return mArray.SizeOfExcludingThis(aMallocSizeOf); + return mArray.ShallowSizeOfExcludingThis(aMallocSizeOf); } //