зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1477898 - Make AutoRestoreEditorState not call EditorBase::SetFlags() since the virtual call cost appears in profile r=m_kato
Unfortunately, EditorBase::SetFlags() is virtual call even though AutoRestoreEditorState always works only with TextEditor (the method is overridden only by HTMLEditor). And AutoRestoreEditorState is a hot path when <input>.value or <textarea>.value is set a lot. Fortunately, EditorBase::Flags() can be an inline method. So, we can make both constructor and destructor of the class check if it'll change flags actually. Additionally, this patch fixes nsTextEditorState::PrepareEditor() too. MozReview-Commit-ID: 7S4hLRRrbfB --HG-- extra : rebase_source : 3c3e7438cd7e6c9853e5cf876277d7459b86c343
This commit is contained in:
Родитель
acd8ea2c75
Коммит
5f1e6f2a03
|
@ -50,6 +50,15 @@
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
inline nsresult
|
||||
SetEditorFlagsIfNecessary(EditorBase& aEditorBase, uint32_t aFlags)
|
||||
{
|
||||
if (aEditorBase.Flags() == aFlags) {
|
||||
return NS_OK;
|
||||
}
|
||||
return aEditorBase.SetFlags(aFlags);
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS ValueSetter
|
||||
{
|
||||
public:
|
||||
|
@ -139,19 +148,24 @@ public:
|
|||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
MOZ_ASSERT(mTextEditor);
|
||||
|
||||
// EditorBase::SetFlags() is a virtual method. Even though it does nothing
|
||||
// if new flags and current flags are same, the calling cost causes
|
||||
// appearing the method in profile. So, this class should check if it's
|
||||
// necessary to call.
|
||||
uint32_t flags = mSavedFlags;
|
||||
flags &= ~(nsIPlaintextEditor::eEditorDisabledMask);
|
||||
flags &= ~(nsIPlaintextEditor::eEditorReadonlyMask);
|
||||
flags |= nsIPlaintextEditor::eEditorDontEchoPassword;
|
||||
mTextEditor->SetFlags(flags);
|
||||
|
||||
if (mSavedFlags != flags) {
|
||||
mTextEditor->SetFlags(flags);
|
||||
}
|
||||
mTextEditor->SetMaxTextLength(-1);
|
||||
}
|
||||
|
||||
~AutoRestoreEditorState()
|
||||
{
|
||||
mTextEditor->SetMaxTextLength(mSavedMaxLength);
|
||||
mTextEditor->SetFlags(mSavedFlags);
|
||||
SetEditorFlagsIfNecessary(*mTextEditor, mSavedFlags);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1482,7 +1496,7 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||
mSelCon->SetDisplaySelection(nsISelectionController::SELECTION_OFF);
|
||||
}
|
||||
|
||||
newTextEditor->SetFlags(editorFlags);
|
||||
SetEditorFlagsIfNecessary(*newTextEditor, editorFlags);
|
||||
}
|
||||
|
||||
if (shouldInitializeEditor) {
|
||||
|
@ -1496,8 +1510,10 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||
// editor for us.
|
||||
|
||||
if (!defaultValue.IsEmpty()) {
|
||||
rv = newTextEditor->SetFlags(editorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = SetEditorFlagsIfNecessary(*newTextEditor, editorFlags);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Now call SetValue() which will make the necessary editor calls to set
|
||||
// the default value. Make sure to turn off undo before setting the default
|
||||
|
@ -1509,8 +1525,10 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
|||
NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Now restore the original editor flags.
|
||||
rv = newTextEditor->SetFlags(editorFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = SetEditorFlagsIfNecessary(*newTextEditor, editorFlags);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsPasswordTextControl()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче