Bug 1340771 part 2 - Introduce a WeakFrame class for heap allocated weak frame pointers, stored in a hashtable for fast lookup. r=tn

* * *
Bug 1340771 part 3 - Change existing heap allocated AutoWeakFrame instances to use WeakFrame instead.  r=tn

MozReview-Commit-ID: GSuUiy98jBa
This commit is contained in:
Mats Palmgren 2017-03-01 18:03:14 +01:00
Родитель d13aaf9ce0
Коммит 6ef6efaea3
25 изменённых файлов: 227 добавлений и 64 удалений

Просмотреть файл

@ -121,7 +121,7 @@ protected:
private:
// Currently focused control.
AutoWeakFrame mCurrCtrlFrame;
WeakFrame mCurrCtrlFrame;
int32_t mCaretOffset;
HyperTextAccessible* mAccWithCaret;
};

Просмотреть файл

@ -329,7 +329,7 @@ private:
// Stores the root frame of the subdocument while the subdocument is being
// reframed. Used to restore the presentation after reframing.
AutoWeakFrame mDetachedSubdocFrame;
WeakFrame mDetachedSubdocFrame;
// Stores the containing document of the frame corresponding to this
// frame loader. This is reference is kept valid while the subframe's
// presentation is detached and stored in mDetachedSubdocFrame. This

Просмотреть файл

@ -715,7 +715,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
bool mPreferFallback : 1;
bool mPreferFallbackKnown : 1;
AutoWeakFrame mPrintFrame;
WeakFrame mPrintFrame;
RefPtr<nsPluginInstanceOwner> mInstanceOwner;
nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;

Просмотреть файл

