diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-05 10:31:42 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:23 -0500 |
commit | d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f (patch) | |
tree | c5a20606c673e9509a8354bdbcaf17c18fab991b | |
parent | ca596f2823f90c1416db8a317ac8eb22c9119bbf (diff) | |
download | UXP-d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f.tar UXP-d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f.tar.gz UXP-d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f.tar.lz UXP-d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f.tar.xz UXP-d7e5ad445cc8cb3f3f04e7c177350fcf1c12c62f.zip |
Bug 1299363 - Part 4: Hold a pointer of ElementQueue in ReactionsStack instead.
1. It is possible that invoking a reaction triggers pushing a new ElementQueue into ReactionStack (e.g., calling define() in constructor which probably enqueue another upgrade reaction), and the reference of ElementQueue passed to InvokeReactions becomes invalid due to the memmove in nsTArray implementation.
2. And we get another benefit from this is memmove becomes faster.
Tag UXP Issue #1344
-rw-r--r-- | dom/base/CustomElementRegistry.cpp | 28 | ||||
-rw-r--r-- | dom/base/CustomElementRegistry.h | 4 |
2 files changed, 18 insertions, 14 deletions
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 82f15f683..660222058 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -833,7 +833,7 @@ void CustomElementReactionsStack::CreateAndPushElementQueue() { // Push a new element queue onto the custom element reactions stack. - mReactionsStack.AppendElement(); + mReactionsStack.AppendElement(MakeUnique<ElementQueue>()); } void @@ -844,15 +844,19 @@ CustomElementReactionsStack::PopAndInvokeElementQueue() MOZ_ASSERT(!mReactionsStack.IsEmpty(), "Reaction stack shouldn't be empty"); - ElementQueue& elementQueue = mReactionsStack.LastElement(); + const uint32_t lastIndex = mReactionsStack.Length() - 1; + ElementQueue* elementQueue = mReactionsStack.ElementAt(lastIndex).get(); // Check element queue size in order to reduce function call overhead. - if (!elementQueue.IsEmpty()) { + if (!elementQueue->IsEmpty()) { InvokeReactions(elementQueue); } - DebugOnly<bool> isRemovedElement = mReactionsStack.RemoveElement(elementQueue); - MOZ_ASSERT(isRemovedElement, - "Reaction stack should have an element queue to remove"); + // InvokeReactions() might create other custom element reactions, but those + // new reactions should be already consumed and removed at this point. + MOZ_ASSERT(lastIndex == mReactionsStack.Length() - 1, + "reactions created by InvokeReactions() should be consumed and removed"); + + mReactionsStack.RemoveElementAt(lastIndex); } void @@ -882,7 +886,7 @@ CustomElementReactionsStack::Enqueue(Element* aElement, // Add element to the current element queue. if (!mReactionsStack.IsEmpty()) { - mReactionsStack.LastElement().AppendElement(do_GetWeakReference(aElement)); + mReactionsStack.LastElement()->AppendElement(do_GetWeakReference(aElement)); elementData->mReactionQueue.AppendElement(aReaction); return; } @@ -907,16 +911,16 @@ CustomElementReactionsStack::InvokeBackupQueue() { // Check backup queue size in order to reduce function call overhead. if (!mBackupQueue.IsEmpty()) { - InvokeReactions(mBackupQueue); + InvokeReactions(&mBackupQueue); } } void -CustomElementReactionsStack::InvokeReactions(ElementQueue& aElementQueue) +CustomElementReactionsStack::InvokeReactions(ElementQueue* aElementQueue) { // Note: It's possible to re-enter this method. - for (uint32_t i = 0; i < aElementQueue.Length(); ++i) { - nsCOMPtr<Element> element = do_QueryReferent(aElementQueue[i]); + for (uint32_t i = 0; i < aElementQueue->Length(); ++i) { + nsCOMPtr<Element> element = do_QueryReferent(aElementQueue->ElementAt(i)); if (!element) { continue; @@ -936,7 +940,7 @@ CustomElementReactionsStack::InvokeReactions(ElementQueue& aElementQueue) } reactions.Clear(); } - aElementQueue.Clear(); + aElementQueue->Clear(); } //----------------------------------------------------- diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index db208bf71..620492cbb 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -247,7 +247,7 @@ private: ~CustomElementReactionsStack() {}; // The choice of 8 for the auto size here is based on gut feeling. - AutoTArray<ElementQueue, 8> mReactionsStack; + AutoTArray<UniquePtr<ElementQueue>, 8> mReactionsStack; ElementQueue mBackupQueue; // https://html.spec.whatwg.org/#enqueue-an-element-on-the-appropriate-element-queue bool mIsBackupQueueProcessing; @@ -258,7 +258,7 @@ private: * Invoke custom element reactions * https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions */ - void InvokeReactions(ElementQueue& aElementQueue); + void InvokeReactions(ElementQueue* aElementQueue); void Enqueue(Element* aElement, CustomElementReaction* aReaction); |