From 82dc9b22718610e5a36e0a668ca132399d4b1ab2 Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Wed, 10 Jun 2020 10:46:14 +0000 Subject: [PATCH] Bug 1642949 - Replace uses of RemoveElementAt by RemoveLastElement/PopLastElement where possible. r=necko-reviewers,froydnj Differential Revision: https://phabricator.services.mozilla.com/D78027 --- dom/base/CustomElementRegistry.cpp | 8 +++++-- dom/base/ResponsiveImageSelector.cpp | 2 +- dom/base/nsDOMMutationObserver.cpp | 7 +++--- dom/base/nsPlainTextSerializer.cpp | 8 +------ dom/base/nsXMLContentSerializer.cpp | 2 +- dom/cache/AutoUtils.cpp | 3 +-- dom/console/Console.cpp | 6 ++--- dom/events/EventDispatcher.cpp | 5 ++--- dom/html/TextControlState.cpp | 3 +-- dom/html/nsHTMLContentSink.cpp | 19 +++++----------- dom/indexedDB/ActorsParent.cpp | 7 ++---- dom/media/webaudio/AudioNode.cpp | 14 ++++-------- dom/media/webaudio/AudioNode.h | 4 ++++ dom/media/webaudio/AudioParam.cpp | 4 +--- dom/plugins/base/nsNPAPIPluginInstance.cpp | 10 ++------- dom/plugins/ipc/PluginModuleChild.cpp | 7 +++--- dom/webbrowserpersist/nsWebBrowserPersist.cpp | 4 +--- dom/workers/Queue.h | 4 +--- dom/workers/RuntimeService.cpp | 2 +- dom/xml/nsXMLContentSink.cpp | 6 ++--- dom/xslt/base/txStack.h | 4 +--- dom/xslt/xslt/txExecutionState.cpp | 7 +----- dom/xslt/xslt/txStylesheetCompiler.cpp | 6 ++--- editor/libeditor/TypeInState.cpp | 22 +++++-------------- gfx/layers/ImageContainer.cpp | 5 +---- gfx/layers/LayerSorter.cpp | 5 +---- gfx/layers/wr/IpcResourceUpdateQueue.cpp | 6 ++--- layout/base/PresShell.cpp | 3 +-- layout/base/nsBidiPresUtils.cpp | 2 +- layout/base/nsPresArena.cpp | 6 ++--- layout/style/ServoStyleSet.cpp | 5 +---- layout/svg/SVGTextFrame.cpp | 4 ++-- layout/tables/nsTableFrame.cpp | 2 +- netwerk/cache2/CacheIndexIterator.cpp | 3 +-- netwerk/protocol/http/nsHttpChannel.cpp | 4 ++-- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 2 +- .../components/commandlines/nsCommandLine.cpp | 4 +--- .../ApplicationReputation.cpp | 18 +++++---------- .../nsUrlClassifierPrefixSet.cpp | 2 +- widget/cocoa/nsCocoaUtils.mm | 3 +-- widget/gtk/WindowSurfaceWayland.cpp | 11 ++++------ xpcom/base/nsMemoryReporterManager.cpp | 5 ++--- xpcom/ds/nsExpirationTracker.h | 11 +++++----- xpcom/ds/nsTPriorityQueue.h | 10 ++++++--- 44 files changed, 99 insertions(+), 176 deletions(-) diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 1e112d2047ed..02c18e339f18 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -241,19 +241,23 @@ class MOZ_RAII AutoConstructionStackEntry final { : mStack(aStack) { MOZ_ASSERT(aElement->IsHTMLElement() || aElement->IsXULElement()); +#ifdef DEBUG mIndex = mStack.Length(); +#endif mStack.AppendElement(aElement); } ~AutoConstructionStackEntry() { MOZ_ASSERT(mIndex == mStack.Length() - 1, "Removed element should be the last element"); - mStack.RemoveElementAt(mIndex); + mStack.RemoveLastElement(); } private: nsTArray>& mStack; +#ifdef DEBUG uint32_t mIndex; +#endif }; } // namespace @@ -1295,7 +1299,7 @@ void CustomElementReactionsStack::PopAndInvokeElementQueue() { lastIndex == mReactionsStack.Length() - 1, "reactions created by InvokeReactions() should be consumed and removed"); - mReactionsStack.RemoveElementAt(lastIndex); + mReactionsStack.RemoveLastElement(); mIsElementQueuePushedForCurrentRecursionDepth = false; } diff --git a/dom/base/ResponsiveImageSelector.cpp b/dom/base/ResponsiveImageSelector.cpp index 9536054c5c35..c991c606df48 100644 --- a/dom/base/ResponsiveImageSelector.cpp +++ b/dom/base/ResponsiveImageSelector.cpp @@ -204,7 +204,7 @@ void ResponsiveImageSelector::SetDefaultSource(const nsAString& aURLString, int32_t candidates = mCandidates.Length(); if (candidates && (mCandidates[candidates - 1].Type() == ResponsiveImageCandidate::eCandidateType_Default)) { - mCandidates.RemoveElementAt(candidates - 1); + mCandidates.RemoveLastElement(); } mDefaultSourceURL = aURLString; diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 52a935282ed0..04b9f8c7d911 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -911,16 +911,15 @@ void nsDOMMutationObserver::EnterMutationHandling() { ++sMutationLevel; } void nsDOMMutationObserver::LeaveMutationHandling() { if (sCurrentlyHandlingObservers && sCurrentlyHandlingObservers->Length() == sMutationLevel) { - nsTArray>& obs = - sCurrentlyHandlingObservers->ElementAt(sMutationLevel - 1); + nsTArray> obs = + sCurrentlyHandlingObservers->PopLastElement(); for (uint32_t i = 0; i < obs.Length(); ++i) { nsDOMMutationObserver* o = static_cast(obs[i]); if (o->mCurrentMutations.Length() == sMutationLevel) { // It is already in pending mutations. - o->mCurrentMutations.RemoveElementAt(sMutationLevel - 1); + o->mCurrentMutations.RemoveLastElement(); } } - sCurrentlyHandlingObservers->RemoveElementAt(sMutationLevel - 1); } --sMutationLevel; } diff --git a/dom/base/nsPlainTextSerializer.cpp b/dom/base/nsPlainTextSerializer.cpp index 11fb69728d01..7751846f1930 100644 --- a/dom/base/nsPlainTextSerializer.cpp +++ b/dom/base/nsPlainTextSerializer.cpp @@ -383,13 +383,7 @@ void nsPlainTextSerializer::PushBool(nsTArray& aStack, bool aValue) { } bool nsPlainTextSerializer::PopBool(nsTArray& aStack) { - bool returnValue = false; - uint32_t size = aStack.Length(); - if (size > 0) { - returnValue = aStack.ElementAt(size - 1); - aStack.RemoveElementAt(size - 1); - } - return returnValue; + return aStack.Length() ? aStack.PopLastElement() : false; } bool nsPlainTextSerializer::IsIgnorableRubyAnnotation( diff --git a/dom/base/nsXMLContentSerializer.cpp b/dom/base/nsXMLContentSerializer.cpp index e4f0839cbdd9..6d79fcc66d60 100644 --- a/dom/base/nsXMLContentSerializer.cpp +++ b/dom/base/nsXMLContentSerializer.cpp @@ -432,7 +432,7 @@ void nsXMLContentSerializer::PopNameSpaceDeclsFor(nsIContent* aOwner) { if (mNameSpaceStack[index].mOwner != aOwner) { break; } - mNameSpaceStack.RemoveElementAt(index); + mNameSpaceStack.RemoveLastElement(); } } diff --git a/dom/cache/AutoUtils.cpp b/dom/cache/AutoUtils.cpp index e4d54af4051f..8d55f30420fe 100644 --- a/dom/cache/AutoUtils.cpp +++ b/dom/cache/AutoUtils.cpp @@ -306,8 +306,7 @@ void AutoChildOpArgs::Add(JSContext* aCx, const InternalRequest& aRequest, if (aRv.Failed()) { CleanupChild(pair.request().body(), Delete); - args.requestResponseList().RemoveElementAt( - args.requestResponseList().Length() - 1); + args.requestResponseList().RemoveLastElement(); } break; diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp index a2edd7f8f694..32250522b27c 100644 --- a/dom/console/Console.cpp +++ b/dom/console/Console.cpp @@ -1935,7 +1935,7 @@ static bool ProcessArguments(JSContext* aCx, const Sequence& aData, // If there isn't any output but there's already a style, then // discard the previous style and use the next one instead. if (output.IsEmpty() && !aStyles.IsEmpty()) { - aStyles.TruncateLength(aStyles.Length() - 1); + aStyles.RemoveLastElement(); } if (NS_WARN_IF(!FlushOutput(aCx, aSequence, output))) { @@ -2084,9 +2084,7 @@ static bool UnstoreGroupName(nsAString& aName, return false; } - uint32_t pos = aGroupStack->Length() - 1; - aName = (*aGroupStack)[pos]; - aGroupStack->RemoveElementAt(pos); + aName = aGroupStack->PopLastElement(); return true; } diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index c25bff12310d..6a2c59135e3d 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -149,9 +149,8 @@ class EventTargetChainItem { static void DestroyLast(nsTArray& aChain, EventTargetChainItem* aItem) { - uint32_t lastIndex = aChain.Length() - 1; - MOZ_ASSERT(&aChain[lastIndex] == aItem); - aChain.RemoveElementAt(lastIndex); + MOZ_ASSERT(&aChain.LastElement() == aItem); + aChain.RemoveLastElement(); } static EventTargetChainItem* GetFirstCanHandleEventTarget( diff --git a/dom/html/TextControlState.cpp b/dom/html/TextControlState.cpp index 216e545cf3d2..8b564e54cb76 100644 --- a/dom/html/TextControlState.cpp +++ b/dom/html/TextControlState.cpp @@ -1389,8 +1389,7 @@ TextControlState::TextControlState(TextControlElement* aOwningElement) TextControlState* TextControlState::Construct( TextControlElement* aOwningElement) { if (sReleasedInstances && !sReleasedInstances->IsEmpty()) { - TextControlState* state = sReleasedInstances->LastElement(); - sReleasedInstances->RemoveLastElement(); + TextControlState* state = sReleasedInstances->PopLastElement(); state->mTextCtrlElement = aOwningElement; state->mBoundFrame = nullptr; state->mSelectionProperties = SelectionProperties(); diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index 5eb852fd472f..8696f1038961 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -551,15 +551,13 @@ HTMLContentSink::~HTMLContentSink() { mNotificationTimer->Cancel(); } - int32_t numContexts = mContextStack.Length(); - - if (mCurrentContext == mHeadContext && numContexts > 0) { + if (mCurrentContext == mHeadContext && !mContextStack.IsEmpty()) { // Pop off the second html context if it's not done earlier - mContextStack.RemoveElementAt(--numContexts); + mContextStack.RemoveLastElement(); } - int32_t i; - for (i = 0; i < numContexts; i++) { + for (int32_t i = 0, numContexts = mContextStack.Length(); i < numContexts; + i++) { SinkContext* sc = mContextStack.ElementAt(i); if (sc) { sc->End(); @@ -716,11 +714,8 @@ HTMLContentSink::SetParser(nsParserBase* aParser) { nsresult HTMLContentSink::CloseHTML() { if (mHeadContext) { if (mCurrentContext == mHeadContext) { - uint32_t numContexts = mContextStack.Length(); - // Pop off the second html context if it's not done earlier - mCurrentContext = mContextStack.ElementAt(--numContexts); - mContextStack.RemoveElementAt(numContexts); + mCurrentContext = mContextStack.PopLastElement(); } mHeadContext->End(); @@ -842,9 +837,7 @@ void HTMLContentSink::CloseHeadContext() { } if (!mContextStack.IsEmpty()) { - uint32_t n = mContextStack.Length() - 1; - mCurrentContext = mContextStack.ElementAt(n); - mContextStack.RemoveElementAt(n); + mCurrentContext = mContextStack.PopLastElement(); } } diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 2a14e2bec3a4..c5b3a43527d1 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -12496,11 +12496,8 @@ bool ConnectionPool::ScheduleTransaction(TransactionInfo* aTransactionInfo, return false; } } else { - const uint32_t lastIndex = mIdleThreads.Length() - 1; - - dbInfo->mThreadInfo = std::move(mIdleThreads[lastIndex].mThreadInfo); - - mIdleThreads.RemoveElementAt(lastIndex); + dbInfo->mThreadInfo = + std::move(mIdleThreads.PopLastElement().mThreadInfo); AdjustIdleTimer(); } diff --git a/dom/media/webaudio/AudioNode.cpp b/dom/media/webaudio/AudioNode.cpp index 7214523d236f..4bc48b5df5cf 100644 --- a/dom/media/webaudio/AudioNode.cpp +++ b/dom/media/webaudio/AudioNode.cpp @@ -161,16 +161,12 @@ void AudioNode::DisconnectFromGraph() { // Disconnect inputs. We don't need them anymore. while (!mInputNodes.IsEmpty()) { - size_t i = mInputNodes.Length() - 1; - RefPtr input = mInputNodes[i].mInputNode; - mInputNodes.RemoveElementAt(i); - input->mOutputNodes.RemoveElement(this); + InputNode inputNode = mInputNodes.PopLastElement(); + inputNode.mInputNode->mOutputNodes.RemoveElement(this); } while (!mOutputNodes.IsEmpty()) { - size_t i = mOutputNodes.Length() - 1; - RefPtr output = std::move(mOutputNodes[i]); - mOutputNodes.RemoveElementAt(i); + RefPtr output = mOutputNodes.PopLastElement(); size_t inputIndex = FindIndexOfNode(output->mInputNodes, this); // It doesn't matter which one we remove, since we're going to remove all // entries for this node anyway. @@ -180,9 +176,7 @@ void AudioNode::DisconnectFromGraph() { } while (!mOutputParams.IsEmpty()) { - size_t i = mOutputParams.Length() - 1; - RefPtr output = std::move(mOutputParams[i]); - mOutputParams.RemoveElementAt(i); + RefPtr output = mOutputParams.PopLastElement(); size_t inputIndex = FindIndexOfNode(output->InputNodes(), this); // It doesn't matter which one we remove, since we're going to remove all // entries for this node anyway. diff --git a/dom/media/webaudio/AudioNode.h b/dom/media/webaudio/AudioNode.h index 3cb05ba522c6..deceff805362 100644 --- a/dom/media/webaudio/AudioNode.h +++ b/dom/media/webaudio/AudioNode.h @@ -143,6 +143,10 @@ class AudioNode : public DOMEventTargetHelper, public nsSupportsWeakReference { } struct InputNode final { + InputNode() = default; + InputNode(const InputNode&) = delete; + InputNode(InputNode&&) = default; + ~InputNode() { if (mTrackPort) { mTrackPort->Destroy(); diff --git a/dom/media/webaudio/AudioParam.cpp b/dom/media/webaudio/AudioParam.cpp index 69d1d3aea67e..54b3b8c8a003 100644 --- a/dom/media/webaudio/AudioParam.cpp +++ b/dom/media/webaudio/AudioParam.cpp @@ -55,9 +55,7 @@ void AudioParam::DisconnectFromGraphAndDestroyTrack() { "mRefCnt.stabilizeForDeletion()"); while (!mInputNodes.IsEmpty()) { - uint32_t i = mInputNodes.Length() - 1; - RefPtr input = mInputNodes[i].mInputNode; - mInputNodes.RemoveElementAt(i); + RefPtr input = mInputNodes.PopLastElement().mInputNode; input->RemoveOutputParam(this); } diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 530f070a8484..5f1e9baddd07 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -781,9 +781,7 @@ nsresult nsNPAPIPluginInstance::PushPopupsEnabledState(bool aEnabled) { } nsresult nsNPAPIPluginInstance::PopPopupsEnabledState() { - int32_t last = mPopupStates.Length() - 1; - - if (last < 0) { + if (mPopupStates.IsEmpty()) { // Nothing to pop. return NS_OK; } @@ -791,11 +789,7 @@ nsresult nsNPAPIPluginInstance::PopPopupsEnabledState() { nsCOMPtr window = GetDOMWindow(); if (!window) return NS_ERROR_FAILURE; - PopupBlocker::PopupControlState& oldState = mPopupStates[last]; - - PopupBlocker::PopPopupControlState(oldState); - - mPopupStates.RemoveElementAt(last); + PopupBlocker::PopPopupControlState(mPopupStates.PopLastElement()); return NS_OK; } diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 58111414173e..a0db99791038 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -1818,13 +1818,14 @@ void PluginModuleChild::EnteredCall() { mIncallPumpingStack.AppendElement(); } void PluginModuleChild::ExitedCall() { NS_ASSERTION(mIncallPumpingStack.Length(), "mismatched entered/exited"); - uint32_t len = mIncallPumpingStack.Length(); - const IncallFrame& f = mIncallPumpingStack[len - 1]; + const IncallFrame& f = mIncallPumpingStack.LastElement(); if (f._spinning) MessageLoop::current()->SetNestableTasksAllowed( f._savedNestableTasksAllowed); - mIncallPumpingStack.TruncateLength(len - 1); + // XXX Is RemoveLastElement intentionally called only after calling + // SetNestableTasksAllowed? Otherwise, PopLastElement could be used above. + mIncallPumpingStack.RemoveLastElement(); } LRESULT CALLBACK PluginModuleChild::CallWindowProcHook(int nCode, WPARAM wParam, diff --git a/dom/webbrowserpersist/nsWebBrowserPersist.cpp b/dom/webbrowserpersist/nsWebBrowserPersist.cpp index 259415767608..1613095bf27e 100644 --- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp +++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp @@ -1696,9 +1696,7 @@ void nsWebBrowserPersist::FinishSaveDocumentInternal(nsIURI* aFile, } if (mWalkStack.Length() > 0) { - mozilla::UniquePtr toWalk; - mWalkStack.LastElement().swap(toWalk); - mWalkStack.TruncateLength(mWalkStack.Length() - 1); + mozilla::UniquePtr toWalk = mWalkStack.PopLastElement(); // Bounce this off the event loop to avoid stack overflow. typedef StoreCopyPassByRRef WalkStorage; auto saveMethod = &nsWebBrowserPersist::SaveDocumentDeferred; diff --git a/dom/workers/Queue.h b/dom/workers/Queue.h index 7b39eb9be1db..c2ab6aa28a8b 100644 --- a/dom/workers/Queue.h +++ b/dom/workers/Queue.h @@ -49,9 +49,7 @@ struct StorageWithTArray { return false; } - uint32_t index = aStorage.Length() - 1; - aEntry = aStorage.ElementAt(index); - aStorage.RemoveElementAt(index); + aEntry = aStorage.PopLastElement(); return true; } diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index b6ff321e0719..ae60068da62f 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -1358,7 +1358,7 @@ bool RuntimeService::ScheduleWorker(WorkerPrivate& aWorkerPrivate) { { MutexAutoLock lock(mMutex); if (!mIdleThreadArray.IsEmpty()) { - thread = mIdleThreadArray.PopLastElement().mThread; + thread = std::move(mIdleThreadArray.PopLastElement().mThread); } } diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp index 1af5b2d3c33d..db32a6e79dca 100644 --- a/dom/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -798,14 +798,12 @@ nsresult nsXMLContentSink::PushContent(nsIContent* aContent) { } void nsXMLContentSink::PopContent() { - int32_t count = mContentStack.Length(); - - if (count == 0) { + if (mContentStack.IsEmpty()) { NS_WARNING("Popping empty stack"); return; } - mContentStack.RemoveElementAt(count - 1); + mContentStack.RemoveLastElement(); } bool nsXMLContentSink::HaveNotifiedForCurrentContent() const { diff --git a/dom/xslt/base/txStack.h b/dom/xslt/base/txStack.h index 310457e8cd78..83c91ae49d15 100644 --- a/dom/xslt/base/txStack.h +++ b/dom/xslt/base/txStack.h @@ -44,9 +44,7 @@ class txStack : private nsTArray { void* object = nullptr; NS_ASSERTION(!isEmpty(), "popping from empty stack"); if (!isEmpty()) { - const uint32_t count = Length() - 1; - object = ElementAt(count); - RemoveElementAt(count); + object = PopLastElement(); } return object; } diff --git a/dom/xslt/xslt/txExecutionState.cpp b/dom/xslt/xslt/txExecutionState.cpp index 60dc42e415a9..a4e7609dfc39 100644 --- a/dom/xslt/xslt/txExecutionState.cpp +++ b/dom/xslt/xslt/txExecutionState.cpp @@ -331,13 +331,8 @@ nsresult txExecutionState::pushBool(bool aBool) { bool txExecutionState::popBool() { NS_ASSERTION(mBoolStack.Length(), "popping from empty stack"); - uint32_t last = mBoolStack.Length() - 1; - NS_ENSURE_TRUE(last != (uint32_t)-1, false); - bool res = mBoolStack.ElementAt(last); - mBoolStack.RemoveElementAt(last); - - return res; + return mBoolStack.IsEmpty() ? false : mBoolStack.PopLastElement(); } nsresult txExecutionState::pushResultHandler(txAXMLEventHandler* aHandler) { diff --git a/dom/xslt/xslt/txStylesheetCompiler.cpp b/dom/xslt/xslt/txStylesheetCompiler.cpp index 2255f75cabb2..b8819849b39e 100644 --- a/dom/xslt/xslt/txStylesheetCompiler.cpp +++ b/dom/xslt/xslt/txStylesheetCompiler.cpp @@ -589,13 +589,11 @@ nsresult txStylesheetCompilerState::pushPtr(void* aPtr, enumStackType aType) { } void* txStylesheetCompilerState::popPtr(enumStackType aType) { - uint32_t stacklen = mTypeStack.Length(); - if (stacklen == 0) { + if (mTypeStack.IsEmpty()) { MOZ_CRASH("Attempt to pop when type stack is empty"); } - enumStackType type = mTypeStack.ElementAt(stacklen - 1); - mTypeStack.RemoveElementAt(stacklen - 1); + enumStackType type = mTypeStack.PopLastElement(); void* value = mOtherStack.pop(); #ifdef TX_DEBUG_STACK diff --git a/editor/libeditor/TypeInState.cpp b/editor/libeditor/TypeInState.cpp index d7360b7f6244..5dbab79689a3 100644 --- a/editor/libeditor/TypeInState.cpp +++ b/editor/libeditor/TypeInState.cpp @@ -207,15 +207,9 @@ void TypeInState::ClearProp(nsAtom* aProp, nsAtom* aAttr) { * Caller assumes ownership of PropItem and must delete it. */ UniquePtr TypeInState::TakeClearProperty() { - size_t count = mClearedArray.Length(); - if (!count) { - return nullptr; - } - - --count; // indices are zero based - PropItem* propItem = mClearedArray[count]; - mClearedArray.RemoveElementAt(count); - return UniquePtr(propItem); + return mClearedArray.Length() + ? UniquePtr{mClearedArray.PopLastElement()} + : nullptr; } /** @@ -223,14 +217,8 @@ UniquePtr TypeInState::TakeClearProperty() { * Caller assumes ownership of PropItem and must delete it. */ UniquePtr TypeInState::TakeSetProperty() { - size_t count = mSetArray.Length(); - if (!count) { - return nullptr; - } - count--; // indices are zero based - PropItem* propItem = mSetArray[count]; - mSetArray.RemoveElementAt(count); - return UniquePtr(propItem); + return mSetArray.Length() ? UniquePtr{mSetArray.PopLastElement()} + : nullptr; } /** diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 70e6735298ca..dd5660a9ca78 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -84,10 +84,7 @@ UniquePtr BufferRecycleBin::GetBuffer(uint32_t aSize) { return UniquePtr(new (fallible) uint8_t[aSize]); } - uint32_t last = mRecycledBuffers.Length() - 1; - UniquePtr result = std::move(mRecycledBuffers[last]); - mRecycledBuffers.RemoveElementAt(last); - return result; + return mRecycledBuffers.PopLastElement(); } void BufferRecycleBin::ClearRecycledBuffers() { diff --git a/gfx/layers/LayerSorter.cpp b/gfx/layers/LayerSorter.cpp index 7e9b985ef78a..65b5264dac41 100644 --- a/gfx/layers/LayerSorter.cpp +++ b/gfx/layers/LayerSorter.cpp @@ -301,12 +301,9 @@ void SortLayersBy3DZOrder(nsTArray& aLayers) { // and remove edges from it. do { if (!noIncoming.IsEmpty()) { - uint32_t last = noIncoming.Length() - 1; - - Layer* layer = noIncoming.ElementAt(last); + Layer* layer = noIncoming.PopLastElement(); MOZ_ASSERT(layer); // don't let null layer pointers sneak into sortedList - noIncoming.RemoveElementAt(last); sortedList.AppendElement(layer); nsTArray::Edge> outgoing; diff --git a/gfx/layers/wr/IpcResourceUpdateQueue.cpp b/gfx/layers/wr/IpcResourceUpdateQueue.cpp index add597470a4f..a8a9a393959b 100644 --- a/gfx/layers/wr/IpcResourceUpdateQueue.cpp +++ b/gfx/layers/wr/IpcResourceUpdateQueue.cpp @@ -72,11 +72,9 @@ layers::OffsetRange ShmSegmentsWriter::Write(Range aBytes) { if (!AllocChunk()) { // Allocation failed, so roll back to the state at the start of this // Write() call and abort. - for (size_t i = mSmallAllocs.Length(); currAllocLen < i; i--) { - MOZ_ASSERT(i > 0); - RefCountedShmem& shm = mSmallAllocs.ElementAt(i - 1); + while (mSmallAllocs.Length() > currAllocLen) { + RefCountedShmem shm = mSmallAllocs.PopLastElement(); RefCountedShm::Dealloc(mShmAllocator, shm); - mSmallAllocs.RemoveElementAt(i - 1); } MOZ_ASSERT(mSmallAllocs.Length() == currAllocLen); return layers::OffsetRange(0, start, 0); diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 0863183f96c3..d8b9c8ea362a 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -607,11 +607,10 @@ void PresShell::DirtyRootsList::Remove(nsIFrame* aFrame) { nsIFrame* PresShell::DirtyRootsList::PopShallowestRoot() { // List is sorted in order of decreasing depth, so there are no deeper // frames than the last one. - const FrameAndDepth& lastFAD = mList.LastElement(); + const FrameAndDepth& lastFAD = mList.PopLastElement(); nsIFrame* frame = lastFAD.mFrame; // We don't expect frame to change depths. MOZ_ASSERT(frame->GetDepthInFrameTree() == lastFAD.mDepth); - mList.RemoveLastElement(); return frame; } diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 9c6ed0ac35ef..5e2e9f9bd621 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -453,7 +453,7 @@ struct MOZ_STACK_CLASS BidiParagraphData { MOZ_ASSERT(mEmbeddingStack.Length(), "embedding/override underflow"); MOZ_ASSERT(aCh == mEmbeddingStack.LastElement()); AppendPopChar(aCh); - mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1); + mEmbeddingStack.RemoveLastElement(); } void ClearBidiControls() { diff --git a/layout/base/nsPresArena.cpp b/layout/base/nsPresArena.cpp index 95a229532498..20e813d62669 100644 --- a/layout/base/nsPresArena.cpp +++ b/layout/base/nsPresArena.cpp @@ -27,12 +27,10 @@ template nsPresArena::~nsPresArena() { #if defined(MOZ_HAVE_MEM_CHECKS) for (FreeList* entry = mFreeLists; entry != ArrayEnd(mFreeLists); ++entry) { - nsTArray::index_type len; - while ((len = entry->mEntries.Length())) { - void* result = entry->mEntries.ElementAt(len - 1); - entry->mEntries.RemoveElementAt(len - 1); + for (void* result : entry->mEntries) { MOZ_MAKE_MEM_UNDEFINED(result, entry->mEntrySize); } + entry->mEntries.Clear(); } #endif } diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index f4f8dd4c8a5e..607c01f560a4 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -981,10 +981,7 @@ bool ServoStyleSet::EnsureUniqueInnerOnCSSSheets() { }); while (!queue.IsEmpty()) { - uint32_t idx = queue.Length() - 1; - auto* sheet = queue[idx].first; - SheetOwner owner = queue[idx].second; - queue.RemoveElementAt(idx); + auto [sheet, owner] = queue.PopLastElement(); // Only call EnsureUniqueInner for complete sheets. If we do call it on // incomplete sheets, we'll cause problems when the sheet is actually diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 7809a44767ad..3223a777e8d1 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -1627,7 +1627,7 @@ nsTextFrame* TextFrameIterator::Next() { mCurrentPosition -= mCurrentFrame->GetPosition(); if (mCurrentFrame->GetContent()->IsSVGElement(nsGkAtoms::textPath)) { // Pop off the frame if this is a . - mTextPathFrames.TruncateLength(mTextPathFrames.Length() - 1); + mTextPathFrames.RemoveLastElement(); } // Pop off the current baseline. PopBaseline(); @@ -1674,7 +1674,7 @@ void TextFrameIterator::PushBaseline(nsIFrame* aNextFrame) { void TextFrameIterator::PopBaseline() { NS_ASSERTION(!mBaselines.IsEmpty(), "popped too many baselines"); - mBaselines.TruncateLength(mBaselines.Length() - 1); + mBaselines.RemoveLastElement(); } // ----------------------------------------------------------------------------- diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 0c0425a4bcc6..2a00fe578128 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -570,7 +570,7 @@ void nsTableFrame::InsertCol(nsTableColFrame& aColFrame, int32_t aColIndex) { nsTableColType lastColType = lastCol->GetColType(); if (eColAnonymousCell == lastColType) { // remove the col from the cache - mColFrames.RemoveElementAt(numCacheCols - 1); + mColFrames.RemoveLastElement(); // remove the col from the synthetic col group nsTableColGroupFrame* lastColGroup = (nsTableColGroupFrame*)mColGroups.LastChild(); diff --git a/netwerk/cache2/CacheIndexIterator.cpp b/netwerk/cache2/CacheIndexIterator.cpp index 0c365c1f8282..274b0bcc0102 100644 --- a/netwerk/cache2/CacheIndexIterator.cpp +++ b/netwerk/cache2/CacheIndexIterator.cpp @@ -36,8 +36,7 @@ nsresult CacheIndexIterator::GetNextHash(SHA1Sum::Hash* aHash) { return mStatus; } - memcpy(aHash, mRecords[mRecords.Length() - 1]->mHash, sizeof(SHA1Sum::Hash)); - mRecords.RemoveLastElement(); + memcpy(aHash, mRecords.PopLastElement()->mHash, sizeof(SHA1Sum::Hash)); return NS_OK; } diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index d10d54944ee9..410b40dfdedc 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -9035,10 +9035,10 @@ void nsHttpChannel::PushRedirectAsyncFunc(nsContinueRedirectionFunc func) { } void nsHttpChannel::PopRedirectAsyncFunc(nsContinueRedirectionFunc func) { - MOZ_ASSERT(func == mRedirectFuncStack[mRedirectFuncStack.Length() - 1], + MOZ_ASSERT(func == mRedirectFuncStack.LastElement(), "Trying to pop wrong method from redirect async stack!"); - mRedirectFuncStack.TruncateLength(mRedirectFuncStack.Length() - 1); + mRedirectFuncStack.RemoveLastElement(); } //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index dda9032029a1..a70390c5a84c 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -728,7 +728,7 @@ HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnectionByHashKey( listOfWeakConns->Elements()[j] = listOfWeakConns->Elements()[listLen - 1]; } - listOfWeakConns->RemoveElementAt(listLen - 1); + listOfWeakConns->RemoveLastElement(); MOZ_ASSERT(listOfWeakConns->Length() == listLen - 1); listLen--; continue; // without adjusting iterator diff --git a/toolkit/components/commandlines/nsCommandLine.cpp b/toolkit/components/commandlines/nsCommandLine.cpp index 642f466987ba..733f807c4d31 100644 --- a/toolkit/components/commandlines/nsCommandLine.cpp +++ b/toolkit/components/commandlines/nsCommandLine.cpp @@ -96,9 +96,7 @@ nsCommandLine::RemoveArguments(int32_t aStart, int32_t aEnd) { NS_ENSURE_ARG_MIN(aStart, 0); NS_ENSURE_ARG_MAX(uint32_t(aEnd) + 1, mArgs.Length()); - for (int32_t i = aEnd; i >= aStart; --i) { - mArgs.RemoveElementAt(i); - } + mArgs.RemoveElementsAt(mArgs.begin() + aStart, mArgs.begin() + aEnd + 1); return NS_OK; } diff --git a/toolkit/components/reputationservice/ApplicationReputation.cpp b/toolkit/components/reputationservice/ApplicationReputation.cpp index 9ab8f49a5808..a881bd22ae62 100644 --- a/toolkit/components/reputationservice/ApplicationReputation.cpp +++ b/toolkit/components/reputationservice/ApplicationReputation.cpp @@ -990,12 +990,10 @@ nsresult PendingLookup::LookupNext() { // If a url is in blocklist we should call PendingLookup::OnComplete directly. MOZ_ASSERT(mBlocklistCount == 0); - int index = mAnylistSpecs.Length() - 1; nsCString spec; - if (index >= 0) { + if (!mAnylistSpecs.IsEmpty()) { // Check the source URI only. - spec = mAnylistSpecs[index]; - mAnylistSpecs.RemoveElementAt(index); + spec = mAnylistSpecs.PopLastElement(); RefPtr lookup(new PendingDBLookup(this)); // We don't need to check whitelist if the file is not a binary file. @@ -1004,11 +1002,9 @@ nsresult PendingLookup::LookupNext() { return lookup->LookupSpec(spec, type); } - index = mBlocklistSpecs.Length() - 1; - if (index >= 0) { + if (!mBlocklistSpecs.IsEmpty()) { // Check the referrer and redirect chain. - spec = mBlocklistSpecs[index]; - mBlocklistSpecs.RemoveElementAt(index); + spec = mBlocklistSpecs.PopLastElement(); RefPtr lookup(new PendingDBLookup(this)); return lookup->LookupSpec(spec, LookupType::BlocklistOnly); } @@ -1024,11 +1020,9 @@ nsresult PendingLookup::LookupNext() { MOZ_ASSERT_IF(!mIsBinaryFile, mAllowlistSpecs.Length() == 0); // Only binary signatures remain. - index = mAllowlistSpecs.Length() - 1; - if (index >= 0) { - spec = mAllowlistSpecs[index]; + if (!mAllowlistSpecs.IsEmpty()) { + spec = mAllowlistSpecs.PopLastElement(); LOG(("PendingLookup::LookupNext: checking %s on allowlist", spec.get())); - mAllowlistSpecs.RemoveElementAt(index); RefPtr lookup(new PendingDBLookup(this)); return lookup->LookupSpec(spec, LookupType::AllowlistOnly); } diff --git a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp index 010811657de5..333c55407668 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp @@ -540,7 +540,7 @@ nsresult nsUrlClassifierPrefixSet::WritePrefixes( totalDeltas += deltaLength; indexStarts.AppendElement(totalDeltas); } - indexStarts.RemoveElementAt(indexSize); // we don't use the last element + indexStarts.RemoveLastElement(); // we don't use the last element MOZ_ASSERT(indexStarts.Length() == indexSize); } diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm index 529b31677146..77a246827cc8 100644 --- a/widget/cocoa/nsCocoaUtils.mm +++ b/widget/cocoa/nsCocoaUtils.mm @@ -1421,8 +1421,7 @@ void nsCocoaUtils::ResolveMediaCapturePromises(bool aGranted, PromiseArray& aPro // Remove each promise from the list and resolve it. while (aPromiseList->Length() > 0) { - RefPtr promise = aPromiseList->LastElement(); - aPromiseList->RemoveLastElement(); + RefPtr promise = aPromiseList->PopLastElement(); // Resolve on main thread nsCOMPtr runnable(NS_NewRunnableFunction( diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp index 8bd072bcd371..bdaab31c7499 100644 --- a/widget/gtk/WindowSurfaceWayland.cpp +++ b/widget/gtk/WindowSurfaceWayland.cpp @@ -969,19 +969,16 @@ void WindowSurfaceWayland::CacheImageSurface( WindowImageSurface surf = WindowImageSurface(mImageSurface, aRegion); if (mDelayedImageCommits.Length()) { - int lastSurf = mDelayedImageCommits.Length() - 1; - if (surf.OverlapsSurface(mDelayedImageCommits[lastSurf])) { + auto lastSurf = mDelayedImageCommits.PopLastElement(); + if (surf.OverlapsSurface(lastSurf)) { #ifdef MOZ_LOGGING { - gfx::IntRect size = mDelayedImageCommits[lastSurf] - .GetUpdateRegion() - ->GetBounds() - .ToUnknownRect(); + gfx::IntRect size = + lastSurf.GetUpdateRegion()->GetBounds().ToUnknownRect(); LOGWAYLAND((" removing [ %d, %d] -> [%d x %d]\n", size.x, size.y, size.width, size.height)); } #endif - mDelayedImageCommits.RemoveElementAt(lastSurf); } } diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 57152f8c9ada..a1df6616202f 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -2046,9 +2046,8 @@ void nsMemoryReporterManager::EndProcessReport(uint32_t aGeneration, while (s->mNumProcessesRunning < s->mConcurrencyLimit && !s->mChildrenPending.IsEmpty()) { // Pop last element from s->mChildrenPending - RefPtr nextChild; - nextChild.swap(s->mChildrenPending.LastElement()); - s->mChildrenPending.TruncateLength(s->mChildrenPending.Length() - 1); + const RefPtr nextChild = + s->mChildrenPending.PopLastElement(); // Start report (if the child is still alive). if (StartChildReport(nextChild, s)) { ++s->mNumProcessesRunning; diff --git a/xpcom/ds/nsExpirationTracker.h b/xpcom/ds/nsExpirationTracker.h index c82ee1412bd0..0906f3c0b825 100644 --- a/xpcom/ds/nsExpirationTracker.h +++ b/xpcom/ds/nsExpirationTracker.h @@ -189,12 +189,13 @@ class ExpirationTrackerImpl { MOZ_ASSERT(generation.Length() > index && generation[index] == aObj, "Object is lying about its index"); // Move the last object to fill the hole created by removing aObj - uint32_t last = generation.Length() - 1; - T* lastObj = generation[last]; - generation[index] = lastObj; + T* lastObj = generation.PopLastElement(); + // XXX It looks weird that index might point to the element that was just + // removed. Is that really correct? + if (index < generation.Length()) { + generation[index] = lastObj; + } lastObj->GetExpirationState()->mIndexInGeneration = index; - generation.RemoveElementAt(last); - MOZ_ASSERT(generation.Length() == last); state->mGeneration = nsExpirationState::NOT_TRACKED; // We do not check whether we need to stop the timer here. The timer // will check that itself next time it fires. Checking here would not diff --git a/xpcom/ds/nsTPriorityQueue.h b/xpcom/ds/nsTPriorityQueue.h index b5a02957c018..70e711e65a07 100644 --- a/xpcom/ds/nsTPriorityQueue.h +++ b/xpcom/ds/nsTPriorityQueue.h @@ -93,11 +93,15 @@ class nsTPriorityQueue { */ T Pop() { MOZ_ASSERT(!mElements.IsEmpty(), "Empty queue"); - T pop = mElements[0]; + T pop = std::move(mElements[0]); + + if (mElements.Length() == 1) { + mElements.Clear(); + return pop; + } // Move last to front - mElements[0] = mElements[mElements.Length() - 1]; - mElements.TruncateLength(mElements.Length() - 1); + mElements[0] = mElements.PopLastElement(); // Sift down size_type i = 0;