@ -4450,8 +4450,9 @@ EventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
}
}
AutoWeakFrame currentTraget = mCurrentTarget;
FireDragEnterOrExit(aPresContext, aDragEvent, eDragEnter,
lastContent, targetContent, mCurrentTarget);
lastContent, targetContent, currentTraget);
if (sLastDragOverFrame) {
FireDragEnterOrExit(sLastDragOverFrame->PresContext(),

Просмотреть файл

@ -54,7 +54,7 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(OverOutElementsWrapper)
AutoWeakFrame mLastOverFrame;
WeakFrame mLastOverFrame;
nsCOMPtr<nsIContent> mLastOverElement;
@ -930,7 +930,7 @@ private:
// to content.
static LayoutDeviceIntPoint sSynthCenteringPoint;
AutoWeakFrame mCurrentTarget;
WeakFrame mCurrentTarget;
nsCOMPtr<nsIContent> mCurrentTargetContent;
static AutoWeakFrame sLastDragOverFrame;

Просмотреть файл

@ -665,35 +665,51 @@ nsIPresShell::SetVerifyReflowEnable(bool aEnabled)
}
/* virtual */ void
nsIPresShell::AddWeakFrameExternal(AutoWeakFrame* aWeakFrame)
nsIPresShell::AddAutoWeakFrameExternal(AutoWeakFrame* aWeakFrame)
{
AddAutoWeakFrameInternal(aWeakFrame);
}
void
nsIPresShell::AddAutoWeakFrameInternal(AutoWeakFrame* aWeakFrame)
{
if (aWeakFrame->GetFrame()) {
aWeakFrame->GetFrame()->AddStateBits(NS_FRAME_EXTERNAL_REFERENCE);
}
aWeakFrame->SetPreviousWeakFrame(mAutoWeakFrames);
mAutoWeakFrames = aWeakFrame;
}
/* virtual */ void
nsIPresShell::AddWeakFrameExternal(WeakFrame* aWeakFrame)
{
AddWeakFrameInternal(aWeakFrame);
}
void
nsIPresShell::AddWeakFrameInternal(AutoWeakFrame* aWeakFrame)
nsIPresShell::AddWeakFrameInternal(WeakFrame* aWeakFrame)
{
if (aWeakFrame->GetFrame()) {
aWeakFrame->GetFrame()->AddStateBits(NS_FRAME_EXTERNAL_REFERENCE);
}
aWeakFrame->SetPreviousWeakFrame(mWeakFrames);
mWeakFrames = aWeakFrame;
MOZ_ASSERT(!mWeakFrames.GetEntry(aWeakFrame));
mWeakFrames.PutEntry(aWeakFrame);
}
/* virtual */ void
nsIPresShell::RemoveWeakFrameExternal(AutoWeakFrame* aWeakFrame)
nsIPresShell::RemoveAutoWeakFrameExternal(AutoWeakFrame* aWeakFrame)
{
RemoveWeakFrameInternal(aWeakFrame);
RemoveAutoWeakFrameInternal(aWeakFrame);
}
void
nsIPresShell::RemoveWeakFrameInternal(AutoWeakFrame* aWeakFrame)
nsIPresShell::RemoveAutoWeakFrameInternal(AutoWeakFrame* aWeakFrame)
{
if (mWeakFrames == aWeakFrame) {
mWeakFrames = aWeakFrame->GetPreviousWeakFrame();
if (mAutoWeakFrames == aWeakFrame) {
mAutoWeakFrames = aWeakFrame->GetPreviousWeakFrame();
return;
}
AutoWeakFrame* nextWeak = mWeakFrames;
AutoWeakFrame* nextWeak = mAutoWeakFrames;
while (nextWeak && nextWeak->GetPreviousWeakFrame() != aWeakFrame) {
nextWeak = nextWeak->GetPreviousWeakFrame();
}
@ -702,6 +718,19 @@ nsIPresShell::RemoveWeakFrameInternal(AutoWeakFrame* aWeakFrame)
}
}
/* virtual */ void
nsIPresShell::RemoveWeakFrameExternal(WeakFrame* aWeakFrame)
{
RemoveWeakFrameInternal(aWeakFrame);
}
void
nsIPresShell::RemoveWeakFrameInternal(WeakFrame* aWeakFrame)
{
MOZ_ASSERT(mWeakFrames.GetEntry(aWeakFrame));
mWeakFrames.RemoveEntry(aWeakFrame);
}
already_AddRefed<nsFrameSelection>
nsIPresShell::FrameSelection()
{
@ -751,7 +780,7 @@ nsIPresShell::nsIPresShell()
, mDrawEventTargetFrame(nullptr)
#endif
, mPaintCount(0)
, mWeakFrames(nullptr)
, mAutoWeakFrames(nullptr)
, mCanvasBackgroundColor(NS_RGBA(0,0,0,0))
, mSelectionFlags(0)
, mRenderFlags(0)
@ -1366,10 +1395,17 @@ PresShell::Destroy()
}
NS_WARNING_ASSERTION(!mWeakFrames,
NS_WARNING_ASSERTION(!mAutoWeakFrames && mWeakFrames.IsEmpty(),
"Weak frames alive after destroying FrameManager");
while (mWeakFrames) {
mWeakFrames->Clear(this);
while (mAutoWeakFrames) {
mAutoWeakFrames->Clear(this);
}
nsTArray<WeakFrame*> toRemove(mWeakFrames.Count());
for (auto iter = mWeakFrames.Iter(); !iter.Done(); iter.Next()) {
toRemove.AppendElement(iter.Get()->GetKey());
}
for (WeakFrame* weakFrame : toRemove) {
weakFrame->Clear(this);
}
// Let the style set do its cleanup.
@ -2949,15 +2985,26 @@ PresShell::ClearFrameRefs(nsIFrame* aFrame)
{
mPresContext->EventStateManager()->ClearFrameRefs(aFrame);
AutoWeakFrame* weakFrame = mWeakFrames;
AutoWeakFrame* weakFrame = mAutoWeakFrames;
while (weakFrame) {
AutoWeakFrame* prev = weakFrame->GetPreviousWeakFrame();
if (weakFrame->GetFrame() == aFrame) {
// This removes weakFrame from mWeakFrames.
// This removes weakFrame from mAutoWeakFrames.
weakFrame->Clear(this);
}
weakFrame = prev;
}
AutoTArray<WeakFrame*, 4> toRemove;
for (auto iter = mWeakFrames.Iter(); !iter.Done(); iter.Next()) {
WeakFrame* weakFrame = iter.Get()->GetKey();
if (weakFrame->GetFrame() == aFrame) {
toRemove.AppendElement(weakFrame);
}
}
for (WeakFrame* weakFrame : toRemove) {
weakFrame->Clear(this);
}
}
already_AddRefed<gfxContext>

Просмотреть файл

@ -79,6 +79,7 @@ class nsCSSFrameConstructor;
class nsISelection;
template<class E> class nsCOMArray;
class AutoWeakFrame;
class WeakFrame;
class nsIScrollableFrame;
class gfxContext;
class nsIDOMEvent;
@ -1192,10 +1193,20 @@ public:
mozilla::LayoutDeviceIntRect* aScreenRect,
uint32_t aFlags) = 0;
void AddWeakFrameInternal(AutoWeakFrame* aWeakFrame);
virtual void AddWeakFrameExternal(AutoWeakFrame* aWeakFrame);
void AddAutoWeakFrameInternal(AutoWeakFrame* aWeakFrame);
virtual void AddAutoWeakFrameExternal(AutoWeakFrame* aWeakFrame);
void AddWeakFrameInternal(WeakFrame* aWeakFrame);
virtual void AddWeakFrameExternal(WeakFrame* aWeakFrame);
void AddWeakFrame(AutoWeakFrame* aWeakFrame)
void AddAutoWeakFrame(AutoWeakFrame* aWeakFrame)
{
#ifdef MOZILLA_INTERNAL_API
AddAutoWeakFrameInternal(aWeakFrame);
#else
AddAutoWeakFrameExternal(aWeakFrame);
#endif
}
void AddWeakFrame(WeakFrame* aWeakFrame)
{
#ifdef MOZILLA_INTERNAL_API
AddWeakFrameInternal(aWeakFrame);
@ -1204,10 +1215,20 @@ public:
#endif
}
void RemoveWeakFrameInternal(AutoWeakFrame* aWeakFrame);
virtual void RemoveWeakFrameExternal(AutoWeakFrame* aWeakFrame);
void RemoveAutoWeakFrameInternal(AutoWeakFrame* aWeakFrame);
virtual void RemoveAutoWeakFrameExternal(AutoWeakFrame* aWeakFrame);
void RemoveWeakFrameInternal(WeakFrame* aWeakFrame);
virtual void RemoveWeakFrameExternal(WeakFrame* aWeakFrame);
void RemoveWeakFrame(AutoWeakFrame* aWeakFrame)
void RemoveAutoWeakFrame(AutoWeakFrame* aWeakFrame)
{
#ifdef MOZILLA_INTERNAL_API
RemoveAutoWeakFrameInternal(aWeakFrame);
#else
RemoveAutoWeakFrameExternal(aWeakFrame);
#endif
}
void RemoveWeakFrame(WeakFrame* aWeakFrame)
{
#ifdef MOZILLA_INTERNAL_API
RemoveWeakFrameInternal(aWeakFrame);
@ -1815,8 +1836,11 @@ protected:
nsSize mScrollPositionClampingScrollPortSize;
// A list of weak frames. This is a pointer to the last item in the list.
AutoWeakFrame* mWeakFrames;
// A list of stack weak frames. This is a pointer to the last item in the list.
AutoWeakFrame* mAutoWeakFrames;
// A hash table of heap allocated weak frames.
nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
// Most recent canvas background color.
nscolor mCanvasBackgroundColor;

Просмотреть файл

@ -413,7 +413,7 @@ public:
return NS_OK;
}
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
void
@ -527,7 +527,7 @@ public:
}
return NS_OK;
}
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
class nsAsyncResize : public Runnable
@ -556,7 +556,7 @@ public:
}
return NS_OK;
}
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
void

