Bug 1637553 - Reduce array copy in spell checker loop. r=masayuki

Actually, we always clone spell checker range array per IPC call into spell
check loop. But we can use `std::move` to reduce unnecessary copy.

Also, `mozInlineSpellWordUtil::GetNextWord` always returns NS_OK, so
this should use boolean value to know whether loop is done.

Differential Revision: https://phabricator.services.mozilla.com/D75111
This commit is contained in:
Makoto Kato 2020-05-27 14:33:12 +00:00
Родитель d39d9cbb00
Коммит b8d216c8f6
4 изменённых файлов: 31 добавлений и 31 удалений

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

@ -1304,9 +1304,8 @@ nsresult mozInlineSpellChecker::DoSpellCheck(
// XXX Spellchecker API isn't async on chrome process.
static const size_t requestChunkSize =
XRE_IsContentProcess() ? INLINESPELL_MAXIMUM_CHUNKED_WORDS_PER_TASK : 1;
while (NS_SUCCEEDED(aWordUtil.GetNextWord(wordText, &wordNodeOffsetRange,
&dontCheckWord)) &&
!wordNodeOffsetRange.Empty()) {
while (
aWordUtil.GetNextWord(wordText, &wordNodeOffsetRange, &dontCheckWord)) {
// get the range for the current word.
nsINode* beginNode = wordNodeOffsetRange.Begin().Node();
nsINode* endNode = wordNodeOffsetRange.End().Node();
@ -1320,9 +1319,8 @@ nsresult mozInlineSpellChecker::DoSpellCheck(
#ifdef DEBUG_INLINESPELL
printf("We have run out of the time, schedule next round.\n");
#endif
CheckCurrentWordsNoSuggest(aSpellCheckSelection, words, checkRanges);
words.Clear();
checkRanges.Clear();
CheckCurrentWordsNoSuggest(aSpellCheckSelection, std::move(words),
std::move(checkRanges));
// move the range to encompass the stuff that needs checking.
nsresult rv = aStatus->mRange->SetStart(beginNode, beginOffset);
@ -1385,13 +1383,17 @@ nsresult mozInlineSpellChecker::DoSpellCheck(
checkRanges.AppendElement(wordNodeOffsetRange);
wordsChecked++;
if (words.Length() >= requestChunkSize) {
CheckCurrentWordsNoSuggest(aSpellCheckSelection, words, checkRanges);
words.Clear();
checkRanges.Clear();
CheckCurrentWordsNoSuggest(aSpellCheckSelection, std::move(words),
std::move(checkRanges));
// Set new empty data for spellcheck words and range in DOM to avoid
// clang-tidy detection.
words = nsTArray<nsString>();
checkRanges = nsTArray<NodeOffsetRange>();
}
}
CheckCurrentWordsNoSuggest(aSpellCheckSelection, words, checkRanges);
CheckCurrentWordsNoSuggest(aSpellCheckSelection, std::move(words),
std::move(checkRanges));
return NS_OK;
}
@ -1417,8 +1419,10 @@ class MOZ_RAII AutoChangeNumPendingSpellChecks final {
};
void mozInlineSpellChecker::CheckCurrentWordsNoSuggest(
Selection* aSpellCheckSelection, const nsTArray<nsString>& aWords,
const nsTArray<NodeOffsetRange>& aRanges) {
Selection* aSpellCheckSelection, nsTArray<nsString>&& aWords,
nsTArray<NodeOffsetRange>&& aRanges) {
MOZ_ASSERT(aWords.Length() == aRanges.Length());
if (aWords.IsEmpty()) {
return;
}
@ -1428,9 +1432,10 @@ void mozInlineSpellChecker::CheckCurrentWordsNoSuggest(
RefPtr<mozInlineSpellChecker> self = this;
RefPtr<Selection> spellCheckerSelection = aSpellCheckSelection;
uint32_t token = mDisabledAsyncToken;
mSpellCheck->CheckCurrentWordsNoSuggest(aWords)->Then(
nsTArray<nsString> words = std::move(aWords);
mSpellCheck->CheckCurrentWordsNoSuggest(words)->Then(
GetMainThreadSerialEventTarget(), __func__,
[self, spellCheckerSelection, ranges = aRanges.Clone(),
[self, spellCheckerSelection, ranges = std::move(aRanges),
token](const nsTArray<bool>& aIsMisspelled) {
if (token != self->mDisabledAsyncToken) {
// This result is never used

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

@ -277,8 +277,8 @@ class mozInlineSpellChecker final : public nsIInlineSpellChecker,
void EndListeningToEditSubActions() { mIsListeningToEditSubActions = false; }
void CheckCurrentWordsNoSuggest(mozilla::dom::Selection* aSpellCheckSelection,
const nsTArray<nsString>& aWords,
const nsTArray<NodeOffsetRange>& aRanges);
nsTArray<nsString>&& aWords,
nsTArray<NodeOffsetRange>&& aRanges);
};
#endif // #ifndef mozilla_mozInlineSpellChecker_h

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

@ -330,18 +330,17 @@ static void NormalizeWord(const nsAString& aInput, int32_t aPos, int32_t aLen,
// time. It would be better if the inline spellchecker didn't require a
// range unless the word was misspelled. This may or may not be possible.
nsresult mozInlineSpellWordUtil::GetNextWord(nsAString& aText,
NodeOffsetRange* aNodeOffsetRange,
bool* aSkipChecking) {
bool mozInlineSpellWordUtil::GetNextWord(nsAString& aText,
NodeOffsetRange* aNodeOffsetRange,
bool* aSkipChecking) {
#ifdef DEBUG_SPELLCHECK
printf("GetNextWord called; mNextWordIndex=%d\n", mNextWordIndex);
#endif
if (mNextWordIndex < 0 || mNextWordIndex >= int32_t(mRealWords.Length())) {
mNextWordIndex = -1;
*aNodeOffsetRange = NodeOffsetRange();
*aSkipChecking = true;
return NS_OK;
return false;
}
const RealWord& word = mRealWords[mNextWordIndex];
@ -355,7 +354,7 @@ nsresult mozInlineSpellWordUtil::GetNextWord(nsAString& aText,
NS_ConvertUTF16toUTF8(aText).get(), *aSkipChecking);
#endif
return NS_OK;
return true;
}
// mozInlineSpellWordUtil::MakeRange

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

@ -43,18 +43,14 @@ class NodeOffsetRange {
private:
NodeOffset mBegin;
NodeOffset mEnd;
bool mEmpty;
public:
NodeOffsetRange() : mEmpty(true) {}
NodeOffsetRange(NodeOffset b, NodeOffset e)
: mBegin(b), mEnd(e), mEmpty(false) {}
NodeOffsetRange() {}
NodeOffsetRange(NodeOffset b, NodeOffset e) : mBegin(b), mEnd(e) {}
NodeOffset Begin() const { return mBegin; }
NodeOffset End() const { return mEnd; }
bool Empty() const { return mEmpty; }
};
/**
@ -110,11 +106,11 @@ class MOZ_STACK_CLASS mozInlineSpellWordUtil {
static already_AddRefed<nsRange> MakeRange(const NodeOffsetRange& aRange);
// Moves to the the next word in the range, and retrieves it's text and range.
// An empty word and a nullptr range are returned when we are done checking.
// false is returned when we are done checking.
// aSkipChecking will be set if the word is "special" and shouldn't be
// checked (e.g., an email address).
nsresult GetNextWord(nsAString& aText, NodeOffsetRange* aNodeOffsetRange,
bool* aSkipChecking);
bool GetNextWord(nsAString& aText, NodeOffsetRange* aNodeOffsetRange,
bool* aSkipChecking);
// Call to normalize some punctuation. This function takes an autostring
// so we can access characters directly.