Bug 1588745 - part 4: Make TextControlState reuse its instance by itself r=Ehsan

Currently, only `HTMLInputElement` reuses `TextControlState` instance since
`HTMLTextAreaElement` had the instance as a member rather than allocate it.

Now, all instances are allocated in the heap independently for guaranteeing
their lifetime.  So, the reuse mechanism should be managed by
`TextControlState` itself.

Depends on D51393

Differential Revision: https://phabricator.services.mozilla.com/D51394
This commit is contained in:
Masayuki Nakano
2019-11-01 20:51:48 +00:00
parent c14ab80c37
commit 55109d6fed
5 changed files with 58 additions and 50 deletions

View File

@@ -1127,7 +1127,7 @@ class MOZ_STACK_CLASS AutoTextControlHandlingState {
~AutoTextControlHandlingState() {
mTextControlState.mHandlingState = mParent;
if (!mParent && mTextControlStateDestroyed) {
mTextControlState.Destroy();
mTextControlState.DeleteOrCacheForReuse();
}
}
@@ -1180,6 +1180,9 @@ class MOZ_STACK_CLASS AutoTextControlHandlingState {
* mozilla::TextControlState
*****************************************************************************/
TextControlState* TextControlState::sReleasedInstance = nullptr;
bool TextControlState::sHasShutDown = false;
TextControlState::TextControlState(nsITextControlElement* aOwningElement)
: mTextCtrlElement(aOwningElement),
mBoundFrame(nullptr),
@@ -1199,11 +1202,11 @@ TextControlState::TextControlState(nsITextControlElement* aOwningElement)
}
TextControlState* TextControlState::Construct(
nsITextControlElement* aOwningElement, TextControlState** aReusedState) {
if (aReusedState && *aReusedState) {
TextControlState* state = *aReusedState;
MOZ_ASSERT(!state->IsBusy());
*aReusedState = nullptr;
nsITextControlElement* aOwningElement) {
if (sReleasedInstance) {
MOZ_ASSERT(!sReleasedInstance->IsBusy());
TextControlState* state = sReleasedInstance;
sReleasedInstance = nullptr;
state->mTextCtrlElement = aOwningElement;
state->mBoundFrame = nullptr;
state->mSelectionProperties = SelectionProperties();
@@ -1228,12 +1231,32 @@ TextControlState::~TextControlState() {
Clear();
}
void TextControlState::Shutdown() {
sHasShutDown = true;
if (sReleasedInstance) {
sReleasedInstance->DeleteOrCacheForReuse();
sReleasedInstance = nullptr;
}
}
void TextControlState::Destroy() {
// If we're handling something, we should be deleted later.
if (mHandlingState) {
mHandlingState->OnDestroyTextControlState();
return;
}
DeleteOrCacheForReuse();
}
void TextControlState::DeleteOrCacheForReuse() {
MOZ_ASSERT(!IsBusy());
// If we can cache this instance, we should do it instead of deleting it.
if (!sHasShutDown && !sReleasedInstance) {
sReleasedInstance = this;
sReleasedInstance->PrepareForReuse();
return;
}
delete this;
}