Просмотреть файл

@ -103,7 +103,7 @@ private:
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
/**

Просмотреть файл

@ -111,7 +111,7 @@ protected:
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
class DnDListener: public MouseListener {

Просмотреть файл

@ -192,7 +192,7 @@ private:
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
/**

Просмотреть файл

@ -406,6 +406,12 @@ nsIFrame::ContentStatesChanged(mozilla::EventStates aStates)
{
}
AutoWeakFrame::AutoWeakFrame(const WeakFrame& aOther)
: mPrev(nullptr), mFrame(nullptr)
{
Init(aOther.GetFrame());
}
void
AutoWeakFrame::Init(nsIFrame* aFrame)
{
@ -414,6 +420,22 @@ AutoWeakFrame::Init(nsIFrame* aFrame)
if (mFrame) {
nsIPresShell* shell = mFrame->PresContext()->GetPresShell();
NS_WARNING_ASSERTION(shell, "Null PresShell in AutoWeakFrame!");
if (shell) {
shell->AddAutoWeakFrame(this);
} else {
mFrame = nullptr;
}
}
}
void
WeakFrame::Init(nsIFrame* aFrame)
{
Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nullptr);
mFrame = aFrame;
if (mFrame) {
nsIPresShell* shell = mFrame->PresContext()->GetPresShell();
MOZ_ASSERT(shell, "Null PresShell in WeakFrame!");
if (shell) {
shell->AddWeakFrame(this);
} else {

Просмотреть файл

@ -3818,7 +3818,8 @@ public:
/**
* AutoWeakFrame can be used to keep a reference to a nsIFrame in a safe way.
* Whenever an nsIFrame object is deleted, the AutoWeakFrames pointing
* to it will be cleared.
* to it will be cleared. AutoWeakFrame is for variables on the stack or
* in static storage only, there is also a WeakFrame below for heap uses.
*
* Create AutoWeakFrame object when it is sure that nsIFrame object
* is alive and after some operations which may destroy the nsIFrame
@ -3827,17 +3828,23 @@ public:
*
* @note The usage of this class should be kept to a minimum.
*/
class AutoWeakFrame {
class WeakFrame;
class AutoWeakFrame
{
public:
AutoWeakFrame() : mPrev(nullptr), mFrame(nullptr) { }
explicit AutoWeakFrame()
: mPrev(nullptr), mFrame(nullptr) {}
AutoWeakFrame(const AutoWeakFrame& aOther) : mPrev(nullptr), mFrame(nullptr)
AutoWeakFrame(const AutoWeakFrame& aOther)
: mPrev(nullptr), mFrame(nullptr)
{
Init(aOther.GetFrame());
}
MOZ_IMPLICIT AutoWeakFrame(nsIFrame* aFrame) : mPrev(nullptr), mFrame(nullptr)
MOZ_IMPLICIT AutoWeakFrame(const WeakFrame& aOther);
MOZ_IMPLICIT AutoWeakFrame(nsIFrame* aFrame)
: mPrev(nullptr), mFrame(nullptr)
{
Init(aFrame);
}
@ -3864,7 +3871,7 @@ public:
void Clear(nsIPresShell* aShell) {
if (aShell) {
aShell->RemoveWeakFrame(this);
aShell->RemoveAutoWeakFrame(this);
}
mFrame = nullptr;
mPrev = nullptr;
@ -3883,10 +3890,73 @@ public:
Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nullptr);
}
private:
// Not available for the heap!
void* operator new(size_t) = delete;
void* operator new[](size_t) = delete;
void operator delete(void*) = delete;
void operator delete[](void*) = delete;
void Init(nsIFrame* aFrame);
AutoWeakFrame* mPrev;
nsIFrame* mFrame;
nsIFrame* mFrame;
};
/**
* @see AutoWeakFrame
*/
class WeakFrame
{
public:
WeakFrame() : mFrame(nullptr) {}
WeakFrame(const WeakFrame& aOther) : mFrame(nullptr)
{
Init(aOther.GetFrame());
}
MOZ_IMPLICIT WeakFrame(const AutoWeakFrame& aOther) : mFrame(nullptr)
{
Init(aOther.GetFrame());
}
MOZ_IMPLICIT WeakFrame(nsIFrame* aFrame) : mFrame(nullptr)
{
Init(aFrame);
}
~WeakFrame()
{
Clear(mFrame ? mFrame->PresContext()->GetPresShell() : nullptr);
}
WeakFrame& operator=(WeakFrame& aOther) {
Init(aOther.GetFrame());
return *this;
}
WeakFrame& operator=(nsIFrame* aFrame) {
Init(aFrame);
return *this;
}
nsIFrame* operator->() { return mFrame; }
operator nsIFrame*() { return mFrame; }
void Clear(nsIPresShell* aShell) {
if (aShell) {
aShell->RemoveWeakFrame(this);
}
mFrame = nullptr;
}
bool IsAlive() { return !!mFrame; }
nsIFrame* GetFrame() const { return mFrame; }
private:
void Init(nsIFrame* aFrame);
nsIFrame* mFrame;
};
inline bool

