For parallelism with mfbt/Utf8.h. Differential Revision: https://phabricator.services.mozilla.com/D307780
650 lines
26 KiB
C
650 lines
26 KiB
C
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef nsHtml5TokenizerLoopPoliciesSIMD_h
|
|
#define nsHtml5TokenizerLoopPoliciesSIMD_h
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/htmlaccel/htmlaccelNotInline.h"
|
|
#include "mozilla/Utf16.h"
|
|
|
|
/**
|
|
* This policy does not report tokenizer transitions anywhere and does not
|
|
* track line and column numbers. To be used for innerHTML.
|
|
*
|
|
* This the SIMD version for aarch64 and SSSE3-enabled x86/x86_64.
|
|
*/
|
|
struct nsHtml5FastestPolicySIMD {
|
|
static const bool reportErrors = false;
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
|
|
nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
|
|
int32_t aPos) {
|
|
return aState;
|
|
}
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
|
|
nsHtml5Highlighter* aHighlighter) {}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
if (buf[pos] == '<') {
|
|
// Quickly handle the case where there is one tag immediately
|
|
// after another and the very first thing in the data state is a
|
|
// less-than sign.
|
|
return 0;
|
|
}
|
|
return mozilla::htmlaccel::AccelerateDataFastest(buf + pos, buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
if (buf[pos] == '<') {
|
|
// Quickly handle the <iframe></iframe> case.
|
|
return 0;
|
|
}
|
|
return mozilla::htmlaccel::AccelerateRawtextFastest(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// This state shares the SIMD part with the comment state, but this
|
|
// wrapper needs to differ!
|
|
return mozilla::htmlaccel::AccelerateCommentFastest(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance = mozilla::htmlaccel::AccelerateCommentFastest(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedFastest(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedFastest(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
return mozilla::htmlaccel::AccelerateCdataSectionFastest(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
return mozilla::htmlaccel::AcceleratePlaintextFastest(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
|
|
return buf[pos];
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
|
|
nsHtml5Tokenizer* aTokenizer) {
|
|
aTokenizer->lastCR = true;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
|
|
nsHtml5Tokenizer* aTokenizer) {}
|
|
};
|
|
|
|
/**
|
|
* This policy does not report tokenizer transitions anywhere. To be used
|
|
* when _not_ viewing source and when not parsing innerHTML (or other
|
|
* script execution-preventing fragment).
|
|
*/
|
|
struct nsHtml5LineColPolicySIMD {
|
|
static const bool reportErrors = false;
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
|
|
nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
|
|
int32_t aPos) {
|
|
return aState;
|
|
}
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
|
|
nsHtml5Highlighter* aHighlighter) {}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
char16_t c = buf[pos];
|
|
if (c == '<' || c == '\n') {
|
|
// Quickly handle the case where there is one tag immediately
|
|
// after another and the very first thing in the data state is a
|
|
// less-than sign and the case where a tag is immediately followed
|
|
// by a line feed.
|
|
return 0;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateDataLineCol(buf + pos, buf + endPos);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
char16_t c = buf[pos];
|
|
if (c == '<' || c == '\n') {
|
|
// Quickly handle the case where there is one tag immediately
|
|
// after another and the very first thing in the data is a
|
|
// less-than sign and the case where a tag is immediately followed
|
|
// by a line feed.
|
|
return 0;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateRawtextLineCol(buf + pos, buf + endPos);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// This state shares the SIMD part with the comment state, but this
|
|
// wrapper needs to differ!
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateCommentLineCol(buf + pos, buf + endPos);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance = mozilla::htmlaccel::AccelerateCommentLineCol(
|
|
buf + pos, buf + pos + len);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedLineCol(
|
|
buf + pos, buf + pos + len);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedLineCol(
|
|
buf + pos, buf + pos + len);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t advance = mozilla::htmlaccel::AccelerateCdataSectionLineCol(
|
|
buf + pos, buf + endPos);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AcceleratePlaintextLineCol(buf + pos, buf + endPos);
|
|
if (!advance) {
|
|
// When the SIMD advance is zero, don't touch the line and col tracking.
|
|
return 0;
|
|
}
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = advance;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else {
|
|
aTokenizer->col += advance;
|
|
}
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
|
|
// The name of this method comes from the validator.
|
|
// We aren't checking a char here. We read the next
|
|
// UTF-16 code unit and, before returning it, adjust
|
|
// the line and column numbers.
|
|
char16_t c = buf[pos];
|
|
if (MOZ_UNLIKELY(aTokenizer->nextCharOnNewLine)) {
|
|
// By changing the line and column here instead
|
|
// of doing so eagerly when seeing the line break
|
|
// causes the line break itself to be considered
|
|
// column-wise at the end of a line.
|
|
aTokenizer->line++;
|
|
aTokenizer->col = 1;
|
|
aTokenizer->nextCharOnNewLine = false;
|
|
} else if (MOZ_LIKELY(!mozilla::IsLowSurrogate(c))) {
|
|
// SpiderMonkey wants to count scalar values
|
|
// instead of UTF-16 code units. We omit low
|
|
// surrogates from the count so that only the
|
|
// high surrogate increments the count for
|
|
// two-code-unit scalar values.
|
|
//
|
|
// It's somewhat questionable from the performance
|
|
// perspective to make the human-perceivable column
|
|
// count correct for non-BMP characters in the case
|
|
// where there is a single scalar value per extended
|
|
// grapheme cluster when even on the BMP there are
|
|
// various cases where the scalar count doesn't make
|
|
// much sense as a human-perceived "column count" due
|
|
// to extended grapheme clusters consisting of more
|
|
// than one scalar value.
|
|
aTokenizer->col++;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
|
|
nsHtml5Tokenizer* aTokenizer) {
|
|
aTokenizer->nextCharOnNewLine = true;
|
|
aTokenizer->lastCR = true;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
|
|
nsHtml5Tokenizer* aTokenizer) {
|
|
aTokenizer->nextCharOnNewLine = true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* This policy reports the tokenizer transitions to a highlighter. To be used
|
|
* when viewing source.
|
|
*/
|
|
struct nsHtml5ViewSourcePolicySIMD {
|
|
static const bool reportErrors = true;
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t transition(
|
|
nsHtml5Highlighter* aHighlighter, int32_t aState, bool aReconsume,
|
|
int32_t aPos) {
|
|
return aHighlighter->Transition(aState, aReconsume, aPos);
|
|
}
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void completedNamedCharacterReference(
|
|
nsHtml5Highlighter* aHighlighter) {
|
|
aHighlighter->CompletedNamedCharacterReference();
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementData(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
char16_t c = buf[pos];
|
|
if (c == '<' || c == '\n') {
|
|
// Quickly handle the case where there is one tag immediately
|
|
// after another and the very first thing in the data state is a
|
|
// less-than sign and the case where a tag is immediately followed
|
|
// by a line feed.
|
|
return 0;
|
|
}
|
|
return mozilla::htmlaccel::AccelerateDataViewSource(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementRawtext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// We need to check bounds for the `buf[pos]` access below to be OK.
|
|
// Instead of just checking that `pos` isn't equal to `endPos`, let's
|
|
// check that have at least one SIMD stride of data in the same branch,
|
|
// since if we don't have at least one SIMD stride of data, we don't
|
|
// need to proceed.
|
|
if (endPos - pos < 16) {
|
|
return 0;
|
|
}
|
|
char16_t c = buf[pos];
|
|
if (c == '<' || c == '\n') {
|
|
// Quickly handle the case where there is one tag immediately
|
|
// after another and the very first thing in the state is a
|
|
// less-than sign and the case where a tag is immediately followed
|
|
// by a line feed.
|
|
return 0;
|
|
}
|
|
return mozilla::htmlaccel::AccelerateRawtextViewSource(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementScriptDataEscaped(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
// This state shares the SIMD part with the comment state, but this
|
|
// wrapper needs to differ!
|
|
return mozilla::htmlaccel::AccelerateCommentViewSource(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementComment(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance = mozilla::htmlaccel::AccelerateCommentViewSource(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueSingleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueSingleQuotedViewSource(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t
|
|
accelerateAdvancementAttributeValueDoubleQuoted(nsHtml5Tokenizer* aTokenizer,
|
|
char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
int32_t len = endPos - pos;
|
|
int32_t strBufAvailable = aTokenizer->strBuf.length - aTokenizer->strBufLen;
|
|
if (len > strBufAvailable) {
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "strBuf has not been extended correctly.");
|
|
len = strBufAvailable;
|
|
}
|
|
int32_t advance =
|
|
mozilla::htmlaccel::AccelerateAttributeValueDoubleQuotedViewSource(
|
|
buf + pos, buf + pos + len);
|
|
// States that on the non-SIMD path copy characters to strBuf also
|
|
// need to do that in the SIMD case.
|
|
nsHtml5ArrayCopy::arraycopy(buf, pos, aTokenizer->strBuf,
|
|
aTokenizer->strBufLen, advance);
|
|
aTokenizer->strBufLen += advance;
|
|
return advance;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementCdataSection(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
return mozilla::htmlaccel::AccelerateCdataSectionViewSource(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static int32_t accelerateAdvancementPlaintext(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos,
|
|
int32_t endPos) {
|
|
return mozilla::htmlaccel::AcceleratePlaintextViewSource(buf + pos,
|
|
buf + endPos);
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static char16_t checkChar(
|
|
nsHtml5Tokenizer* aTokenizer, char16_t* buf, int32_t pos) {
|
|
return buf[pos];
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentCarriageReturn(
|
|
nsHtml5Tokenizer* aTokenizer) {
|
|
aTokenizer->line++;
|
|
aTokenizer->lastCR = true;
|
|
}
|
|
|
|
MOZ_ALWAYS_INLINE_EVEN_DEBUG static void silentLineFeed(
|
|
nsHtml5Tokenizer* aTokenizer) {
|
|
aTokenizer->line++;
|
|
}
|
|
};
|
|
|
|
#endif // nsHtml5TokenizerLoopPoliciesSIMD_h
|