Просмотреть файл

@ -93,7 +93,7 @@ public:
return NS_OK;
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
static void

Просмотреть файл

@ -105,7 +105,7 @@ public:
// The scroll frame during for which we most recently received a call to
// NotifyAnimatedFromScrollHandler.
AutoWeakFrame mAnimatingScrollHandlerFrame;
WeakFrame mAnimatingScrollHandlerFrame;
// The set of activities that were triggered during
// mAnimatingScrollHandlerFrame's scroll event handler.
EnumSet<ActivityIndex> mScrollHandlerInducedActivity;
@ -132,7 +132,7 @@ public:
virtual void NotifyExpired(LayerActivity* aObject);
public:
AutoWeakFrame mCurrentScrollHandlerFrame;
WeakFrame mCurrentScrollHandlerFrame;
private:
bool mDestroying;

Просмотреть файл

@ -263,7 +263,7 @@ protected:
mozilla::UniquePtr<nsPrintData> mPrt;
nsPagePrintTimer* mPagePrintTimer;
AutoWeakFrame mPageSeqFrame;
WeakFrame mPageSeqFrame;
// Print Preview
mozilla::UniquePtr<nsPrintData> mPrtPreview;

Просмотреть файл

@ -4861,7 +4861,7 @@ public:
return NS_OK;
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
bool

Просмотреть файл

@ -1130,7 +1130,7 @@ nsListBoxBodyFrame::GetFirstItemBox(int32_t aOffset, bool* aCreated)
mBottomFrame = mTopFrame;
if (mTopFrame) {
return mTopFrame->IsXULBoxFrame() ? mTopFrame : nullptr;
return mTopFrame->IsXULBoxFrame() ? mTopFrame.GetFrame() : nullptr;
}
// top frame was cleared out
@ -1138,7 +1138,7 @@ nsListBoxBodyFrame::GetFirstItemBox(int32_t aOffset, bool* aCreated)
mBottomFrame = mTopFrame;
if (mTopFrame && mRowsToPrepend <= 0) {
return mTopFrame->IsXULBoxFrame() ? mTopFrame : nullptr;
return mTopFrame->IsXULBoxFrame() ? mTopFrame.GetFrame() : nullptr;
}
// At this point, we either have no frames at all,
@ -1187,7 +1187,7 @@ nsListBoxBodyFrame::GetFirstItemBox(int32_t aOffset, bool* aCreated)
mBottomFrame = mTopFrame;
return mTopFrame->IsXULBoxFrame() ? mTopFrame : nullptr;
return mTopFrame->IsXULBoxFrame() ? mTopFrame.GetFrame() : nullptr;
} else
return GetFirstItemBox(++aOffset, 0);
}

Просмотреть файл

@ -185,7 +185,7 @@ protected:
nsCOMPtr<nsPIBoxObject> mBoxObject;
// frame markers
AutoWeakFrame mTopFrame;
WeakFrame mTopFrame;
nsIFrame* mBottomFrame;
nsIFrame* mLinkupFrame;

Просмотреть файл

@ -138,7 +138,7 @@ public:
return NS_OK;
}
protected:
AutoWeakFrame mFrame;
WeakFrame mFrame;
nsCOMPtr<nsIAtom> mAttr;
};

Просмотреть файл

@ -31,7 +31,7 @@ public:
NS_DECL_NSIRUNNABLE
AutoWeakFrame mWeakFrame;
WeakFrame mWeakFrame;
nsIPresShell::IntrinsicDirty mIntrinsicDirty;
nsFrameState mBitToAdd;
};
@ -100,7 +100,7 @@ public:
delete this;
}
AutoWeakFrame mWeakFrame;
WeakFrame mWeakFrame;
};
NS_IMETHODIMP

Просмотреть файл

@ -187,11 +187,11 @@ public:
delete this;
}
AutoWeakFrame mWeakFrame;
WeakFrame mWeakFrame;
};
bool
nsTextBoxFrame::UpdateAccesskey(AutoWeakFrame& aWeakThis)
nsTextBoxFrame::UpdateAccesskey(WeakFrame& aWeakThis)
{
nsAutoString accesskey;
nsCOMPtr<nsIDOMXULLabelElement> labelElement = do_QueryInterface(mContent);

Просмотреть файл

@ -71,7 +71,7 @@ protected:
friend class nsDisplayXULTextBox;
// Should be called only by nsAsyncAccesskeyUpdate.
// Returns true if accesskey was updated.
bool UpdateAccesskey(AutoWeakFrame& aWeakThis);
bool UpdateAccesskey(WeakFrame& aWeakThis);
void UpdateAccessTitle();
void UpdateAccessIndex();

Просмотреть файл

@ -1263,12 +1263,11 @@ void
nsXULPopupManager::HidePopupsInList(const nsTArray<nsMenuPopupFrame *> &aFrames)
{
// Create a weak frame list. This is done in a separate array with the
// right capacity predetermined, otherwise the array would get resized and
// move the weak frame pointers around.
nsTArray<AutoWeakFrame> weakPopups(aFrames.Length());
// right capacity predetermined to avoid multiple allocations.
nsTArray<WeakFrame> weakPopups(aFrames.Length());
uint32_t f;
for (f = 0; f < aFrames.Length(); f++) {
AutoWeakFrame* wframe = weakPopups.AppendElement();
WeakFrame* wframe = weakPopups.AppendElement();
if (wframe)
*wframe = aFrames[f];
}

Просмотреть файл

@ -4906,7 +4906,7 @@ public:
return NS_OK;
}
private:
AutoWeakFrame mFrame;
WeakFrame mFrame;
};
bool